Search code examples
pythonmatplotlibbar-chartsubplot

Trying to construct a 2 panel subplot of barplots, however the bars seem to have shifted in second panel


I am attempting to create a 2-panel subplot of RMSE and correlation values, with groupings of bars (such that each combination has 4 bars). It appears, however, that in the second panel, the placement of the bar groupings have become offset, and the order of the xlabels has become jumbled.

Any idea what might be happening here?

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.cbook as cbook
import numpy as np
import scipy
import pandas as pd
from itertools import combinations


### Create Plot ###
matplotlib.rc('xtick', labelsize=22) 
matplotlib.rc('ytick', labelsize=22)
    
combos = {'1 Product', '2 Product', '3 Product','4 Product', '5 Product', '6 Product','7 Product'}
    
top30_rmse = {'RMSE Cold Season': [4.91726910421414,3.92792247654507,3.53717233977146,3.32461948965479,3.19029758875898,3.0975153495569,3.02950308430467],
             'RMSE Warm Season': [4.436715943,3.767955663,3.516888357,3.384377437,3.302319607,3.246462314,3.205968468]}

top30_corr = {'Correlation Cold Season': [0.639808613,0.71965916,0.75785035,0.780044305,0.794336664,0.80422278,0.811432104],
            'Correlation Warm Season': [0.888086922,0.936554339,0.952068621,0.958842973,0.962550154,0.964870985,0.966455676]}

depth_rmse = {'RMSE Cold Season': [3.564576325,3.000595232,2.787357328,2.6743701,2.60422583,2.556393944,2.521672889],
               'RMSE Warm Season': [4.706464351,4.416909958,4.316077216,4.264766936,4.233682287,4.212831767,4.197875134]}

depth_corr = {'Correlation Cold Season': [0.822695625,0.855445131,0.868612894,0.875592404,0.87985752,0.882709683,0.884740798],
            'Correlation Warm Season': [0.858527248,0.880016071,0.887233404,0.890810139,0.892940312,0.894352646,0.89535723]}

x = np.arange(1,8,1)

width = 0.1
multiplier = 0
    
fig = plt.subplots(nrows=2,ncols=1,sharex='all',figsize=(20,20))

## Top-30cm ##
#RMSE#
ax1 = plt.subplot(211)
for stat, group in top30_rmse.items():
    offset = width * multiplier
    rects = ax1.bar(x + offset, group, width, label=stat)
    multiplier += 1
ax1.set_xticks(x + width, combos)
ax1.set_ylim(0,10)
                       
#CORR#
ax2 = ax1.twinx()
for stat, group in top30_corr.items():
    offset = width * multiplier
    rects = ax2.bar(x + offset, group, width,  hatch='x', label=stat)
    multiplier += 1    

ax2.set_ylim(0.5,1)
                       
## Depth ##
#RMSE#
ax3 = plt.subplot(212)
for stat, group in depth_rmse.items():
    offset = width * multiplier
    rects = ax3.bar(x + offset, group, width, label=stat)
    multiplier += 1
ax3.set_xticks(x + width, combos)
ax3.set_ylim(0,10)

#CORR#
ax4 = ax3.twinx()
for stat, group in depth_corr.items():
    offset = width * multiplier
    rects = ax4.bar(x + offset, group, width,  hatch='x', label=stat)
    multiplier += 1                        

ax4.set_ylim(0.5,1)          

plt.tight_layout()
plt.show()

Current Figure


Solution

  • Updating with a more complete answer to both of your questions:

    1. Your bar offset issue: Looks like it has to do with your multiplier variable since you are modifying it and then reusing it. Just reset it with multiplier=0 right above the line ax3 = plt.subplot(212) to fix the issue

    2. Change combos to a list instead of a set to fix that issue.