pythonpandasmatplotlibgrouped-bar-chart

Bar Chart with multiple labels


The following code only shows the main category ['one', 'two', 'three', 'four', 'five', 'six'] as the x axis labels. Is there a way show subcategory ['A', 'B', 'C', 'D'] as secondary x axis labels? enter image description here

df = pd.DataFrame(np.random.rand(6, 4),
                 index=['one', 'two', 'three', 'four', 'five', 'six'],
                 columns=pd.Index(['A', 'B', 'C', 'D'], 
                 name='Genus')).round(2)


df.plot(kind='bar',figsize=(10,4))

Solution

  • Here a possible solution (I had quite a lot of fun!):

    df = pd.DataFrame(np.random.rand(6, 4),
                     index=['one', 'two', 'three', 'four', 'five', 'six'],
                     columns=pd.Index(['A', 'B', 'C', 'D'],
                     name='Genus')).round(2)
    
    ax = df.plot(kind='bar',figsize=(10,4), rot = 0)
    
    # "Activate" minor ticks
    ax.minorticks_on()
    
    # Get location of the center of each rectangle
    rects_locs = map(lambda x: x.get_x() +x.get_width()/2., ax.patches)
    # Set minor ticks there
    ax.set_xticks(rects_locs, minor = True)
    
    
    # Labels for the rectangles
    new_ticks = reduce(lambda x, y: x + y, map(lambda x: [x] * df.shape[0], df.columns.tolist()))
    # Set the labels
    from matplotlib import ticker
    ax.xaxis.set_minor_formatter(ticker.FixedFormatter(new_ticks))  #add the custom ticks
    
    # Move the category label further from x-axis
    ax.tick_params(axis='x', which='major', pad=15)
    
    # Remove minor ticks where not necessary
    ax.tick_params(axis='x',which='both', top='off')
    ax.tick_params(axis='y',which='both', left='off', right = 'off')
    

    Here's what I get:

    enter image description here