简体   繁体   中英

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

I have a pandas dataframe df which looks as follows:

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() is given for reference:

{'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}}

I want to plot a waterfall chart using this data. For this, I plotted a stacked bar plot using the code below and using column Base as bottom.

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")

This returned me the following plot: 在此处输入图像描述

The default width of the bar plot ie 0.8 as per this documentation makes the bar look too narrow. I can increase the width manually while plotting. For example, when I use width = 20 in the above code as follows

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

I get wider bars as shown: 在此处输入图像描述

However, now the position of ticks and labels is distorted. How can I set the width of the bars such that the bars look wide, the space between bars is none or small, and the ticks and labels in the x-axis are still in the same position as bars?

The problem is that each point in the x axis is allocating space for 10 different bars. So any size you put, you will always have 9 empty spaces. Instead, you should restructure the df before plotting:

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()

Result:

在此处输入图像描述

Notice that the patches indices also changed, since we don't have all the empty ones anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM