如何在Matplotlib折线图中显示全部数据标签?
解决Matplotlib折线图添加数据标签的报错问题
数据集
| Period | Demand | Forecast | Error |
|---|---|---|---|
| 0 | 1401.0 | 338.0 | 1063.0 |
| 1 | 1840.0 | 345.0 | 1495.0 |
| 2 | 1242.0 | 341.0 | 901.0 |
| 3 | 1321.0 | 1500.0 | -179.0 |
| 4 | 711.0 | 1500.0 | -789.0 |
原始绘图代码
你原本用来绘制折线图的代码是:
df[['Demand','Forecast']].plot(figsize=(8,3),title='Profil 2022',style=['-','--']) plt.tight_layout()
报错情况
你尝试添加数据标签的代码:
plt.plot(df[['Demand','Forecast']]) for a in zip(df[['Demand','Forecast']]): label = df.index plt.annotate(label, (df[['Demand','Forecast']]), xycoords="data", textcoords="offset points", xytext=(0, 10), ha="center") plt.show()
触发报错:The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
报错原因
- 循环逻辑错误:
zip(df[['Demand','Forecast']])仅遍历列名,无法获取每个数据点的坐标和数值; plt.annotate参数错误:直接传入整个df.index数组作为标签、整个DataFrame作为坐标,Matplotlib无法解析这种数组级别的输入,导致歧义。
正确解决方案
方案1:基于Pandas绘图后添加标签
这种方式复用你原本的Pandas绘图代码,直接在生成的轴对象上添加标签:
import matplotlib.pyplot as plt # 绘制折线图并获取轴对象 ax = df[['Demand','Forecast']].plot(figsize=(8,3), title='Profil 2022', style=['-','--']) # 遍历每条折线的所有数据点 for line in ax.lines: for x, y in zip(line.get_xdata(), line.get_ydata()): # 标注数值,可根据需求调整小数位数 ax.annotate(f'{y:.1f}', (x, y), xytext=(0, 8), # 标签向上偏移8个点 textcoords='offset points', ha='center', # 水平居中 fontsize=8) plt.tight_layout() plt.show()
方案2:纯Matplotlib手动绘制并添加标签
如果更习惯用原生Matplotlib语法,可逐个绘制折线并添加标签:
import matplotlib.pyplot as plt # 创建画布和轴对象 fig, ax = plt.subplots(figsize=(8,3)) # 绘制Demand折线并添加标签 ax.plot(df['Period'], df['Demand'], label='Demand', linestyle='-') for x, y in zip(df['Period'], df['Demand']): ax.annotate(f'{y:.1f}', (x, y), xytext=(0,8), textcoords='offset points', ha='center', fontsize=8) # 绘制Forecast折线并添加标签 ax.plot(df['Period'], df['Forecast'], label='Forecast', linestyle='--') for x, y in zip(df['Period'], df['Forecast']): ax.annotate(f'{y:.1f}', (x, y), xytext=(0,8), textcoords='offset points', ha='center', fontsize=8) ax.set_title('Profil 2022') ax.legend() plt.tight_layout() plt.show()
关键注意点
- 必须逐个遍历每个数据点,传入单个
x(Period值)和y(Demand/Forecast值)作为坐标,不能用整个数组; annotate的第一个参数是要显示的内容,这里直接用数值本身,可按需修改格式;xytext参数控制标签相对于数据点的偏移量,避免标签和折线重叠。
内容的提问来源于stack exchange,提问作者Deryansyah
相关产品推荐
相关产品推荐

