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)

    # Add invisible data to add another legend
    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.add_artist(l1)
    
    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]])