如何解决保存双字典直方图到PDF时的'tuple'无savefig属性错误?
解决'tuple' object has no attribute 'savefig'错误并成功保存直方图为PDF
嘿,这个报错的根源其实很明确:你误用了matplotlib里plt.subplots()的返回值!
为什么会报错?
plt.subplots()函数返回的是一个元组(包含Figure画布对象和Axes坐标轴对象),但你把这个元组直接赋值给了变量fig。当你调用fig.savefig()时,相当于在对一个元组调用方法,而元组根本没有savefig这个属性,所以就抛出了这个错误。
修复步骤
只需要正确拆分plt.subplots()的返回值,把单独的Figure对象存为fig就行。这里有两种可选的修复方式:
方式一:规范使用Axes对象绘图(推荐)
把返回的Figure和Axes对象拆分出来,用Axes对象来控制绘图,这是matplotlib更推荐的面向对象写法:
import matplotlib.pyplot as plt import numpy as np # 正确拆分返回值:fig是画布对象,ax是坐标轴对象 fig, ax = plt.subplots(figsize=(40, 15)) barWidth = 0.25 EL = list(dict_graph_EL.values()) EA = list(dict_graph_EA.values()) br1 = np.arange(len(EL)) br2 = [x + barWidth for x in br1] # 用ax对象绘制柱状图 ax.bar(br1, EL, color='blue', width=barWidth, edgecolor='grey', label='EL') ax.bar(br2, EA, color='pink', width=barWidth, edgecolor='grey', label='EA') list_labels = list(dict_graph_EA.keys()) # 用ax设置刻度和标签 ax.set_xticks([r + barWidth for r in range(len(EL))]) ax.set_xticklabels(list_labels, rotation=60) ax.set_ylabel('Avg percentage of error on EL(blue)/EA(pink)') ax.set_xlabel('Programs') ax.legend(['Avg EL', 'Avg EA'], loc='upper left') # 先保存再显示(避免show()清空画布导致保存空白) fig.savefig("avgELEA.pdf", bbox_inches='tight') plt.show()
方式二:保留plt接口,仅修正变量赋值
如果你习惯用plt的全局接口绘图,只需要修改第一行,用下划线接收不需要的Axes对象:
# 只取返回的Figure对象,用_忽略Axes对象 fig, _ = plt.subplots(figsize=(40, 15)) # 后面的代码和你原来的基本一致,仅调整show()的调用 barWidth = 0.25 EL= list(dict_graph_EL.values()) EA= list(dict_graph_EA.values()) br1 = np.arange(len(list(dict_graph_EL.keys()))) br2 = [x + barWidth for x in br1] plt.bar(br1, EL, color ='blue', width = barWidth, edgecolor ='grey', label ='EL') plt.bar(br2, EA, color ='pink', width = barWidth, edgecolor ='grey', label ='EA') list_labels = list(dict_graph_EA.keys()) plt.xticks([r + barWidth for r in range(len(EL))], list_labels , rotation=60) plt.ylabel('Avg percentage of error on EL(blue)/EA(pink)') plt.xlabel('Programs') plt.legend(['Avg EL', 'Avg EA'], loc='upper left') # 先保存再显示 fig.savefig("avgELEA.pdf", bbox_inches='tight') plt.show()
额外提醒
- 一定要先调用
fig.savefig()再调用plt.show()!因为plt.show()会清空当前的画布内容,有些情况下如果先显示再保存,会得到空白的PDF文件。 plt.show()不需要传入fig参数,直接调用即可。
内容的提问来源于stack exchange,提问作者Pleasant94
相关产品推荐
相关产品推荐

