如何自动提取CSV表头作为Python matplotlib绘图的图例标签
报错根因
直接将pandas DataFrame传入matplotlib原生ax.plot()方法时,matplotlib不会自动将DataFrame列名绑定为折线的label属性,调用legend()时检索不到带有效标签的绘图元素,就会抛出如下警告:
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
可行实现方案
方案1:使用DataFrame内置plot方法(代码最简洁)
pandas自带的Series/DataFrame绘图接口原生支持自动将列名作为图例标签,只需要指定绑定的子图对象即可,无需手动拼接列名:
for i in range(len(model[idx]['asb_path'])): j = len(model[idx]['asb_path'])-i-1 # 读取带表头的CSV文件 potiso = pd.read_csv(model[idx]['potiso_path'][i], index_col=0) asb = pd.read_csv(model[idx]['asb_path'][i], index_col=0) # 绘制potiso数据,指定固定标签 potiso.plot(ax=axs[j], label='NODE_POT_ISO') # 直接绘制asb全列数据,自动以列名作为图例标签 asb.plot(ax=axs[j]) axs[j].set_title(os.path.basename(model[idx]['asb_path'][i])) axs[j].set_xlabel('time(s)') axs[j].set_ylabel('displacement(m)') axs[j].legend() axs[j].grid(True) plt.savefig(fig_path)
该方案下后续调整CSV列数量、修改列名,都不需要改动绘图代码,pandas会自动识别所有列并匹配对应标签。
方案2:遍历DataFrame列绑定标签(兼容原生matplotlib写法)
如果需要保留原生matplotlib的ax.plot()调用习惯,可以遍历DataFrame的列名,逐列绘图时自动将列名传入label参数:
for i in range(len(model[idx]['asb_path'])): j = len(model[idx]['asb_path'])-i-1 potiso = pd.read_csv(model[idx]['potiso_path'][i], index_col=0) asb = pd.read_csv(model[idx]['asb_path'][i], index_col=0) axs[j].plot(potiso, label='NODE_POT_ISO') # 遍历asb所有列,自动将列名设为标签 for col_name in asb.columns: axs[j].plot(asb[col_name], label=col_name) axs[j].set_title(os.path.basename(model[idx]['asb_path'][i])) axs[j].set_xlabel('time(s)') axs[j].set_ylabel('displacement(m)') axs[j].legend() axs[j].grid(True) plt.savefig(fig_path)
注意事项
- 如果CSV列名以下划线
_开头,matplotlib默认会隐藏这类标签,遇到该场景可以在传label时增加固定前缀,例如label=f"RESULT_{col_name}"即可正常显示在图例中。 - 上述两种方案均不需要硬编码任何列名,后续调整CSV结构时无需修改后处理脚本,完全适配需求。
内容的提问来源于stack exchange,提问作者MathisGauthey
相关产品推荐
相关产品推荐

