如何增加分组条之间的间距

How to increase spacing between grouped bars

我有一个很大的数据集,并且有多个组,但是增加条形宽度也无济于事,因为组的大小不同。可以看到1112之间没有space,我需要每组单独绘制。

这是一个例子来说明我的问题。

import matplotlib.pyplot as plt

bar_width = 0.25

r = [8, 9, 10, 11, 12]
r1 = [(x) for x in r]
bars1 = [10,20, 40, 60, 80]

r = [1, 2, 8, 9, 10, 11, 12]
r2 = [(x + bar_width) for x in r]

bars2 = [5, 10,15, 20, 40, 60, 80]

bars3 = [ 12,23, 70, 94]
r = [4, 5,  11, 14]
r3 = [(x + bar_width * 2) for x in r]



bars4 = [ 60,120, 193]
r = [ 10,  11, 14]
r4 = [(x + bar_width * 3) for x in r]


r = [1, 2,3,4,5,6,7, 8, 9, 10, 11, 12]
r5 = [(x + bar_width * 4) for x in r]
bars5 = [3,5,23,14, 10, 20, 45,40,56, 60, 80,99]

plt.bar(r1, bars1, width=bar_width, align='center')
plt.bar(r2, bars2, width=bar_width, align='center')
plt.bar(r3, bars3, width=bar_width, align='center')
plt.bar(r4, bars4, width=bar_width, align='center')
plt.bar(r5, bars5, width=bar_width, align='center')
plt.legend(
    ('a', 'b', 'c', 'd', 'e'))

plt.show()

一个想法是增加 figsize:

fig, ax = plt.subplots(figsize=(15, 5))
bar_width = 0.1

ax.bar(r1, bars1, width=bar_width, align='center')
ax.bar(r2, bars2, width=bar_width, align='center')
ax.bar(r3, bars3, width=bar_width, align='center')
ax.bar(r4, bars4, width=bar_width, align='center')
ax.bar(r5, bars5, width=bar_width, align='center')
ax.legend(('a', 'b', 'c', 'd', 'e'))

根据您的应用,堆叠条形可能是一种解决方案,而不是彼此相邻的条形。

不用计算位置和宽度,pandas绘图会更容易。

这是一个例子:

import matplotlib.pyplot as plt
import pandas as pd

r1 = [8, 9, 10, 11, 12]
bars1 = [10, 20, 40, 60, 80]

r2 = [1, 2, 8, 9, 10, 11, 12]
bars2 = [5, 10, 15, 20, 40, 60, 80]

r3 = [4, 5, 11, 14]
bars3 = [12, 23, 70, 94]

r4 = [10, 11, 14]
bars4 = [60, 120, 193]

r5 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
bars5 = [3, 5, 23, 14, 10, 20, 45, 40, 56, 60, 80, 99]

rs = r1 + r2 + r3 + r4 + r5
heights = bars1 + bars2 + bars3 + bars4 + bars5
names = ['a'] * len(bars1) + ['b'] * len(bars2) + ['c'] * len(bars3) + ['d'] * len(bars4) + ['e'] * len(bars5)

df = pd.DataFrame({'r': rs,
                   'height': heights,
                   'name': names})
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(15, 4))
for ax in (ax1, ax2):
    df.pivot(index='r', columns='name', values='height').plot.bar(stacked=(ax == ax2), rot=0, ax=ax)
ax1.set_title('dodged bars')
ax2.set_title('stacked bars')
plt.tight_layout()
plt.show()

如果您想编写自定义代码,同样的数据框也可以提供帮助,例如,隐藏条省略空条:

fig, ax = plt.subplots()
colors = {'a': 'C0', 'b': 'C1', 'c': 'C2', 'd': 'C3', 'e': 'C44'}
tick_pos = []
tick_r = []
name_list = ['a', 'b', 'c', 'd', 'e']
pos = 0
for r in range(df['r'].min(), df['r'].max() + 1):
    start_pos = pos
    for name in name_list:
        row = df[(df['r'] == r) & (df['name'] == name)]
        if len(row) != 0:
            ax.bar(pos, row['height'], color=colors[name], width=1)
            pos += 1
    end_pos = pos
    if start_pos != end_pos:
        tick_pos.append((start_pos + end_pos - 1) / 2)
        tick_r.append(r)
        pos += 0.3 # this is the gap between the groups
ax.set_xticks(tick_pos)
ax.set_xticklabels(tick_r)
ax.legend(handles=[plt.Rectangle((0, 0), 0, 0, color=colors[n]) for n in name_list], labels=name_list)
ax.margins(x=0.01)
plt.tight_layout()
plt.show()