本文目录导读:

- 使用Matplotlib + PdfPages(最常用)
- 使用ReportLab(专业PDF生成)
- 使用Plotly生成交互式图表并导出为PDF
- 使用Seaborn + Matplotlib
- 完整示例:生成报告PDF
- 安装必要的库
- 关键提示
我来介绍几种在Python中生成PDF图表的方法:
使用Matplotlib + PdfPages(最常用)
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
# 创建数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = x * 0.5
# 创建PDF文件
with PdfPages('charts.pdf') as pdf:
# 图表1: 折线图
plt.figure(figsize=(8, 6))
plt.plot(x, y1, label='sin(x)', linewidth=2)
plt.plot(x, y2, label='cos(x)', linewidth=2)
plt.title('三角函数曲线')
plt.xlabel('x值')
plt.ylabel('y值')
plt.legend()
plt.grid(True, alpha=0.3)
pdf.savefig() # 保存当前图表到PDF
plt.close()
# 图表2: 柱状图
plt.figure(figsize=(8, 6))
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 32]
plt.bar(categories, values, color='skyblue')
plt.title('分类数据柱状图')
plt.xlabel('类别')
plt.ylabel('数值')
pdf.savefig()
plt.close()
# 图表3: 散点图
plt.figure(figsize=(8, 6))
np.random.seed(42)
x_scatter = np.random.randn(100)
y_scatter = 2 * x_scatter + np.random.randn(100) * 0.5
plt.scatter(x_scatter, y_scatter, alpha=0.6, c='red')
plt.title('散点图示例')
plt.xlabel('X值')
plt.ylabel('Y值')
pdf.savefig()
plt.close()
使用ReportLab(专业PDF生成)
from reportlab.lib import colors
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.lineplots import LinePlot
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph
def create_reportlab_charts():
# 创建PDF文档
doc = SimpleDocTemplate("reportlab_charts.pdf", pagesize=A4)
# 创建柱状图
d = Drawing(400, 200)
bar_chart = VerticalBarChart()
bar_chart.x = 50
bar_chart.y = 50
bar_chart.height = 125
bar_chart.width = 300
bar_chart.data = [[13, 42, 49, 103, 85]]
bar_chart.categoryAxis.categoryNames = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5']
bar_chart.valueAxis.valueMin = 0
bar_chart.valueAxis.valueMax = 120
bar_chart.bars[0].fillColor = colors.HexColor('#2563EB')
d.add(bar_chart)
# 保存PDF
doc.build([d])
create_reportlab_charts()
使用Plotly生成交互式图表并导出为PDF
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
# 创建数据
df = px.data.iris()
# 创建散点图
fig = px.scatter(df, x="sepal_width", y="sepal_length",
color="species", size="petal_length",
title="鸢尾花数据集散点图")
# 导出为PDF(需要安装kaleido)
# pip install -U kaleido
fig.write_image("plotly_chart.pdf", format="pdf")
# 或者创建多个图表到一个PDF
import pdfkit # 需要安装: pip install pdfkit
# 创建html内容包含多个图表
html_content = """
<html>
<body>
<h2>图表报告</h2>
<div id="chart1"></div>
<div id="chart2"></div>
</body>
</html>
"""
# 转换为PDF
pdfkit.from_string(html_content, 'charts_report.pdf')
使用Seaborn + Matplotlib
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
# 设置风格
sns.set_theme(style="whitegrid")
# 加载示例数据
tips = sns.load_dataset("tips")
with PdfPages('seaborn_charts.pdf') as pdf:
# 图表1: 箱线图
plt.figure(figsize=(10, 6))
sns.boxplot(x="day", y="total_bill", data=tips, palette="Set2")
plt.title('每日消费金额分布')
pdf.savefig()
plt.close()
# 图表2: 热力图
plt.figure(figsize=(10, 8))
correlation = tips.corr()
sns.heatmap(correlation, annot=True, cmap='coolwarm', center=0)
plt.title('相关性热力图')
pdf.savefig()
plt.close()
# 图表3: 分布图
plt.figure(figsize=(12, 6))
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
sns.histplot(tips['total_bill'], kde=True, ax=axes[0])
axes[0].set_title('消费金额分布')
sns.scatterplot(x='total_bill', y='tip', hue='time',
data=tips, ax=axes[1])
axes[1].set_title('消费与小费关系')
pdf.savefig()
plt.close()
完整示例:生成报告PDF
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
from datetime import datetime
def generate_report_pdf():
"""生成包含多个图表和文字说明的PDF报告"""
with PdfPages('report.pdf') as pdf:
# 封面信息
plt.figure(figsize=(8.5, 11))
plt.axis('off')
plt.text(0.5, 0.6, '数据分析报告', fontsize=24,
ha='center', fontweight='bold')
plt.text(0.5, 0.5, f'生成日期: {datetime.now().strftime("%Y-%m-%d")}',
fontsize=14, ha='center')
plt.text(0.5, 0.4, '作者: Python脚本', fontsize=14, ha='center')
pdf.savefig()
plt.close()
# 图表1: 趋势分析
fig, ax1 = plt.subplots(figsize=(10, 6))
months = ['1月', '2月', '3月', '4月', '5月', '6月']
sales_2023 = [120, 135, 110, 180, 165, 200]
sales_2024 = [130, 150, 125, 195, 180, 220]
x = np.arange(len(months))
width = 0.35
ax1.bar(x - width/2, sales_2023, width, label='2023年', color='#3498db')
ax1.bar(x + width/2, sales_2024, width, label='2024年', color='#e74c3c')
ax1.set_xlabel('月份')
ax1.set_ylabel('销售额(万元)')
ax1.set_title('月销售额对比分析')
ax1.set_xticks(x)
ax1.set_xticklabels(months)
ax1.legend()
ax1.grid(True, alpha=0.3)
# 添加文字说明
plt.figtext(0.5, 0.01,
'图1显示2024年上半年销售额较2023年同期有所增长,'
'其中3月和4月增长最为明显。',
ha='center', fontsize=10, style='italic')
pdf.savefig()
plt.close()
# 图表2: 饼图
plt.figure(figsize=(8, 8))
categories = ['电子产品', '服装', '食品', '家居', '其他']
proportions = [35, 25, 20, 12, 8]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
plt.pie(proportions, labels=categories, colors=colors,
autopct='%1.1f%%', startangle=90, explode=(0.05, 0, 0, 0, 0))
plt.title('产品销售占比分析')
plt.figtext(0.5, 0.01,
'图2显示电子产品占比最高(35%),为主要收入来源。',
ha='center', fontsize=10, style='italic')
pdf.savefig()
plt.close()
# 添加元数据
d = pdf.infodict()
d['Title'] = '销售数据分析报告'
d['Author'] = 'Python脚本'
d['Subject'] = '2024年上半年销售数据分析'
d['CreationDate'] = datetime.now()
# 生成报告
generate_report_pdf()
print("PDF报告已生成:report.pdf")
安装必要的库
pip install matplotlib numpy seaborn # 如果需要ReportLab pip install reportlab # 如果需要Plotly导出PDF pip install plotly kaleido
关键提示
- Matplotlib + PdfPages 是最常用和灵活的方式
- ReportLab 适合专业的PDF生成,但不如图表库方便
- Plotly 适合交互式图表,但导出PDF需要额外工具
- 设置中文字体以避免乱码:
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False
根据你的具体需求选择合适的方案,通常Matplotlib+PdfPages就能满足大多数场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播