
本文详解如何使用 pandas、matplotlib 和 xlsxwriter 将多列时间序列数据自动绘制成图表,并以紧凑的两列网格形式批量插入 excel,避免图表错位、间距失控等问题。
本文详解如何使用 pandas、matplotlib 和 xlsxwriter 将多列时间序列数据自动绘制成图表,并以紧凑的两列网格形式批量插入 excel,避免图表错位、间距失控等问题。
在将 Python 绘制的图表导出到 Excel 时,原代码仅通过线性累加 y_offset 实现垂直堆叠,导致所有图表纵向排列、间隔过大(如首图在列 D、次图跳至列 AFD),且未控制列位置,无法形成规整网格。要实现「每行 2 图」的整齐布局,关键在于动态计算单元格坐标(row, col)而非像素偏移(x_offset, y_offset),并合理设置图像缩放比例与行列间距。
以下是优化后的完整实现方案:
import pandas as pd
import matplotlib.pyplot as plt
import xlsxwriter
import io
def generate_seasonal_charts(file_path, start_date, end_date, output_file):
# 数据读取与预处理
df = pd.read_excel(file_path)
df['Date'] = pd.to_datetime(df['Date'])
df = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
df.set_index('Date', inplace=True)
# 创建 Excel 工作簿与工作表
workbook = xlsxwriter.Workbook(output_file)
worksheet = workbook.add_worksheet("Charts")
# 图表参数配置(单位:像素)
image_width_px = 800
image_height_px = 400
row_height = 30 # Excel 行高(约对应 40 像素)
col_width = 15 # Excel 列宽(约对应 114 像素)
# 每行显示 2 个图表 → 计算起始单元格位置(row, col)
charts_per_row = 2
chart_row_start = 1 # 从第 2 行开始(索引为 1,跳过标题行)
chart_col_start = 1 # 从 B 列开始(索引为 1)
# 遍历所有数据列(跳过索引列 'Date',即 df.columns[0])
for i, column in enumerate(df.columns):
if column == 'Date': # 显式跳过日期列(更健壮于 df.columns[1:])
continue
# 计算当前图表所在 Excel 单元格位置
row_idx = chart_row_start + (i // charts_per_row) * 25 # 每图占约 25 行(预留空间)
col_idx = chart_col_start + (i % charts_per_row) * 15 # 每图占约 15 列宽度
# 绘图
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(df.index, df[column], linewidth=1.5)
ax.set_xlabel('Date')
ax.set_ylabel('Price')
ax.set_title(f'Price Trend: {column}', fontsize=12, fontweight='bold')
ax.grid(True, alpha=0.7)
plt.tight_layout()
# 保存为 PNG 字节流
buf = io.BytesIO()
fig.savefig(buf, format='png', dpi=120, bbox_inches='tight')
buf.seek(0)
# 插入 Excel:使用 cell position(非 pixel offset)+ 自适应缩放
# x_scale / y_scale 确保图像清晰填充指定区域(推荐固定比例)
worksheet.insert_image(
row_idx, col_idx, '',
{
'image_data': buf,
'x_scale': 1.0,
'y_scale': 1.0,
'positioning': 1 # 可移动可调整大小(Excel 中双击可编辑)
}
)
plt.close(fig)
workbook.close()
print(f"✅ Charts successfully exported to {output_file}")
# ✅ 正确调用方式(修复原代码中位置错误的函数调用)
if __name__ == "__main__":
file_path = "chart testing.xlsx"
output_file = "output_with_grid.xlsx"
start_date = '2018-01-01'
end_date = '2023-12-31'
generate_seasonal_charts(file_path, start_date, end_date, output_file)关键改进说明:
诊断并修复涉及公式、命名范围、Power Query 刷新、数据透视表、VBA/宏保存等问题的 Microsoft Excel XLSX 工作簿
- ✅ 网格定位逻辑:使用
(i // 2)控制行号递增、(i % 2)控制列号轮换,天然实现「左→右、上→下」的网格填充; - ✅ Excel 坐标系优先:
insert_image(row, col, ...)直接指定单元格位置,彻底规避像素偏移导致的错位(如 AFD 列异常); - ✅ 响应式缩放:设
'x_scale': 1.0, 'y_scale': 1.0并配合positioning=1,使图像在 Excel 中自动适配单元格区域,双击可拖拽调整; - ✅ 健壮性增强:显式跳过
'Date'列(而非依赖df.columns[1:]),避免列顺序变动引发错误; - ✅ 结构规范:将入口逻辑封装于
if __name__ == "__main__":,消除原代码中workbook.close()后误写参数的严重语法隐患。
注意事项:
立即学习“Python免费学习笔记(深入)”;
- Excel 中图像默认锚定在单元格左上角,若需微调,可在 Excel 中选中图片 → 「格式图片」→「属性」→ 选择「大小和属性」手动对齐;
- 若图表过多导致 Excel 行数溢出,可增大
* 25中的乘数(如改为* 30)以增加行间距; -
dpi=120保障导出图像清晰度,低于 96 可能模糊,高于 150 会显著增大文件体积。
通过以上重构,您即可一键生成专业、紧凑、易维护的多图表 Excel 报告,真正实现“所见即所得”的网格化可视化输出。

















