ArnaudM22
ArnaudM22

Reputation: 11

Stacked bar plot in subplots using pandas .plot()

I created a hypothetical DataFrame containing 3 measurements for 20 experiments. Each experiment is associated with a Subject (3 possibilities).

import random
    
random.seed(42) #set seed
tuples = list(zip(*[list(range(20)),random.choices(['Jean','Marc','Paul'], k = 20)]))#index labels
index=pd.MultiIndex.from_tuples(tuples, names=['num_exp','Subject'])#index
test= pd.DataFrame(np.random.randint(0,100,size=(20, 3)),index=index,columns=['var1','var2','var3']) #DataFrame
test.head() #first lines

head

I succeeded in constructing stacked bar plots with the 3 measurements (each bar is an experiment) for each subject:

test.groupby('Subject').plot(kind='bar', stacked=True,legend=False) #plots

plot1 plot2 plot3

Now, I would like to put each plot (for each subject) in a subplot. If I use the "subplots" argument, it gives me the following :

test.groupby('Subject').plot(kind='bar', stacked=True,legend=False,subplots= True) #plot with subplot

plotsubplot1 plotsubplot2 plotsubplot3

It created a subplot for each measurment because they correspond to columns in my DataFrame. I don't know how I could do otherwise because I need them as columns to create stacked bars.

So here is my question : Is it possible to construct this kind of figure with stacked bar plots in subplots (ideally in an elegant way, without iterating) ?

Thanks in advance !

Upvotes: 0

Views: 473

Answers (1)

ArnaudM22
ArnaudM22

Reputation: 11

I solved my problem with a simple loop without using anything else than pandas .plot()

Pandas .plot() has an ax parameters for matplotlib axes object.

So, starting from the list of distinct subjects :

subj= list(dict.fromkeys(test.index.get_level_values('Subject')))

I define my subplots :

fig, axs = plt.subplots(1, len(subj))

Then, I have to iterate for each subplot :

 for a in range(len(subj)):
    test.loc[test.index.get_level_values('Subject') == subj[a]].unstack(level=1).plot(ax= axs[a], kind='bar', stacked=True,legend=False,xlabel='',fontsize=10) #Plot
    axs[a].set_title(subj[a],pad=0,fontsize=15) #title 
    axs[a].tick_params(axis='y', pad=0,size=1) #yticks

And it works well ! :finalresult

Upvotes: 1

Related Questions