如何用fig、ax绘制多组柱状图?DataFrame可视化问题求助
问题解决与参数解释
一、先修正你的代码错误
你之前的代码有两个关键问题:
- subplot用法错误:创建多子图要使用
plt.subplots()(带s),而非plt.subplot();同时figsize必须写成figsize=(10, 5)(带括号),正确写法是:
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
这里axes是包含两个子图轴对象的数组,后续用axes[0]和axes[1]分别操作两个子图。
- bar函数参数错误:
ax.bar()必须指定x轴位置/标签和柱子高度(height),你直接传df.actual_price是不完整的。比如要展示某列的min和max,x轴可以设为['最小值', '最大值'],height对应这两个具体数值。
二、具体实现代码
假设你的DataFrame是通过groupby聚合后得到的,已经包含actual_price和discount_price的min、max值,分两种情况处理:
情况1:普通列结构(列名如actual_min, actual_max)
import matplotlib.pyplot as plt import pandas as pd # 示例聚合后DataFrame data = { 'group': ['A', 'B', 'C'], 'actual_min': [100, 150, 120], 'actual_max': [200, 250, 180], 'discount_min': [80, 120, 90], 'discount_max': [180, 220, 160] } df = pd.DataFrame(data).set_index('group') # 创建1行2列子图 fig, axes = plt.subplots(1, 2, figsize=(12, 6)) x_labels = ['最小值', '最大值'] bar_width = 0.2 # 第一个子图:actual_price极值 for idx, group in enumerate(df.index): heights = [df.loc[group, 'actual_min'], df.loc[group, 'actual_max']] axes[0].bar([i + bar_width*idx for i in range(len(x_labels))], heights, width=bar_width, label=group) axes[0].set_title('Actual Price 极值') axes[0].set_xticks([i + bar_width for i in range(len(x_labels))]) axes[0].set_xticklabels(x_labels) axes[0].legend() # 第二个子图:discount_price极值 for idx, group in enumerate(df.index): heights = [df.loc[group, 'discount_min'], df.loc[group, 'discount_max']] axes[1].bar([i + bar_width*idx for i in range(len(x_labels))], heights, width=bar_width, label=group) axes[1].set_title('Discount Price 极值') axes[1].set_xticks([i + bar_width for i in range(len(x_labels))]) axes[1].set_xticklabels(x_labels) axes[1].legend() plt.tight_layout() plt.show()
情况2:多层列结构(groupby.agg生成的MultiIndex列)
如果你的聚合代码是这样的:
df = df.groupby('group').agg({ 'actual_price': ['min', 'max'], 'discount_price': ['min', 'max'] })
先扁平化列名再画图:
# 扁平化列名,把('actual_price', 'min')转为'actual_price_min' df.columns = ['_'.join(col) for col in df.columns] # 后续画图代码和情况1一致,只需将列名替换为'actual_price_min'、'actual_price_max'等
三、height参数解释
matplotlib.pyplot.bar()中的height参数就是柱子的高度,对应你要展示的具体数值——比如你要画actual_price的最小值,height就传这个最小值;要画最大值,就传最大值的数值。
四、是否需要调整DataFrame结构?
如果你的DataFrame已经包含actual_price和discount_price的min、max值(无论普通列还是多层列),只需做简单的列名处理(比如扁平化多层列),不需要大幅调整结构。如果还没计算极值,先执行聚合:
# 先聚合得到各分组的极值 df_agg = df.groupby('你的分组列').agg({ 'actual_price': ['min', 'max'], 'discount_price': ['min', 'max'] })
内容的提问来源于stack exchange,提问作者ShazelP
相关产品推荐
相关产品推荐

