Stacked Bar Plot From Loop Not Adding Different Components Of Bars
Solution 1:
Problem number 1, if I understand you correctly is that the heigth of the bars is not 1 (i.e. the sum of all the fractions). Your code
p1 = plt.bar(ind, plot_df.iloc[:,0], width)
p2 = plt.bar(ind, plot_df.iloc[:,1], width)
...
creates four bar plots, allstartingfrom0 (on the y-axis). What we want is for p2
to start on top of p1
, p3
to start on top of p2
and so on. To do this we can specify the bottom
argument (which defaults to 0) in plt.bar
. So,
p1 = plt.bar(ind, plot_df.iloc[:,0], width)
p2 = plt.bar(ind, plot_df.iloc[:,1], width, bottom=plot_df.iloc[:,0])
...
for p3
we want bottom
to start on the sum of plot_df.iloc[:,0]
and plot_df.iloc[:,1]
. We can do this either explicitly or using np.sum
like so np.sum(plot_df.iloc[:,:i]
. The latter of course has the advantage that we can sum over an arbitrary number of columns (like you want in your function).
As for your function... I gave it a shot. You probably have to perfect it yourself
def bar_plot(plot_df):
width = 0.35 # width of bars
p_s = []
p_s.append(plt.bar(ind, plot_df.iloc[:,0], width))
for i in range(1,len(plot_df.columns)):
p_s.append(plt.bar(ind, plot_df.iloc[:,i], width,
bottom=np.sum(plot_df.iloc[:,:i], axis=1)))
plt.ylabel('[%]')
plt.title('Responses by country')
x_ticks_names = tuple([item for item in plot_df.index])
plt.xticks(ind, x_ticks_names)
plt.yticks(np.arange(0, 1.1, 0.1)) # ticks from, to, steps
plt.legend(p_s, plot_df.columns)
plt.show()
Solution 2:
The function provided by @mortysporty (all credit accordingly) can be tweaked to complete the desired task by just adding a few lines in the beginning that are referenced later:
import matplotlib.pyplot as plt
import numpy as np
def newest_bar_plot(plot_df):
N = len(plot_df) # number of groups
ind = np.arange(N) # x locations for the groups
width = 0.35 # width of bars
p_s = []
p_s.append(plt.bar(ind, plot_df.iloc[:,0], width))
for i in range(1,len(plot_df.columns)):
p_s.append(plt.bar(ind, plot_df.iloc[:,i], width,
bottom=np.sum(plot_df.iloc[:,:i], axis=1)))
plt.ylabel('[%]')
plt.title('Responses by country')
x_ticks_names = tuple([item for item in plot_df.index])
plt.xticks(ind, x_ticks_names)
plt.yticks(np.arange(0, 1.1, 0.1)) # ticks from, to, steps
plt.legend(p_s, plot_df.columns)
plt.show()
Post a Comment for "Stacked Bar Plot From Loop Not Adding Different Components Of Bars"