Search code examples
matplotlibseabornboxplotcolorbar

How to add a colorbar to seaborn boxplot?


I made a boxplot using seaborn.boxplot(). The x axis ranges from -0.95 to 0.95. Because the values on the x axis are important, I would like to create a colorbar that matches these values. Using plt.colorbar(), I got the following error message 'RuntimeError: No mappable was found to use for colorbar creation. First define a mappable such as an image (with imshow) or a contour set (with contourf)'. Searching for solutions on stackoverflow, I found matplotlib colorbar not working (due to garbage collection?), Matplotlib: Creating Colorbar. I gave them a try but I'm generating more errors, suggesting that I'm not doing the right thing. Therefore, I really would appreciate if someone could help me out and teach me how to do it properly. Thank you in advance for your time and sharing knowledge.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.DataFrame({'x_val':[
-0.95,
-0.95,
-0.95,
-0.95,
-0.9,
-0.9,
-0.9,
-0.9,
-0.85,
-0.85,
-0.85,
-0.85,
-0.8,
-0.8,
-0.8,
-0.8,
-0.75,
-0.75,
-0.75,
-0.75,
-0.7,
-0.7,
-0.7,
-0.7,
-0.65,
-0.65,
-0.65,
-0.65,
-0.6,
-0.6,
-0.6,
-0.6,
-0.55,
-0.55,
-0.55,
-0.55,
-0.5,
-0.5,
-0.5,
-0.5,
-0.45,
-0.45,
-0.45,
-0.45,
-0.4,
-0.4,
-0.4,
-0.4,
-0.35,
-0.35,
-0.35,
-0.35,
-0.3,
-0.3,
-0.25,
-0.25,
-0.25,
-0.2,
-0.2,
-0.2,
-0.15,
-0.15,
-0.15,
-0.1,
-0.1,
-0.1,
-0.1,
-0.05,
-0.05,
-0.05,
0.05,
0.05,
0.1,
0.1,
0.1,
0.15,
0.15,
0.2,
0.2,
0.2,
0.25,
0.25,
0.25,
0.3,
0.3,
0.3,
0.3,
0.35,
0.35,
0.35,
0.35,
0.4,
0.4,
0.4,
0.45,
0.45,
0.45,
0.45,
0.5,
0.5,
0.5,
0.5,
0.55,
0.55,
0.55,
0.55,
0.6,
0.6,
0.6,
0.6,
0.65,
0.65,
0.65,
0.65,
0.7,
0.7,
0.7,
0.7,
0.75,
0.75,
0.75,
0.75,
0.8,
0.8,
0.8,
0.8,
0.85,
0.85,
0.85,
0.85,
0.9,
0.9,
0.9,
0.9,
0.95,
0.95,
0.95,
0.95],
'y_val':[
0.97,
0.98,
0.96,
0.97,
0.94,
0.94,
0.96,
0.96,
0.93,
0.92,
0.92,
0.94,
0.92,
0.9,
0.93,
0.9,
0.91,
0.91,
0.88,
0.89,
0.86,
0.91,
0.87,
0.9,
0.88,
0.89,
0.85,
0.84,
0.86,
0.87,
0.82,
0.82,
0.84,
0.82,
0.8,
0.88,
0.77,
0.76,
0.84,
0.86,
0.83,
0.77,
0.82,
0.76,
0.81,
0.75,
0.8,
0.76,
0.81,
0.73,
0.72,
0.74,
0.73,
0.79,
0.7,
0.79,
0.73,
0.69,
0.7,
0.75,
0.7,
0.69,
0.74,
0.69,
0.69,
0.74,
0.68,
0.75,
0.69,
0.71,
0.73,
0.68,
0.7,
0.71,
0.76,
0.67,
0.76,
0.79,
0.75,
0.71,
0.7,
0.8,
0.74,
0.76,
0.73,
0.8,
0.71,
0.72,
0.79,
0.81,
0.71,
0.82,
0.74,
0.79,
0.8,
0.74,
0.77,
0.82,
0.8,
0.76,
0.84,
0.78,
0.83,
0.83,
0.85,
0.77,
0.8,
0.84,
0.88,
0.85,
0.81,
0.88,
0.85,
0.87,
0.87,
0.9,
0.84,
0.88,
0.91,
0.9,
0.86,
0.88,
0.92,
0.89,
0.91,
0.91,
0.92,
0.94,
0.92,
0.95,
0.96,
0.94,
0.95,
0.94,
0.97,
0.96,
0.97,
0.96]})

#plot
fig,ax = plt.subplots(figsize=(9,6))  
sns.boxplot(x='x_val',y='y_val',data=df,ax=ax,palette='YlGnBu')
plt.xticks(rotation=90)
#plt.colorbar()
plt.show()
plt.close()

enter image description here


Solution

  • You can add a custom colorbar with cm.ScalarMappable

    from matplotlib import cm, colors
    
    norm = colors.Normalize(df.x_val.min(), df.x_val.max())
    plt.xticks(rotation=90)
    fig.colorbar(cm.ScalarMappable(norm=norm,cmap='YlGnBu'), ax=ax)
    

    Output:

    enter image description here