openpyxl保存折线图到Excel触发AttributeError报错求助
问题根因
- 你当前通过
matplotlib.pyplot生成的是独立渲染的位图,不属于openpyxl支持的可直接写入的原生图表对象,无法通过add_chart接口直接插入 - 你注释中打开的
ws1.add_chart("Line Chart", 'H1')写法错误,add_chart第一个参数要求传入openpyxl初始化完成的图表实例,传入字符串会触发'str' object has no attribute 'anchor'报错。
解决方案
可根据需求选择以下两种实现方式:
方式1:直接插入matplotlib生成的现有折线图
该方式不需要修改你已写好的绘图逻辑,只需要先将plt生成的图表存为本地图片,再插入到Excel即可:
- 导入openpyxl的图片加载类
- 绘图完成后先保存图片到本地,再调用
add_image方法插入到工作表指定位置 - 调整图片尺寸避免变形后保存工作簿
可直接替换的参考代码:
import matplotlib.pyplot as plt from openpyxl.drawing.image import Image # 保留你原有代码里导入openpyxl、创建/加载工作簿wb、工作表ws1、定义pn/pd/dpt/fnm变量的部分 plt.title('PHID / PHIN Crossover') plt.plot(pn, dpt, color='red', marker='', label='PHIN') plt.plot(pd, dpt, color='blue', marker='', label='PHID') # 修正原代码第二个系列label误写为PHIN的问题 plt.xlabel('Porosity') plt.ylabel('Depth') plt.gca().invert_yaxis() plt.legend(['PHIN', 'PHID']) plt.tight_layout() # 自动调整布局避免标题、坐标轴标签被截断 # 注意:必须先执行savefig再调用plt.show(),否则画布清空会导致保存的图片为空白 plt.savefig('temp_crossover_chart.png', dpi=150) plt.show() # 不需要弹窗预览图片可以注释这行 # 加载图片插入到H1单元格位置 chart_img = Image('temp_crossover_chart.png') # 可根据实际需求调整图片宽高 chart_img.width = 600 chart_img.height = 450 ws1.add_image(chart_img, 'H1') wb.save(fnm)
方式2:生成openpyxl原生Excel折线图
该方式插入的图表是Excel可直接编辑的原生图表,不需要生成临时图片,缺点是需要先把绘图数据写入工作表单元格供图表引用,参考代码如下:
from openpyxl.chart import LineChart, Reference # 保留你原有导入、创建wb/ws1、定义pn/pd/dpt/fnm的代码 # 第一步:把数据写入工作表,这里示例从A列开始存储 # A列存深度dpt,B列存PHIN(pn),C列存PHID(pd) for i in range(len(dpt)): ws1.cell(row=i+1, column=1, value=dpt[i]) ws1.cell(row=i+1, column=2, value=pn[i]) ws1.cell(row=i+1, column=3, value=pd[i]) # 第二步:创建折线图对象并设置基础属性 chart = LineChart() chart.title = "PHID / PHIN Crossover" chart.x_axis.title = "Porosity" chart.y_axis.title = "Depth" # 反转Y轴,和原代码invert_yaxis效果一致 chart.y_axis.scaling.orientation = "maxMin" # 第三步:绑定数据系列和坐标轴类别 phin_data = Reference(ws1, min_col=2, min_row=1, max_row=len(dpt)) phid_data = Reference(ws1, min_col=3, min_row=1, max_row=len(dpt)) depth_data = Reference(ws1, min_col=1, min_row=1, max_row=len(dpt)) chart.add_data(phin_data, titles_from_data=False) chart.add_data(phid_data, titles_from_data=False) chart.set_categories(depth_data) # 设置系列名称和线条颜色 chart.series[0].title = "PHIN" chart.series[0].graphicalProperties.line.solidFill = "red" chart.series[1].title = "PHID" chart.series[1].graphicalProperties.line.solidFill = "blue" # 第四步:插入图表到H1位置 ws1.add_chart(chart, "H1") wb.save(fnm)
内容的提问来源于stack exchange,提问作者Mbw00001
相关产品推荐
相关产品推荐

