如何将Plotly figure factory标注热图无模糊插入PDF文件?
核心原因:你现在遇到的模糊是因为Plotly默认导出的PNG分辨率过低,属于栅格图像放大后必然出现的失真,仅调整ReportLab的绘制尺寸无法解决,需要从图像导出环节和格式选择入手优化,可按优先级尝试以下方案:
- 方案1:提高PNG导出分辨率(改动最小,快速生效)
给to_image方法添加scale参数,默认值为1,设为2~3即可获得足够的高清栅格图,修改对应代码为:
TrayLayoutView.graph_pdf_list.append(fig.to_image(format='png', scale=3))
也可同步指定导出的原生尺寸匹配你最终的绘制大小,避免缩放失真:
TrayLayoutView.graph_pdf_list.append(fig.to_image(format='png', width=700, height=700, scale=2))
- 方案2:使用矢量格式从根源避免模糊(清晰度最优)
矢量图不存在分辨率限制,任意缩放都不会失真,有两种实现方式可选:
第一种:直接导出PDF单页合并
跳过PNG中转环节,直接将Plotly图导出为PDF字节流,再用PDF处理库合并所有页面,完全保留矢量特性:
from PyPDF2 import PdfReader, PdfWriter from io import BytesIO # 导出环节改为存pdf字节 TrayLayoutView.graph_pdf_list.append(fig.to_image(format='pdf')) # 生成最终PDF response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = f'attachment; filename="{pdf_name}"' output = PdfWriter() for pdf_page_bytes in TrayLayoutView.graph_pdf_list: reader = PdfReader(BytesIO(pdf_page_bytes)) # 可根据需求调整页面尺寸匹配原需求的横版letter规格 output.add_page(reader.pages[0]) output.write(response)
第二种:导出SVG后用ReportLab绘制
如果需要保留原有ReportLab的页面布局、自定义页眉页脚等逻辑,可以导出为SVG格式后绘制:
# 提前安装依赖:pip install svglib from svglib.svglib import svg2rlg # 导出环节改为存svg字节 TrayLayoutView.graph_pdf_list.append(fig.to_image(format='svg')) # 绘制环节修改为: for svg_bytes in TrayLayoutView.graph_pdf_list: drawing = svg2rlg(BytesIO(svg_bytes)) # 按需求缩放适配页面 scale = 700 / max(drawing.width, drawing.height) drawing.scale(scale, scale) renderPDF.draw(drawing, page, x, y) page.showPage()
- 注意事项:如果选择方案1,不要在ReportLab绘制时将小分辨率的PNG拉伸到远大于原生尺寸的规格,否则即便调了scale也会出现模糊。
内容的提问来源于stack exchange,提问作者Medina
相关产品推荐
相关产品推荐

