在 Python 中使用 pandas 和 matplotlib 绘制条形图时,如何删除条形之间的 space?

How can I remove space between bars while plotting bar plot using pandas and matplotlib in Python?

我有一个 pandas 数据框 df 如下所示:

Base    Current level   New fan New refrigerator    Unplug unused appliances    Run washing machine with full load  Fix leakages    After three months  Install smart thermostat    Replace light bulbs with LED lights Replace desktop with laptop After six months
0   0   150.0   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1   150 0.0 10.0    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2   160 0.0 0.0 15.0    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3   160 0.0 0.0 0.0 15.0    0.0 0.0 0.0 0.0 0.0 0.0 0.0
4   145 0.0 0.0 0.0 0.0 15.0    0.0 0.0 0.0 0.0 0.0 0.0
5   140 0.0 0.0 0.0 0.0 0.0 5.0 0.0 0.0 0.0 0.0 0.0
6   0   0.0 0.0 0.0 0.0 0.0 0.0 140.0   0.0 0.0 0.0 0.0
7   115 0.0 0.0 0.0 0.0 0.0 0.0 0.0 25.0    0.0 0.0 0.0
8   105 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 10.0    0.0 0.0
9   95  0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 10.0    0.0
10  0   0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 95.0

df.to_dict()给出供参考:

{'Base': {0: 0,
  1: 150,
  2: 160,
  3: 160,
  4: 145,
  5: 140,
  6: 0,
  7: 115,
  8: 105,
  9: 95,
  10: 0},
 'Current level': {0: 150.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'New fan': {0: 0.0,
  1: 10.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'New refrigerator': {0: 0.0,
  1: 0.0,
  2: 15.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'Unplug unused appliances': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 15.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'Run washing machine with full load': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 15.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'Fix leakages': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 5.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'After three months': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 140.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'Install smart thermostat': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 25.0,
  8: 0.0,
  9: 0.0,
  10: 0.0},
 'Replace light bulbs with LED lights': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 10.0,
  9: 0.0,
  10: 0.0},
 'Replace desktop with laptop': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 10.0,
  10: 0.0},
 'After six months': {0: 0.0,
  1: 0.0,
  2: 0.0,
  3: 0.0,
  4: 0.0,
  5: 0.0,
  6: 0.0,
  7: 0.0,
  8: 0.0,
  9: 0.0,
  10: 95.0}}

我想使用这些数据绘制瀑布图。为此,我使用下面的代码绘制了一个堆积条形图,并使用 Base 列作为底部。

colors = ["royalblue","green","green","red","red","red","royalblue",
        "red","red","red","royalblue"]

fig = df.loc[:,"Current level":].plot(kind = "bar",
                               bottom = df["Base"],
                     
                               color = colors)


selected_patches = fig.patches[0], fig.patches[20], fig.patches[40]


plt.legend(selected_patches, ["Base", "Rise", "Fall"], loc = "upper right")

plt.xticks(ticks = np.arange(0, len(df)), labels = df.columns[1:], rotation = 90)

plt.title("My electricity saving plan")

plt.ylabel("kWh consumption")

这让我返回了以下情节:

条形图的默认宽度即 0.8 as per this documentation 使条形看起来太窄。 我可以在绘图时手动增加宽度。比如我在上面的代码中使用width = 20时如下

fig = df.loc[:,"Current level":].plot(kind = "bar",
                               bottom = df["Base"],
                                      width = 20,
                               color = colors)

我得到更宽的条,如图所示:

但是,现在刻度和标签的位置是扭曲的。如何设置条形的宽度,使条形看起来很宽,条形之间的 space 为 none 或较小,并且 x-axis 中的刻度和标签仍然相同柱状图的位置?

问题是 x 轴上的每个点都为 10 个不同的柱分配 space。所以无论你放什么尺寸,你总会有 9 个空的 spaces。相反,您应该在绘图之前重组 df:

import matplotlib.pyplot as plt

colors = ["royalblue","green","green","red","red","red","royalblue",
        "red","red","red","royalblue"]

fig = df.loc[:,"Current level":].T.max(axis=1).plot(kind='bar', bottom=df['Base'], width=1, color=colors)

selected_patches = fig.patches[0], fig.patches[2], fig.patches[4]
plt.legend(selected_patches, ["Base", "Rise", "Fall"], loc = "upper right")

plt.xticks(ticks = np.arange(0, len(df)), labels = df.columns[1:], rotation = 90)

plt.title("My electricity saving plan")

plt.ylabel("kWh consumption")
plt.show()

结果:

请注意,补丁索引也发生了变化,因为我们不再拥有所有的空索引。