如何为含字符串X轴的折线图添加数值标注?
解决折线图标注的ConversionError问题
错误原因很明确:你用df['Month']的字符串值(比如'JAN')作为plt.annotate的x坐标,但Matplotlib绘制折线图时,x轴底层实际使用的是DataFrame的索引值(0到11),Month列只是被用作x轴的刻度标签显示,并非真实的轴坐标值,所以直接传入字符串会触发类型转换错误。
下面给两种可行的解决方式:
方法一:使用DataFrame索引作为标注的x坐标
直接循环DataFrame的索引和对应MEAN值,用索引作为x轴坐标,同时保留原Month字符串作为刻度显示:
import matplotlib.pyplot as plt import pandas as pd # 你的DataFrame数据 data = { 'Month': ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'], 'MEAN': [1.0, 2.0, 5.0, 3.0, 4.0, 2.0, 1.0, 1.0, 0.0, 0.0, 2.0, 3.0] } df = pd.DataFrame(data) fig = plt.figure('Graphic', figsize=(20,15), dpi=300) ax1 = fig.add_axes([0.15, 0.20, 0.70, 0.60]) df.plot(kind='line', marker='o', style=['--'], linewidth=7, color='black', ms=15, ax=ax1) # 修改循环:用索引i作为x坐标,y为MEAN值 for i, y in enumerate(df['MEAN']): label = "{:.2f}".format(y) # 用ax1.annotate替代plt.annotate,更精准绑定当前轴 ax1.annotate(label, (i, y), textcoords="offset points", xytext=(0,10), ha='center') # 确保x轴显示Month字符串(默认已经是,这里可以显式设置) ax1.set_xticks(range(len(df))) ax1.set_xticklabels(df['Month']) plt.show()
关键改动:
- 用
enumerate(df['MEAN'])获取索引i(对应x轴的实际坐标)和y值 - 用
ax1.annotate替代plt.annotate,避免多轴场景下的混乱 - 显式设置x轴刻度和标签,确保显示Month字符串
方法二:将Month转为有序分类类型
先把Month列转为有序分类,让Matplotlib能正确识别其作为x轴的映射关系:
import matplotlib.pyplot as plt import pandas as pd data = { 'Month': ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'], 'MEAN': [1.0, 2.0, 5.0, 3.0, 4.0, 2.0, 1.0, 1.0, 0.0, 0.0, 2.0, 3.0] } df = pd.DataFrame(data) # 将Month转为有序分类,指定顺序确保绘图时的顺序正确 month_order = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'] df['Month'] = pd.Categorical(df['Month'], categories=month_order, ordered=True) fig = plt.figure('Graphic', figsize=(20,15), dpi=300) ax1 = fig.add_axes([0.15, 0.20, 0.70, 0.60]) # 绘图时指定x为Month列 df.plot(x='Month', kind='line', marker='o', style=['--'], linewidth=7, color='black', ms=15, ax=ax1) # 循环时用分类的编码值作为x坐标 for x, y in zip(df['Month'].cat.codes, df['MEAN']): label = "{:.2f}".format(y) ax1.annotate(label, (x, y), textcoords="offset points", xytext=(0,10), ha='center') plt.show()
这种方式适合需要保留Month列作为分类数据的场景,通过cat.codes获取分类对应的数值坐标。
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

