使用Python制作Excel组合图表的完整指南
作者:杨利杰YJlio
这一篇主要解决一个很常见的问题:单独看柱形图只能看数量,单独看折线图只能看趋势,但真实汇报往往需要同时看“量”和“变化”。比如桌面支持月报里,既要看每个月工单数量,又要看解决率、满意度、平均处理时长,如果分成多张图,读者就要来回对照;如果强行塞进同一个坐标轴,又很容易因为量级不同导致折线贴地爬行。
组合图的价值就在这里:柱形图负责表达数量,折线图负责表达趋势,一张图把多个维度的信息放到同一个分析场景里。
这张图展示了组合图表的核心主题:用柱形图看数量,用折线图看趋势。

从这张图中可以看出,组合图并不是为了“把图做得更复杂”,而是为了让一张图同时承载数量、趋势、比例、变化方向等信息。这里要注意,组合图只有在数据关系明确时才有价值,不能为了炫技硬组合。
读完这篇文章,至少要带走三件事:
- 知道什么时候应该使用组合图,而不是柱形图或折线图;
- 理解同坐标轴组合图和双 y 轴组合图的区别;
- 能用 Python 从 Excel 读取数据,生成一张可用于报告的组合图 PNG。
2. 绘制组合图:同坐标轴适合量级相近的数据
组合图最简单的做法,是把柱形图和折线图画在同一个坐标轴里。这个方法适合两组数据的数值范围差不多,比如“工单数量”和“处理时长评分”、“销售额”和“订单数量指数”这类相对接近的数据。
但这里有一个硬前提:两组数据的量级必须接近。如果一组数据是 0~10000,另一组数据是 0~100,强行放在同一个 y 轴上,小的那条线基本看不清,这种图表不是分析,而是在制造误读。
这张图展示了同坐标轴组合图的效果,适合把量级相近的数据放在一起观察。

从这张图中可以看出,柱形图和折线图共享同一个 y 轴,读者可以直接比较两组数据的变化节奏。它的优点是简单直观,缺点也明显:一旦两组数据量级差异过大,图表就会失真。
下面是同坐标轴组合图的最小可用代码:
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
months = ["1月", "2月", "3月", "4月", "5月", "6月"]
tickets = [120, 98, 135, 110, 150, 160] # 柱形:工单数量
avg_time = [80, 75, 90, 82, 88, 95] # 折线:处理效率评分
x = np.arange(len(months))
plt.figure(figsize=(9, 6))
plt.bar(x, tickets, width=0.6, label="工单数量", alpha=0.75)
plt.plot(x, avg_time, marker="o", linewidth=2, label="处理效率评分")
plt.xticks(x, months)
plt.title("组合图:工单数量 + 处理效率评分")
plt.xlabel("月份")
plt.ylabel("数值")
plt.grid(axis="y", linestyle="--", alpha=0.4)
plt.legend()
plt.tight_layout()
plt.show()
推荐做法:同坐标轴组合图适合用在“两个指标都能放到同一个数值尺度下解释”的场景。只要你发现其中一条线被压得几乎看不见,就不要硬撑,应该改用双 y 轴。
3. 设置不同坐标轴:双 y 轴组合图解决量级差异
真实工作里更常见的是另一种情况:柱形图表示数量,折线图表示百分比。例如“工单数量”可能是几千单,“解决率”却是 0~100%。这两个指标如果放在同一个 y 轴上,解决率折线会被压扁,看起来几乎没有变化。
这时候就要用 Matplotlib 的 twinx() 创建第二个 y 轴。左边 y 轴给柱形图,右边 y 轴给折线图。
这张图展示了双 y 轴组合图的典型用法:左轴看工单量,右轴看解决率。

从这张图中可以看出,双 y 轴最大的价值是解决“单位不同、量级不同”的问题。左侧 y 轴承载数量,右侧 y 轴承载百分比,读者既能看到业务量变化,也能看到质量指标是否跟得上。
下面是双 y 轴组合图的代码模板:
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
months = ["1月", "2月", "3月", "4月", "5月", "6月"]
tickets = [120, 98, 135, 110, 150, 160] # 柱形:工单数量
solve_rate = [92, 88, 95, 90, 96, 97] # 折线:解决率
x = np.arange(len(months))
fig, ax1 = plt.subplots(figsize=(9, 6))
# 左轴:柱形图
ax1.bar(x, tickets, width=0.6, alpha=0.75, label="工单数量")
ax1.set_xlabel("月份")
ax1.set_ylabel("工单数量(单)")
ax1.set_xticks(x)
ax1.set_xticklabels(months)
ax1.grid(axis="y", linestyle="--", alpha=0.4)
# 右轴:折线图
ax2 = ax1.twinx()
ax2.plot(x, solve_rate, marker="o", linewidth=2, linestyle="--", label="解决率(%)")
ax2.set_ylabel("解决率(%)")
ax2.set_ylim(0, 100)
# 合并图例
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1 + h2, l1 + l2, loc="upper left")
plt.title("组合图:工单数量(柱) + 解决率(折线)")
plt.tight_layout()
plt.show()
注意:双 y 轴不是万能方案。它能提高可读性,也可能制造误解。尤其是右轴范围如果随意缩放,会让一条折线看起来“波动很大”,实际可能只是 1%~2% 的变化。
4. 组合图的核心判断:不是能不能画,而是该不该画
很多人学图表时容易进入一个误区:只要代码能画出来,就觉得图表是合理的。但在真实汇报里,图表首先是表达工具,不是代码炫技。组合图尤其如此,因为它把两个甚至多个指标放在一起,如果没有清晰的业务关系,读者反而更难理解。
我判断一张组合图是否应该使用,通常看三个问题:
- 两组数据是否有业务关联;
- 两组数据是否需要放在同一时间维度下观察;
- 读者是否能通过一张图得出更清晰的判断。
举个桌面运维的例子:
| 场景 | 柱形图指标 | 折线图指标 | 是否适合组合图 |
|---|---|---|---|
| 月度工单复盘 | 工单数量 | 解决率 | 适合 |
| 镜像上线评估 | 投诉数量 | 稳定率 | 适合 |
| 资产盘点 | 设备数量 | 品牌占比 | 不太适合 |
| 网络排障 | 断网次数 | 平均恢复时长 | 适合 |
| 用户满意度 | 满意人数 | 满意率 | 适合 |
推荐做法:组合图应该服务于一个明确判断,例如“业务量增加后,服务质量有没有下降?”“工单减少后,处理效率有没有提升?”如果没有这种判断目标,就不建议强行做组合图。
5. 企业可交付版:从 Excel 读取数据,一键生成组合图并保存 PNG
如果只是手写几组列表画图,学习意义有,但工作价值有限。真正能落地的做法,是从 Excel 读取数据,然后自动生成 PNG。这样每次月报、周报、数据复盘,只需要更新 Excel 数据,脚本就能重新输出图表。
这张图展示了从 Excel 数据读取、Python 生成组合图、最终保存 PNG 的完整流程。

从这张图中可以看出,自动化出图的关键不在于单个绘图函数,而在于形成一条完整链路:读取数据 → 清洗字段 → 生成图表 → 保存文件 → 用于报告。这才是办公自动化的实际价值。
假设 Excel 中有三列:
| 月份 | 工单数量 | 解决率 |
|---|---|---|
| 1月 | 120 | 92 |
| 2月 | 98 | 88 |
| 3月 | 135 | 95 |
可以使用下面这段代码生成组合图:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
def excel_to_combo_chart(
xlsx_path: str,
sheet: str,
x_col: str,
bar_col: str,
line_col: str,
out_png: str = "out/combo.jpg",
line_is_percent: bool = True
):
df = pd.read_excel(xlsx_path, sheet_name=sheet)
# 读取并清洗数据
x_labels = df[x_col].astype(str).tolist()
bar = pd.to_numeric(df[bar_col], errors="coerce").fillna(0).tolist()
line = pd.to_numeric(df[line_col], errors="coerce").fillna(0).tolist()
x = np.arange(len(x_labels))
fig, ax1 = plt.subplots(figsize=(10, 6))
# 左轴:柱形图
ax1.bar(x, bar, width=0.6, alpha=0.75, label=bar_col)
ax1.set_xlabel(x_col)
ax1.set_ylabel(bar_col)
ax1.set_xticks(x)
ax1.set_xticklabels(x_labels)
ax1.grid(axis="y", linestyle="--", alpha=0.4)
# 给柱形图加数据标签
for i, v in enumerate(bar):
ax1.text(i, v, str(int(v)), ha="center", va="bottom")
# 右轴:折线图
ax2 = ax1.twinx()
ax2.plot(x, line, marker="o", linewidth=2, linestyle="--", label=line_col)
ax2.set_ylabel(line_col)
if line_is_percent:
ax2.set_ylim(0, 100)
# 合并图例
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1 + h2, l1 + l2, loc="upper left")
plt.title(f"组合图:{bar_col}(柱) + {line_col}(折线)")
plt.tight_layout()
out_png = Path(out_png)
out_png.parent.mkdir(parents=True, exist_ok=True)
plt.savefig(out_png, dpi=200)
plt.close()
return str(out_png)
if __name__ == "__main__":
png = excel_to_combo_chart(
xlsx_path="report.xlsx",
sheet="数据",
x_col="月份",
bar_col="工单数量",
line_col="解决率",
out_png="out/组合图_工单数量_解决率.jpg",
line_is_percent=True
)
print("已输出:", png)
这段代码的关键点有三个:第一,使用 pandas 从 Excel 读取数据;第二,使用 twinx() 创建双 y 轴;第三,将图表保存为 PNG,方便插入 Word、PPT、Excel 或 CSDN 博客。
不要只看脚本有没有报错。生成图片以后,一定要打开 PNG 检查标题、图例、单位、数据范围是否合理。图能生成,不代表图就是对的。
6. 常见坑:组合图最容易“看着对,其实错”
组合图最危险的地方,不是代码写不出来,而是图表看起来很专业,实际表达却有问题。尤其是双 y 轴组合图,如果坐标范围、单位、图例没有处理好,读者很容易被误导。
这张图展示了组合图常见坑与规范,包括单位清楚、标签清晰、范围锁定、图例合并等关键点。

从这张图中可以看出,一张可交付的组合图不只是“柱形 + 折线”这么简单,还要保证单位清楚、标签不拥挤、图例能看懂、百分比范围合理。否则图表越复杂,误导风险越高。
6.1 右轴不锁范围,趋势可能被夸大
如果折线表示百分比,比如解决率、满意度、达成率,我建议右轴固定为 0~100。否则 Matplotlib 自动缩放后,95% 到 97% 的变化可能被画得像大幅波动。
ax2.set_ylim(0, 100)
推荐做法:百分比指标优先锁定 0~100,除非你明确告诉读者这是局部放大图。
6.2 两边单位不写清楚,图表就没有交付价值
左轴是“单”,右轴是“%”,必须写在轴标题里。否则读者只能靠猜,这对技术文章和工作汇报都不合格。
ax1.set_ylabel("工单数量(单)")
ax2.set_ylabel("解决率(%)")
6.3 图例只显示一边,会导致读者看不懂
双 y 轴图表有两个坐标轴对象,分别是 ax1 和 ax2。如果只调用一边的 legend(),图例可能只显示柱形图,不显示折线图。
h1, l1 = ax1.get_legend_handles_labels() h2, l2 = ax2.get_legend_handles_labels() ax1.legend(h1 + h2, l1 + l2, loc="upper left")
这个问题很隐蔽。因为图已经画出来了,但读者不知道每条线代表什么,最终会降低整张图的可信度。
7. 效果验证:一张组合图是否合格,看这 5 点
脚本执行完成以后,不要只看 PNG 文件是否生成。我更建议从“交付视角”检查图表,因为组合图最终是给人看的,不是给 Python 自己看的。
我通常按下面 5 点验收:
- 标题是否说明图表主题:例如“工单数量 + 解决率趋势”;
- 左右 y 轴单位是否明确:一个是数量,一个是百分比;
- 图例是否完整:柱形和折线都能对应上;
- 数据标签是否影响阅读:标签不能挤在一起;
- 坐标范围是否合理:百分比是否锁定 0~100,数量是否留有顶部空间。
真正的验证不是“有没有生成图”,而是“图能不能支持你要表达的判断”。比如你要说明“工单量增长但解决率没有下降”,那读者应该能从图里一眼看出来。
8. 本节小结:组合图是一张图讲完“量 + 趋势 + 质量”
这一节我真正掌握的不是某一行代码,而是组合图背后的表达逻辑。柱形图适合表达数量,折线图适合表达趋势,双 y 轴适合处理不同单位和不同量级的数据。
我把这节内容总结成四句话:
- 同量级数据:可以使用同坐标轴组合图;
- 不同量级数据:优先考虑双 y 轴组合图;
- 百分比指标:建议锁定 0~100,避免视觉误导;
- 自动化交付:从 Excel 读取数据,生成 PNG,才是真正可复用的办公自动化流程。
组合图不是为了让图表“看起来高级”,而是为了让读者在一张图里同时看清:业务量有没有变化,趋势有没有变化,质量有没有跟上。
9. 我的总结提升
这一篇的核心,不是简单记住“制作组合图表展示多维信息”这个小节名称,而是要把它放到 Python + Excel 办公自动化的完整路径里理解。
真正有价值的读书笔记,应该做到三点:
- 知道它解决什么问题:不是为了画图而画图,而是为了让数据表达更清楚;
- 知道代码为什么这样写:尤其是
twinx()、图例合并、坐标范围锁定这些关键点; - 知道如何验证结果:图表生成以后,要检查单位、范围、图例和业务结论是否一致。
如果只会复制代码,但不能判断图表是否误导读者,这类图表反而会降低汇报质量。
所以我建议把组合图当成一个“汇报表达工具”,而不是单纯的 Matplotlib 练习。后续写周报、月报、工单统计、镜像上线效果评估时,这类图非常实用。
到此这篇关于使用Python制作Excel组合图表的完整指南的文章就介绍到这了,更多相关Python Excel组合图表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
