SharedHatched bars.ipynbOpen in CoCalc
import pandas as pd
import matplotlib.cm as cm
import numpy as np
import matplotlib.pyplot as plt

def plot_clustered_stacked(dfall, labels=None, title=None,  H=".xO", **kwargs):
"""Given a list of dataframes, with identical columns and index, create a clustered stacked bar plot.
labels is a list of the names of the dataframe, used for the legend
title is a string for the title of the plot
H is the hatch used for identification of the different dataframe"""

n_df = len(dfall)
n_col = len(dfall[0].columns)
n_ind = len(dfall[0].index)
#axe = plt.subplot(111)
fig, axe = plt.subplots(figsize=(10,5))
j = 0
colors = ['k','b','purple']
for df in dfall : # for each data frame
axe = df.plot(kind="bar",
linewidth=1,
stacked=True,
ax=axe,
color='w',
edgecolor=colors[j],
legend=False,
grid=False,
**kwargs)  # make bar plots
j+=1

h,l = axe.get_legend_handles_labels() # get the handles we want to modify
for i in range(0, n_df * n_col, n_col): # len(h) = n_col * n_df
for j, pa in enumerate(h[i:i+n_col]):
for rect in pa.patches: # for each index
rect.set_x(rect.get_x() + 1 / float(n_df + 1) * i / float(n_col))
rect.set_hatch(H[j]*2)# * int(j)) #edited part
rect.set_width(1 / float(n_df + 1))

axe.set_xticks((np.arange(0, 2 * n_ind, 2) + 1 / float(n_df + 1)) / 2.)
axe.set_xticklabels(df.index, rotation = 0,fontsize=12)
axe.set_yticklabels([0,0.2,0.4,0.6,0.8,1.0], rotation = 0,fontsize=12)
axe.set_xlabel('Health zone at risk',fontsize=16)
axe.set_ylabel('Realtive area at risk',fontsize=16)
#axe.set_title(title)

n=[]
for i in range(n_df):
n.append(axe.bar(0, 0, color=colors[i]))#, hatch=H[i]))

l1 = axe.legend(h[:n_col], l[:n_col], loc=[1.01, 0.5],frameon=False,title='Probability of infection',fontsize=12)
if labels is not None:
l2 = plt.legend(n, labels, loc=[1.01, 0.1],frameon= False,title='Vaccine Scenarios',fontsize=12)

axe.spines['top'].set_visible(False)
axe.spines['right'].set_visible(False)
axe.spines['left'].set_linewidth(2)
axe.spines['bottom'].set_linewidth(2)

return axe

# Data
nv = np.array([[0.000000,1.000000,0.000000],[0.425469,0.460020,0.054294],[0.550527,0.127092,0.012399],[0.547170,0.037736,0.018868],[0.149459,0.137660,0.007866],[0.258350,0.015678,0.000000],[0.090226,0.007519,0.022556],[0.021590,0.000000,0.000000],[0.017937,0.000000,0.000000]])

v = np.array([[1.000000,0.000000,0.000000],[0.608095,0.090819,0.000000],[0.301922,0.017979,0.000620],[0.141509,0.014151,0.004717],[0.153392,0.021632,0.000000],[0.059305,0.000000,0.000000],[0.007519,0.015038,0.007519],[0.001227,0.000000,0.000000],[0.000000,0.000000,0.000000]])
vr = np.array([[1.000000,0.000000,0.000000],[0.607108,0.168806,0.000000],[0.378177,0.034718,0.000620],[0.363208,0.018868,0.004717],[0.144543,0.045231,0.000000],[0.101568,0.000000,0.000000],[0.022556,0.015038,0.007519],[0.002453,0.000000,0.000000],[0.000000,0.000000,0.000000]])
index = ['Bumbu','Iboko','Bikoro','Mbandaka','Ntondo','Ingende','Bolonge','Inongo','Penzwa']
columns = ['0.001< P $\leq$ 0.01','0.01 < P $\leq$ 0.05',' P > 0.05']
dfnv = pd.DataFrame(nv,index=index, columns=columns)
dfv = pd.DataFrame(v,index=index, columns=columns)
dfvr = pd.DataFrame(vr,index=index, columns=columns)

plot_clustered_stacked([dfnv, dfv, dfvr],["No vaccination", "Vaccination", "Vaccination (48% refusal)"])

plt.savefig('hatched_fig2.png', bbox_inches="tight",dpi=600)  # Save as pdf later


import numpy as np
A =  np.array([[0.1829,0.0816, 0],[0.0902,    0.0226,  0.0075]])
A

array([[0.1829, 0.0816, 0. ], [0.0902, 0.0226, 0.0075]])