简体   繁体   中英

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 !

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

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