You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正Matplotlib与Pandas GroupBy折线图添加数据标签的报错?

为Pandas分组后的折线图添加数据标签的代码修正

问题描述

用户编写了以下代码,试图为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()

错误信息

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

修正方案

错误根源在于matplotlib.axes.Axes.annotate()方法只能处理单个数据点的标注,不能直接传入Pandas Series作为参数。需要遍历排序后的数据框中的每一行,为每个点单独添加标签。

修正后的代码如下:

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')
        line_chart = sub_frame_sorted.plot("Year - Month", "Score", title=f"Score Trend for {group_name}")
        
        # 遍历每一行,逐个添加数据标签
        for x, y in zip(sub_frame_sorted['Year - Month'], sub_frame_sorted['Score']):
            line_chart.annotate(str(y), (x, y), ha='center', va='bottom', fontsize=8)

plt.tight_layout()
plt.show()

关键修改点

  • 用zip()将x轴(年份月份)和y轴(分数)的元素一一配对,遍历每个数据点
  • 调用annotate()时传入单个的标签值(转为字符串避免格式问题)、单个坐标点
  • 添加va='bottom'参数让标签在数据点上方显示,避免重叠;可选调整fontsize让标签更美观
  • 为每个子图添加标题,区分不同用户的趋势图
  • 加入plt.tight_layout()自动调整子图间距,防止标签或标题被截断

内容的提问来源于stack exchange,提问作者Mark K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 14:38:01