如何调整基于14行7列Dataframe的分组柱状图组间间距与柱宽?
调整分组柱状图的柱子宽度与组间间距方案
嗨,刚好之前也折腾过类似的分组柱状图需求,给你分享一下用Matplotlib实现的具体方法,完美解决加宽组内柱子、增大组间间距且不重叠的问题!
核心思路
要实现你的需求,关键是手动控制每个柱子的位置和宽度:
- 给单个柱子设置合适的宽度(调大这个值就能加宽柱子)
- 给不同月份的组之间预留额外的间距,避免组与组挤在一起
完整代码示例
先模拟你的14行7列DataFrame,然后一步步绘图:
import matplotlib.pyplot as plt import numpy as np import pandas as pd # 模拟你的数据结构:14个月份,7个分组 months = [f"2023-{i:02d}" for i in range(1,15)] groups = [f"Group {j}" for j in range(1,8)] df = pd.DataFrame(np.random.randint(10, 50, size=(14,7)), index=months, columns=groups) # 开始绘图 fig, ax = plt.subplots(figsize=(12, 6)) n_groups = len(groups) bar_width = 0.12 # 单个柱子的宽度,数值越大柱子越宽,注意别超过组内空间导致重叠 group_gap = 0.2 # 组与组之间的间距,数值越大组间空隙越大 # 计算每个月份组的基准位置(控制组间间距) base_pos = np.arange(len(months)) * (bar_width * n_groups + group_gap) # 遍历每个分组绘制柱子 for idx, group_name in enumerate(groups): # 计算当前分组柱子的位置 bar_pos = base_pos + idx * bar_width ax.bar(bar_pos, df[group_name], width=bar_width, label=group_name) # 调整X轴刻度,让刻度标签对齐每个月份组的中间 ax.set_xticks(base_pos + bar_width * (n_groups - 1) / 2) ax.set_xticklabels(months, rotation=45, ha='right') # 旋转标签避免重叠 # 添加图表元素 ax.set_xlabel('月份') ax.set_ylabel('数据值') ax.set_title('各分组月度数据对比') ax.legend(loc='upper right') plt.tight_layout() # 自动调整布局,避免标签被截断 plt.show()
参数调整说明
bar_width:直接控制单个柱子的宽度,你可以慢慢增大这个值,直到柱子接近但不重叠(比如从0.1开始往上调)group_gap:控制不同月份组之间的空隙,数值越大,组与组之间的间隔越宽figsize:如果月份标签还是挤,可以把第一个参数(宽度)调大,比如改成(14,6)
补充:用Seaborn的简化方案
如果你习惯用Seaborn,可以先把DataFrame转成长格式,再通过width参数调整柱子宽度,组间间距可以通过调整X轴的刻度间隔实现:
import seaborn as sns # 转成长格式 df_long = df.reset_index().melt(id_vars='index', var_name='Group', value_name='Value') df_long.rename(columns={'index':'Month'}, inplace=True) fig, ax = plt.subplots(figsize=(12,6)) sns.barplot(data=df_long, x='Month', y='Value', hue='Group', width=0.8, ax=ax) # 调整X轴刻度间距(可选) ax.set_xticks(np.arange(len(months)) * 1.1) # 增大刻度间距间接增大组间间距 ax.set_xticklabels(months, rotation=45, ha='right') plt.tight_layout() plt.show()
不过Seaborn的组间间距控制没有Matplotlib那么灵活,更推荐第一种手动控制位置的方法。
内容的提问来源于stack exchange,提问作者TH15
相关产品推荐
相关产品推荐

