7

I am trying to make plots in Python using several different libraries (bokeh, seaborn and matlotlib), but keeping the same color scheme. I have chosen categorical pallete from bokeh with:
from bokeh.palettes import Category10 as palette
and then also used it in seaborn and matplotlib. My problem is that, although in matplotlib color seem to very similar to bokeh (as defined in the palette), seaborn shows somehow noticeable darker colors (i.e. less saturated or desaturated) than it should be. I am wondering if it is making some kind of dimming of any color scheme by default and if there is any way to avoid this. Below there is code for making the same barplot using different libraries
Using bokeh:

source = pd.DataFrame({'names': ['exp_1', 'exp_2'], 'data':[3, 5], 'color':palette[10][:2]})
p = bokeh.plotting.figure(x_range=['exp_1', 'exp_2'], y_range=(0,6), plot_height=500, title="test")
p.vbar(x='names', top='data', width=0.9,  legend_field="names", source=source, color='color')
p.xgrid.grid_line_color = None
p.legend.orientation = "horizontal"
p.legend.location = "top_center"
p.xaxis.major_label_text_font_size = '22pt'
p.yaxis.major_label_text_font_size = '22pt'
bokeh.io.show(p)

Using matplotlib:

# same palette both for seaborn and matplotlib (taken from bokeh palette)
sns_palette=sns.color_palette(palette[10]) 
fig, ax = plt.subplots()
plt.style.use('seaborn')
ax.set_xlabel('experiment', fontsize=20)
ax.tick_params(axis='both', which='major', labelsize=22)
ax.set_xticks([0, 1])
ax.set_xticklabels(['exp_1', 'exp_2'], fontsize=18)
ax.bar([0, 1], source['data'], align='center', color=sns_palette[:2])

and using bokeh:

plt.figure()
ax = sns.barplot(x="names", y="data", data=source, palette=sns_palette[0:2])
ax.set_xlabel('experiment', fontsize=20)
ax.tick_params(axis='both', which='major', labelsize=18)
plt.tight_layout()


bokeh barplot:
bokeh
matplotlib barplot
matplotlib
seaborn barplot:
seaborn

My Work
  • 2,143
  • 2
  • 19
  • 47
Antonio
  • 325
  • 1
  • 3
  • 9
  • @JohanC doesn't seem to be the reason: I checked, and using white background and also explicit alpha=1 doesn't change the color of barplots: `sns.set_style('white') ; kwargs = {'alpha':1}; ax = sns.barplot(x="names", y="data", data=source, palette=sns_palette[0:2], **kwargs)` – Antonio Apr 17 '20 at 14:20
  • 3
    [`barplot`](https://seaborn.pydata.org/generated/seaborn.barplot.html) has an option `saturation` which defaults to `0.75`. Setting it to `1` avoids all saturation: `sns.barplot(..., saturation=1)` (nonetheless, the documentation recommends some desaturation for aestetic reasons). – JohanC Apr 17 '20 at 15:41
  • @JohanC Yes, that works! Thanks! (Interestingly this 'desaturation' option by default seem to exist only in barplot and boxplot, but not in lineplot). If you post your comment as an answer I can accept it – Antonio Apr 17 '20 at 15:49
  • The linked documentation explains that the desaturation is recommended for large areas, so not for lines. – JohanC Apr 17 '20 at 15:51
  • Does this answer your question? [Seaborn chart colors are different than those specified by palette](https://stackoverflow.com/questions/44334874/seaborn-chart-colors-are-different-than-those-specified-by-palette) – My Work Feb 13 '22 at 11:14

1 Answers1

6

Seaborn barplot sets the saturation of the bar face colors to 0.75 by default. This can be overridden by adding saturation=1 to the barplot call.

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

source = pd.DataFrame({'names': ['exp_1', 'exp_2'], 'data':[3, 5]})
fig, ax = plt.subplots(1, 2)

# default saruration setting
sns.barplot(x="names", y="data", data=source, ax=ax[0])
ax[0].set_title('default saturation')

# additional parameter `saturation=1` passed to barplot
sns.barplot(x="names", y="data", data=source, saturation=1, ax=ax[1])
ax[1].set_title('saturation=1')

(This answer is straight form the comment by @JohanC, I'm just elevating it to an answer ... happy for ownership to go to that user.)

Stephen McAteer
  • 826
  • 1
  • 8
  • 12