如何使用 FPDF 和 Streamlit 将子图保存为 PDF
How to save subplot as PDF using FPDF and Streamlit
我有一个要保存为 PDF 的子图。我正在尝试在 Streamlit 应用程序中执行此操作并创建我正在使用 FPDF 库的 PDF。
子图工作没有任何问题。问题是我无法将其另存为 PDF,因为会显示一条错误消息,指出我要保存的图形未定义。
这就是我创建包含子图的图形的方式:
fig1, (ax1, ax2) = plt.subplots(1, 2)
hip_angle, _, _ = angle_calculation(merged)
hip_angle_2, _, _ = angle_calculation(merged_2)
sub_plotting(freq_left, hip_angle_2, 'Hip angle - Left leg', ax1)
sub_plotting(freq_right, hip_angle, 'Hip angle - Right leg', ax2)
ax1.set_xlabel('Gait phase %')
ax2.set_xlabel('Gait phase %')
ax1.set_ylabel('Angle (degrees)')
ax2.set_ylabel('Angle (degrees)')
ax1.set_xticks(np.arange(0, 110, step=10))
ax2.set_xticks(np.arange(0, 110, step=10))
ax1.set_ylim([-20, 50])
ax2.set_ylim([-20, 50])
ax1.set_aspect('auto')
ax2.set_aspect('auto')
fig1.set_figheight(8)
fig1.set_figwidth(18)
st.pyplot(fig1)
# Here I am just creating a button to download the figure
fig = 'Hip angle.png'
plt.savefig(fig)
with open(fig, "rb") as f:
btn = st.download_button(
label="Descarregar imagem",
data=f,
file_name=fig,
mime="image/png")
这就是我用来尝试保存 PDF 中的图形的方法。
checkbox = st.checkbox('Name', value='')
if checkbox:
name = st.text_input('Nome do utente', value=' ')
st.download_button(
label="Descarregar relatório",
data=create_pdf(fig1),
file_name="Relatório.pdf",
mime="application/pdf",
)
正如我提到的,有一个错误指出 fig1
未定义。
这是我用来创建 PDF 模板的函数。
def create_pdf(figure1):
pdf = FPDF()
pdf.add_page()
figure = io.BytesIO()
figure1.savefig(figure, format="png")
saved_fig = tempfile.NamedTemporaryFile()
with open(f"{saved_fig.name}.png", 'wb') as sf:
sf.write(figure.getvalue())
pdf.set_xy(30, 50)
pdf.image(figure1, w=140, h=110)
figure.close()
return bytes(pdf.output())
这是一个适用于 pdf 下载的简化代码。我们首先基于 png 文件创建 pdf 文件。创建后,我们将其用于下载。
代码
import matplotlib.pyplot as plt
import streamlit as st
from fpdf import FPDF
def create_pdf(img_fn, pdf_fn):
"""
Create pdf written to pdf_fn with the image file img_fn.
"""
pdf = FPDF()
pdf.add_page()
# Save to pdf
pdf.set_xy(30, 50)
pdf.image(img_fn, w=140, h=110)
pdf.output(pdf_fn)
def main():
x = [1, 2, 3, 4, 5, 6]
y = [1, 5, 3, 5, 7, 8]
fig1, (ax1, ax2) = plt.subplots(1, 2)
ax1.plot(x, y)
ax2.scatter(x, y)
st.pyplot(fig1)
# Save to png
img_fn = 'Hip angle.png'
fig1.savefig(img_fn)
# Prepare file for download.
dfn = 'angle.png'
with open(img_fn, "rb") as f:
st.download_button(
label="Descarregar imagem",
data=f,
file_name=dfn,
mime="image/png")
# pdf download
checkbox = st.checkbox('Name', value='')
if checkbox:
pdf_fn = 'mypdf.pdf'
create_pdf(img_fn, pdf_fn)
with open(pdf_fn, 'rb') as h_pdf:
st.download_button(
label="Descarregar relatório",
data=h_pdf,
file_name="Relatório.pdf",
mime="application/pdf",
)
if __name__ == '__main__':
main()
输出
下载的 png 输出:
已下载 pdf 输出
我有一个要保存为 PDF 的子图。我正在尝试在 Streamlit 应用程序中执行此操作并创建我正在使用 FPDF 库的 PDF。 子图工作没有任何问题。问题是我无法将其另存为 PDF,因为会显示一条错误消息,指出我要保存的图形未定义。 这就是我创建包含子图的图形的方式:
fig1, (ax1, ax2) = plt.subplots(1, 2)
hip_angle, _, _ = angle_calculation(merged)
hip_angle_2, _, _ = angle_calculation(merged_2)
sub_plotting(freq_left, hip_angle_2, 'Hip angle - Left leg', ax1)
sub_plotting(freq_right, hip_angle, 'Hip angle - Right leg', ax2)
ax1.set_xlabel('Gait phase %')
ax2.set_xlabel('Gait phase %')
ax1.set_ylabel('Angle (degrees)')
ax2.set_ylabel('Angle (degrees)')
ax1.set_xticks(np.arange(0, 110, step=10))
ax2.set_xticks(np.arange(0, 110, step=10))
ax1.set_ylim([-20, 50])
ax2.set_ylim([-20, 50])
ax1.set_aspect('auto')
ax2.set_aspect('auto')
fig1.set_figheight(8)
fig1.set_figwidth(18)
st.pyplot(fig1)
# Here I am just creating a button to download the figure
fig = 'Hip angle.png'
plt.savefig(fig)
with open(fig, "rb") as f:
btn = st.download_button(
label="Descarregar imagem",
data=f,
file_name=fig,
mime="image/png")
这就是我用来尝试保存 PDF 中的图形的方法。
checkbox = st.checkbox('Name', value='')
if checkbox:
name = st.text_input('Nome do utente', value=' ')
st.download_button(
label="Descarregar relatório",
data=create_pdf(fig1),
file_name="Relatório.pdf",
mime="application/pdf",
)
正如我提到的,有一个错误指出 fig1
未定义。
这是我用来创建 PDF 模板的函数。
def create_pdf(figure1):
pdf = FPDF()
pdf.add_page()
figure = io.BytesIO()
figure1.savefig(figure, format="png")
saved_fig = tempfile.NamedTemporaryFile()
with open(f"{saved_fig.name}.png", 'wb') as sf:
sf.write(figure.getvalue())
pdf.set_xy(30, 50)
pdf.image(figure1, w=140, h=110)
figure.close()
return bytes(pdf.output())
这是一个适用于 pdf 下载的简化代码。我们首先基于 png 文件创建 pdf 文件。创建后,我们将其用于下载。
代码
import matplotlib.pyplot as plt
import streamlit as st
from fpdf import FPDF
def create_pdf(img_fn, pdf_fn):
"""
Create pdf written to pdf_fn with the image file img_fn.
"""
pdf = FPDF()
pdf.add_page()
# Save to pdf
pdf.set_xy(30, 50)
pdf.image(img_fn, w=140, h=110)
pdf.output(pdf_fn)
def main():
x = [1, 2, 3, 4, 5, 6]
y = [1, 5, 3, 5, 7, 8]
fig1, (ax1, ax2) = plt.subplots(1, 2)
ax1.plot(x, y)
ax2.scatter(x, y)
st.pyplot(fig1)
# Save to png
img_fn = 'Hip angle.png'
fig1.savefig(img_fn)
# Prepare file for download.
dfn = 'angle.png'
with open(img_fn, "rb") as f:
st.download_button(
label="Descarregar imagem",
data=f,
file_name=dfn,
mime="image/png")
# pdf download
checkbox = st.checkbox('Name', value='')
if checkbox:
pdf_fn = 'mypdf.pdf'
create_pdf(img_fn, pdf_fn)
with open(pdf_fn, 'rb') as h_pdf:
st.download_button(
label="Descarregar relatório",
data=h_pdf,
file_name="Relatório.pdf",
mime="application/pdf",
)
if __name__ == '__main__':
main()