求助:将Matplotlib绘图插入Word文档表格时触发AttributeError错误
问题解决:AttributeError: 'Figure' object has no attribute 'seek'
问题背景
开发模块需生成带3列表格的Word文档,调用子模块生成笛卡尔坐标系梯形图,但运行时触发错误:AttributeError: 'Figure' object has no attribute 'seek'
报错堆栈
File ~\anaconda3\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals) File c:\users\barry\.spyder-py3\createtablewithspecificdimensions.py:40 run.add_picture(fig, width=Inches(3.0), height=Inches(3.0)) File ~\anaconda3\Lib\site-packages\docx\text\run.py:79 in add_picture inline = self.part.new_pic_inline(image_path_or_stream, width, height) File ~\anaconda3\Lib\site-packages\docx\parts\story.py:71 in new_pic_inline rId, image = self.get_or_add_image(image_descriptor) File ~\anaconda3\Lib\site-packages\docx\parts\story.py:37 in get_or_add_image image_part = package.get_or_add_image_part(image_descriptor) File ~\anaconda3\Lib\site-packages\docx\package.py:31 in get_or_add_image_part return self.image_parts.get_or_add_image_part(image_descriptor) File ~\anaconda3\Lib\site-packages\docx\package.py:74 in get_or_add_image_part image = Image.from_file(image_descriptor) File ~\anaconda3\Lib\site-packages\docx\image\image.py:49 in from_file stream.seek(0) AttributeError: 'Figure' object has no attribute 'seek'
错误原因
run.add_picture()仅接受图片文件路径或二进制流对象,但当前传入的是matplotlib的Figure对象,该对象不具备文件流的seek()方法,导致报错。此外子模块已将图片保存为本地文件,直接使用文件路径即可。
修改方案
1. 被调用模块(Trapezoid_in_Cartesian_Grid_1.py)修改
调整函数返回值为图片文件路径,优化图形设置并释放内存:
from datetime import datetime import matplotlib.pyplot as plt import numpy as np from matplotlib.path import Path import matplotlib.patches as patches from matplotlib.ticker import MultipleLocator import matplotlib.ticker as ticker import random def ReflectTrap01OverXaxis(a,b,h,k): # 创建梯形顶点 verts1 = [(a,b),(a+h,b),(a+h,b-k),(a,b-k+1),(a,b)] codes1 = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY] # 提前设置图尺寸,创建Figure fig = plt.figure(figsize=(3.0, 3.0)) ax = fig.add_subplot(111) path1 = Path(verts1, codes1) patch1 = patches.PathPatch(path1, edgecolor="black", facecolor="None", lw=1, zorder=3) ax.add_patch(patch1) # 设置坐标轴与网格 ax.set_xlim(-12,12) ax.set_ylim(-12,12) plt.grid(True) plt.tick_params(labelsize=6) plt.xlabel(None, fontsize=7) plt.axhline(color="black") plt.axvline(color="black") ax.grid(which="both", color="black", linewidth=0.4) ax.minorticks_on() # 生成唯一图片文件名并保存 current_datetime = datetime.now().strftime("%Y-%m-%d %H%M%S") img_path = f"fig1_{current_datetime}.jpg" plt.savefig(img_path, dpi=1200, format="jpg") plt.close(fig) # 关闭Figure释放内存 return img_path # 返回图片路径
2. 主模块修改
接收图片路径传入add_picture,修正表格单元格索引错误:
import os import random from docx import Document from docx.shared import Inches from datetime import datetime import Trapezoid_in_Cartesian_Grid_1 doc = Document() # 创建3列表格 tbl = doc.add_table(rows=1, cols=0) tbl.add_column(width=Inches(0.4)) tbl.add_column(width=Inches(3.0)) tbl.add_column(width=Inches(3.0)) # 设置表头(可选) header_row = tbl.rows[0] header_row.cells[0].text = "序号" header_row.cells[1].text = "题目要求" header_row.cells[2].text = "图形" for i in range(10): a = random.randint(-8,8) b = random.randint(-8,8) h = random.randint(-3,3) k = random.randint(-3,3) img_path = Trapezoid_in_Cartesian_Grid_1.ReflectTrap01OverXaxis(a,b,h,k) # 添加新行并填充内容 row = tbl.add_row() row.cells[0].text = str(i+1) + "." row.cells[1].text = "Reflect the figure over the y-axis." # 向当前行第三列添加图片 paragraph = row.cells[2].paragraphs[0] run = paragraph.add_run() run.add_picture(img_path, width=Inches(3.0), height=Inches(3.0)) # 可选:删除临时图片,避免生成过多文件 # os.remove(img_path) # 生成文档文件名并设置表头 current_datetime = datetime.now().strftime("%Y-%m-%d %H%M%S") file_name = f"WS_Proj_{current_datetime}" header = doc.sections[0].header header.paragraphs[0].text = file_name doc.save(f"{file_name}.docx")
额外说明
- 被调用模块中,将
plt.rcParams["figure.figsize"]改为创建Figure时直接指定figsize,确保尺寸设置生效。 - 添加
plt.close(fig)避免多次循环后内存占用过高。 - 主模块修正了单元格引用错误,原代码会一直往表头单元格添加图片,现在改为当前行的对应单元格。
- 可启用
os.remove(img_path)删除临时图片,减少文件冗余。
内容的提问来源于stack exchange,提问作者Mark Barry
相关产品推荐
相关产品推荐

