Jav*_*más 2 python pdf report matplotlib pandas
我需要一份包含很多图的 PDF 报告。它们中的大多数将在循环中使用 matplotlib 创建,但我还需要包括 Pandas 图和数据框(整个视图)和 seaborn 图。现在我已经探索了以下解决方案:
savefig在循环的每次迭代中使用command 并将所有绘图保存为图像,以便稍后将所有绘图插入 Latex 中。这也将是非常耗时的选择。另一个选项是使用该命令将绘图保存为 pdf,然后合并所有 pdf。这将创建一个丑陋的报告,因为这些图不会适合整个页面。所以我的问题如下:是否有任何简单快捷的方法可以将所有这些图(如果它沿着生成它们的代码更好)以一个体面的方面呈现在 PDF 中?
我的建议是将 matplotlibssavefig用于BytesIO缓冲区(或将缓冲区保存到列表或类似的数据结构中 100)。然后,您可以使用这些图像缓冲区将图像插入到 pdf 中,使用的库如reportlab(此处的网站和此处的文档)。我经常使用这种方法来使用python-pptx库创建 PowerPoint 文档,但也通过带有reportlab. reportlablibrary 非常强大,而且有点“低级”,因此入门可能会有一点学习曲线,但它肯定能满足您的需求。有入门教程简单的在这里。reportlab 是 BSD 许可证,可在 pip 和 conda 上使用。
无论如何,我的代码片段看起来像这样。
对不起,它有点长,但我的代码有一些帮助函数来打印文本和虚拟图像。您应该能够直接复制/粘贴它。
import io
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
import numpy as np
import matplotlib.pyplot as plt
def plot_hist():
""" Create a sample histogram plot and return a bytesio buffer with plot
Returns
-------
BytesIO : in memory buffer with plot image, can be passed to reportlab or elsewhere
"""
# from https://matplotlib.org/gallery/lines_bars_and_markers/scatter_masked.html#sphx-glr-gallery-lines-bars-and-markers-scatter-masked-py
plt.figure(figsize=(7, 2.25))
N = 100
r0 = 0.6
x = 0.9 * np.random.rand(N)
y = 0.9 * np.random.rand(N)
area = (20 * np.random.rand(N))**2 # 0 to 10 point radii
c = np.sqrt(area)
r = np.sqrt(x * x + y * y)
area1 = np.ma.masked_where(r < r0, area)
area2 = np.ma.masked_where(r >= r0, area)
plt.scatter(x, y, s=area1, marker='^', c=c)
plt.scatter(x, y, s=area2, marker='o', c=c)
# Show the boundary between the regions:
theta = np.arange(0, np.pi / 2, 0.01)
plt.plot(r0 * np.cos(theta), r0 * np.sin(theta))
# create buffer and save image to buffer
# dpi should match the dpi of your PDF, I think 300 is typical otherwise it won't pretty well
buf = io.BytesIO()
plt.savefig(buf, format='png', dpi=300)
buf.seek(0)
# you'll want to close the figure once its saved to buffer
plt.close()
return buf
def add_text(text, style="Normal", fontsize=12):
""" Adds text with some spacing around it to PDF report
Parameters
----------
text : str
The string to print to PDF
style : str
The reportlab style
fontsize : int
The fontsize for the text
"""
Story.append(Spacer(1, 12))
ptext = "<font size={}>{}</font>".format(fontsize, text)
Story.append(Paragraph(ptext, styles[style]))
Story.append(Spacer(1, 12))
# Use basic styles and the SimpleDocTemplate to get started with reportlab
styles=getSampleStyleSheet()
doc = SimpleDocTemplate("form_letter.pdf",pagesize=letter,
rightMargin=inch/2,leftMargin=inch/2,
topMargin=72,bottomMargin=18)
# The "story" just holds "instructions" on how to build the PDF
Story=[]
add_text("My Report", style="Heading1", fontsize=24)
# See plot_hist for information on how to get BytesIO object of matplotlib plot
# This code uses reportlab Image function to add and valid PIL input to the report
image_buffer1 = plot_hist()
im = Image(image_buffer1, 7*inch, 2.25*inch)
Story.append(im)
add_text("This text explains something about the chart.")
image_buffer2 = plot_hist()
im = Image(image_buffer2, 7*inch, 2.25*inch)
Story.append(im)
add_text("This text explains something else about another chart chart.")
# This command will actually build the PDF
doc.build(Story)
# should close open buffers, can use a "with" statement in python to do this for you
# if that works better
image_buffer1.close()
image_buffer2.close()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3108 次 |
| 最近记录: |