You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Matplotlib的ax.bar将Pandas时序子图转为柱状图

解决Matplotlib多子图混合柱状图与折线图的问题

下面是符合需求的可运行代码,通过Matplotlib原生ax类方法实现第一个子图为柱状图、后两个为折线图的效果,同时保持子图风格统一、布局定制完整:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 构造示例数据集
np.random.seed(42)
categories = ['A', 'B', 'C', 'D', 'E']

# 数据集1的计数、均值、标准差
data1_count = np.random.randint(5, 20, size=len(categories))
data1_mean = np.random.uniform(10, 30, size=len(categories))
data1_std = np.random.uniform(1, 5, size=len(categories))

# 数据集2的计数、均值、标准差
data2_count = np.random.randint(5, 20, size=len(categories))
data2_mean = np.random.uniform(10, 30, size=len(categories))
data2_std = np.random.uniform(1, 5, size=len(categories))

# 创建3行1列的子图布局,共享x轴保证对齐
fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(8, 12), sharex=True)
x = np.arange(len(categories))  # 将分类转为数值化x轴位置
bar_width = 0.35  # 柱状图宽度,控制并排间距

# 第一个子图:计数柱状图(两个数据集并排)
ax_count = axes[0]
bar1 = ax_count.bar(x - bar_width/2, data1_count, bar_width, label='数据集1')
bar2 = ax_count.bar(x + bar_width/2, data2_count, bar_width, label='数据集2')

# 配置第一个子图的标签、标题、图例
ax_count.set_ylabel('计数')
ax_count.set_title('各分类计数对比')
ax_count.set_xticks(x)
ax_count.set_xticklabels(categories)
ax_count.legend()

# 给柱状图添加数值标签
for bars in [bar1, bar2]:
    for bar in bars:
        height = bar.get_height()
        ax_count.annotate(f'{height}',
                          xy=(bar.get_x() + bar.get_width()/2, height),
                          xytext=(0, 3),
                          textcoords="offset points",
                          ha='center', va='bottom')

# 第二个子图:均值折线图
ax_mean = axes[1]
ax_mean.plot(x, data1_mean, marker='o', linestyle='-', label='数据集1')
ax_mean.plot(x, data2_mean, marker='s', linestyle='-', label='数据集2')
ax_mean.set_ylabel('均值')
ax_mean.set_title('各分类均值对比')
ax_mean.legend()

# 第三个子图:标准差折线图
ax_std = axes[2]
ax_std.plot(x, data1_std, marker='^', linestyle='-', label='数据集1')
ax_std.plot(x, data2_std, marker='D', linestyle='-', label='数据集2')
ax_std.set_xlabel('分类')
ax_std.set_ylabel('标准差')
ax_std.set_title('各分类标准差对比')
ax_std.legend()

# 自动调整子图间距,避免元素重叠
plt.tight_layout()
plt.show()

常见错误方法分析

错误方法1:直接使用ax.bar未处理x轴位置

直接传入分类文本作为x轴参数,会导致两个数据集的柱子重叠,无法区分:

# 错误示例:柱子完全重叠
ax_count = axes[0]
ax_count.bar(categories, data1_count, label='数据集1')
ax_count.bar(categories, data2_count, label='数据集2')

原因:分类文本作为x轴时,无法自动分配并排位置,两个数据集的柱子会绘制在同一坐标点上。

错误方法2:使用Pandas的df.plot(kind='bar')

这种方式会破坏子图的定制设置(如共享x轴、布局参数),且风格与Matplotlib原生ax方法不一致:

# 错误示例:破坏子图定制与风格统一
df_count = pd.DataFrame({'数据集1': data1_count, '数据集2': data2_count}, index=categories)
df_count.plot(kind='bar', ax=axes[0])

原因:Pandas绘图会覆盖子图的默认配置,导致共享x轴失效,且标题、标签的样式与后两个折线图不协调。


内容的提问来源于stack exchange,提问作者Cebbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 15:49:57