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,20,40,60,80,100], rotation = 0,fontsize=12)
    axe.set_xlabel('Health zone at risk',fontsize=16)
    axe.set_ylabel('Percentage of 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,100.000000,0.000000],[42.546890,46.001974,5.429418],[55.052697,12.709237,1.239926],[54.716981,3.773585,1.886792],[14.945919,13.765978,0.786627],[25.835037,1.567825,0.000000],[9.022556,0.751880,2.255639],[2.158979,0.000000,0.000000],[1.793722,0.000000,0.000000]])

v = np.array([[100.000000,0.000000,0.000000],[60.612043,7.798618,0.000000],[28.580285,1.673900,0.061996],[11.792453,1.415094,0.471698],[15.732547,1.671583,0.000000],[4.976142,0.000000,0.000000],[0.751880,1.503759,0.751880],[0.098135,0.000000,0.000000],[0.000000,0.000000,0.000000]])
vr = np.array([[100.000000,0.000000,0.000000],[60.217177,14.906219,0.000000],[36.205828,3.099814,0.061996],[33.018868,1.415094,0.471698],[15.240905,3.736480,0.000000],[8.997955,0.000000,0.000000],[2.255639,1.503759,0.751880],[0.220805,0.000000,0.000000],[0.000000,0.000000,0.000000]])
index = ['Bumbu','Iboko','Bikoro','Mbandaka','Ntondo','Ingende','Bolonge','Inongo','Penzwa']
columns = ['0.001< Pr $\leq$ 0.01','0.01 < Pr $\leq$ 0.05',' Pr > 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]])