简体   繁体   English

使用来自另一个 pandas 列 matplotlib 的标签注释多行 plot 中的单行

[英]annotate a single line from a multi-line plot with labels from another pandas column matplotlib

i have been looking around and i can find examples for annotating a single line chart by using iterrows for the dataframe.我一直在环顾四周,我可以找到使用iterrows的 iterrows 来注释单个折线图的示例。 what i am struggling with is我正在努力的是

a) selecting the single line in the plot instead of ax.lines (using ax.lines[#] ) is clearly not proper and a)选择 plot 中的单行而不是ax.lines (使用ax.lines[#] )显然不合适,并且

b) annotating the values for the line with values from a different column b)用来自不同列的值注释该行的值

the dataframe dfg is in a format such that (edited to provide a minimal, reproducible example ): dataframe dfg的格式如下(经过编辑以提供最小的、可重现的示例):

week    2016    2017    2018    2019    2020    2021    min     max     avg WoW Change
1       8188.0  9052.0  7658.0  7846.0  6730.0  6239.0  6730    9052    7893.7  
2       7779.0  8378.0  7950.0  7527.0  6552.0  6045.0  6552    8378    7588.0  -194.0
3       7609.0  7810.0  8041.0  8191.0  6432.0  5064.0  6432    8191    7529.4  -981.0
4       8256.0  8290.0  8430.0  7083.0  6660.0  6507.0  6660    8430    7687.0  1443.0
5       7124.0  9372.0  7892.0  7146.0  6615.0  5857.0  6615    9372    7733.7  -650.0
6       7919.0  8491.0  7888.0  6210.0  6978.0  5898.0  6210    8491    7455.3  41.0
7       7802.0  7286.0  7021.0  7522.0  6547.0  4599.0  6547    7802    7218.1  -1299.0
8       8292.0  7589.0  7282.0  5917.0  6217.0  6292.0  5917    8292    7072.3  1693.0
9       8048.0  8150.0  8003.0  7001.0  6238.0  5655.0  6238    8150    7404.0  -637.0
10      7693.0  7405.0  7585.0  6746.0  6412.0  5323.0  6412    7693    7135.1  -332.0
11      8384.0  8307.0  7077.0  6932.0  6539.0                  6539    8384    7451.7  
12      7748.0  8224.0  8148.0  6540.0  6117.0                  6117    8224    7302.6  
13      7254.0  7850.0  7898.0  6763.0  6047.0                  6047    7898    7108.1  
14      7940.0  7878.0  8650.0  6599.0  5874.0                  5874    8650    7352.1  
15      8187.0  7810.0  7930.0  5992.0  5680.0                  5680    8187    7066.6  
16      7550.0  8912.0  8469.0  7149.0  4937.0                  4937    8912    7266.6  
17      7660.0  8264.0  8549.0  7414.0  5302.0                  5302    8549    7291.4  
18      7655.0  7620.0  7323.0  6693.0  5712.0                  5712    7655    6910.0  
19      7677.0  8590.0  7601.0  7612.0  5391.0                  5391    8590    7264.6  
20      7315.0  8294.0  8159.0  6943.0  5197.0                  5197    8294    7057.0  
21      7839.0  7985.0  7631.0  6862.0  7200.0                  6862    7985    7480.6  
22      7705.0  8341.0  8346.0  7927.0  6179.0                  6179    8346    7574.7  
...     ...     ...     ...     ...     ...                     ...     ...     ...
51      8167.0  7993.0  7656.0  6809.0  5564.0                  5564    8167    7131.4  
52      7183.0  7966.0  7392.0  6352.0  5326.0                  5326    7966    6787.3  
53                                               5369.0         5369    5369    5369.0  

with the graph plotted by:图表由以下人员绘制:

        fig, ax = plt.subplots(1, figsize=[14,4])

        ax.fill_between(dfg.index, dfg["min"], dfg["max"], label="5 Yr. Range", facecolor="oldlace")
        ax.plot(dfg.index, dfg[2020], label="2020", c="grey")
        ax.plot(dfg.index, dfg[2021], label="2021", c="coral") 
        ax.plot(dfg.index, dfg.avg, label="5 Yr. Avg.", c="goldenrod", ls=(0,(1,2)), lw=3).

I would like to label the dfg[2021] line with the values from dfg['WoW Change'] .我想 label dfg[2021]行与来自 dfg dfg['WoW Change']的值。 Additionally, if anyone knows how to get the calculate the first value in the WoW column based on the last value from 2020 and the first value from 2021, that would be wonderful!此外,如果有人知道如何根据 2020 年的最后一个值和 2021 年的第一个值来计算 WoW 列中的第一个值,那就太好了! It's currently just dfg['WoW Change'] = dfg[2021].diff()目前只是dfg['WoW Change'] = dfg[2021].diff()

Thanks!谢谢!

Figured it out.弄清楚了。 Zipped the index and two columns up as a tuple.将索引和两列压缩为一个元组。 I ended up deciding I only wanted the last value to be shown but using below code:我最终决定我只希望显示最后一个值,但使用以下代码:

    a = dfg.index.values
    b = dfg[2021]
    c = dfg['WoW Change']
    
    #zip 3 columns separately
    labels = list(zip(dfg.index.values,dfg[2021],dfg['WoW Change']))

    #remove tuples with index + 2 nan values
    labels_light = [i for i in labels if not any(isinstance(n,float) and math.isnan(n) for n in i)]

    #label last point using list accessors
    ax.annotate(str("w/w change: " + str("{:,}".format(int(labels_light[-1][2])))+link[1]),xy=(labels_light[-1][0],labels_light[-1][1]))

I'm sure this could have been done much better by someone who knows what they're doing, any feedback is appreciated.我敢肯定,知道自己在做什么的人可以做得更好,感谢任何反馈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM