我的知识记录

Python图表叠加柱状图折线图组合图:双轴混合图表

用Python matplotlib在一张图上叠加柱状图和折线图,双Y轴展示量级不同的两个指标,代码完整可运行,适合销售业绩和增长率组合分析。

场景痛点

做经营分析时,一张图上想同时看"月度销售额(柱)"和"利润率(线)",销售额几十万、利润率百分之几,两个指标量级差100倍,硬放一个轴折线就贴底了。Excel做组合图要右键"更改系列图表类型"再选次坐标轴,操作绕。matplotlib用 twinx() 几行代码就能把柱子和折线叠在一张图上,左轴柱、右轴线,一目了然。

用到的库

pip install matplotlib

完整代码

# 导入库
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

# 解决中文乱码
matplotlib.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "Arial Unicode MS"]
matplotlib.rcParams["axes.unicode_minus"] = False


def draw_combo_chart():
months = ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月"]
sales = [120, 150, 180, 160, 210, 260, 240, 290]       # 销售额(万元)
profit_rate = [0.18, 0.20, 0.22, 0.19, 0.24, 0.26, 0.25, 0.28]  # 利润率

fig, ax1 = plt.subplots(figsize=(10, 6))

# ===== 左轴:柱状图 销售额 =====
bar_color = "#4C72B0"
bars = ax1.bar(months, sales, color=bar_color, alpha=0.7, width=0.5, label="销售额")
ax1.set_xlabel("月份", fontsize=12)
ax1.set_ylabel("销售额(万元)", fontsize=12, color=bar_color)
ax1.tick_params(axis="y", labelcolor=bar_color)
ax1.set_ylim(0, 360)

# 柱顶标注销售额
for bar in bars:
h = bar.get_height()
ax1.text(bar.get_x() + bar.get_width() / 2, h + 5,
f"{h}", ha="center", fontsize=9, color=bar_color)

# ===== 右轴:折线 利润率 =====
ax2 = ax1.twinx()
line_color = "#C44E52"
ax2.plot(months, profit_rate, color=line_color, marker="o",
linewidth=2.5, markersize=8, label="利润率")
ax2.set_ylabel("利润率", fontsize=12, color=line_color)
ax2.tick_params(axis="y", labelcolor=line_color)
ax2.set_ylim(0, 0.4)
# 右轴格式化成百分比
ax2.yaxis.set_major_formatter(plt.FuncFormatter(lambda v, _: f"{v:.0%}"))

# 折线点上方标注利润率
for i, rate in enumerate(profit_rate):
ax2.text(i, rate + 0.015, f"{rate:.0%}", ha="center",
fontsize=9, color=line_color)

# 合并两个轴的图例
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("月度销售额与利润率组合图", fontsize=16)
plt.tight_layout()
plt.savefig("combo_bar_line.png", dpi=150)
plt.close()
print("组合图已保存为 combo_bar_line.png")


if __name__ == "__main__":
draw_combo_chart()

代码讲解

  • ax1.bar() 在左轴画蓝色半透明柱子表示销售额,alpha=0.7 让柱子不要太抢戏,折线叠在上面更突出。
  • ax2 = ax1.twinx() 创建共享X轴的右轴,ax2.plot() 画红色折线表示利润率,marker="o" 在每个月数据点画圆点。
  • 两个轴的刻度颜色分别和柱子、折线对应,tick_params(labelcolor=...) 让读图时不会搞混哪根线对应哪个轴。
  • 左右轴的范围手动设置:左轴 0~360,右轴 0~0.4,这样柱子和折线不会挤在同一条水平线上,视觉层次清晰。
  • FuncFormatter 把右轴小数转成百分比格式,0.25 显示成 25%。
  • 柱顶和折线上都加了数值标签,读者不用对照轴就能读到精确数字。
  • 图例用 get_legend_handles_labels() 把两个轴的图例句柄合并,放左上角。

运行结果

当前目录生成 combo_bar_line.png,图中蓝色柱子是月度销售额(左轴),红色带圆点折线是利润率(右轴,百分比格式),柱顶和折线点上方都标注了具体数值。整体能看出销售额在波动上升,利润率也稳步走高。

注意事项

  • 组合图最容易犯的错是两个轴起点不从0开始,导致视觉对比失真。柱图必须从0起,折线可以从合理值起,但报告里要注明。
  • 柱子宽度 width=0.5 比较舒服,太宽会显得笨重,太窄会和折线混淆。
  • 右轴百分比范围根据实际数据调,如果利润率在10%~30%之间,set_ylim(0, 0.4) 合适;如果是个位数,改成 0~0.15
  • pyecharts也能做组合图,用 Bar().overlap(Line()),需要交互式版本时可以参考。

Python图表叠加柱状图折线图组合图:双轴混合图表

标签:

更新时间:2026-09-14 20:33:08

上一篇:Python根据Excel数据画趋势图:pandas读取matplotlib出图

下一篇:Python画柱状图并添加数据标签:柱顶数值标注方法