Python将数据标签添加到Matplotlib和Pandas GroupBy中的线图上

pgccezyw  于 2023-03-03  发布在  Python
关注(0)|答案(2)|浏览(178)

希望在Pandas GroupBy的Matplotlib生成的折线图中添加数据标签。

import matplotlib.pyplot as plt
import pandas as pd
from io import StringIO

csvfile = StringIO(
"""
Name    Year - Month    Score
Mike    2022-09 192
Mike    2022-08 708
Mike    2022-07 140
Mike    2022-05 144
Mike    2022-04 60
Mike    2022-03 108
Kate    2022-07 19850
Kate    2022-06 19105
Kate    2022-05 23740
Kate    2022-04 19780
Kate    2022-03 15495
Peter   2022-08 51
Peter   2022-07 39
Peter   2022-06 49
Peter   2022-05 49
Peter   2022-04 79
Peter   2022-03 13
Lily    2022-11 2
David   2022-11 3
David   2022-10 6
David   2022-08 2""")

df = pd.read_csv(csvfile, sep = '\t', engine='python')

for group_name, sub_frame in df.groupby("Name"):
    if sub_frame.shape[0] >= 2:
        sub_frame_sorted = sub_frame.sort_values('Year - Month')       # sort the data-frame by a column

        line_chart = sub_frame_sorted.plot("Year - Month", "Score")

        label = sub_frame_sorted['Score']
        line_chart.annotate(label, (sub_frame_sorted['Year - Month'], sub_frame_sorted['Score']), ha='center') 

plt.show()

数据标签的2行引发错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

我该怎么改正呢?谢谢。

f1tvaqid

f1tvaqid1#

正如错误所说,问题出在annotate()中。sub_frame_sorted是一个 Dataframe ,在使用annotate之前,您需要使用for循环来获取其中的每一项。另外,x轴是年-月,它被视为字符串,您将遇到问题。因此,您只需要使用index。我使用了0,1,2...使用i。这应该可以工作...如果你认为文本重叠了一行,你可以添加一个小的偏移量希望这是你正在寻找的。

更新代码

for group_name, sub_frame in df.groupby("Name"):
    if sub_frame.shape[0] >= 2:
        sub_frame_sorted = sub_frame.sort_values('Year - Month')       # sort the data-frame by a column
        line_chart = sub_frame_sorted.plot("Year - Month", "Score", legend=False)
        i=0
        for ix, vl in sub_frame_sorted.iterrows(): 
            line_chart.annotate(vl['Score'], (i, vl['Score']), ha='center') 
            i=i+1
plt.show()

输出图

第一节第一节第一节第一节第二节第一节第三节第一节

i86rm4rw

i86rm4rw2#

所以,问题应该出在for循环内部。
您可以将代码替换为以下代码:

for group_name, sub_frame in df.groupby("Name"):
    if sub_frame.shape[0] >= 2:
        sub_frame_sorted = sub_frame.sort_values('Year - Month')

        line_chart = sub_frame_sorted.plot("Year - Month", "Score")
        for x, y in zip(sub_frame_sorted["Year - Month"], sub_frame_sorted["Score"]):
            label = "{:.0f}".format(y)  # format the label as a string
            line_chart.annotate(label, (x, y), textcoords="offset points", xytext=(0,10), ha='center')

如果你遇到关于“年-月”的错误,你应该使用to_datetime()方法转换它。
如果有帮助请告诉我。谢谢。

相关问题