Seaborn FacetGrid: while mapping a stripplot dodge not implemented

2.4k views Asked by At

Using Seaborn, I'm trying to generate a factorplot with each subplot showing a stripplot. In the stripplot, I'd like to control a few aspects of the markers.

Here is the first method I tried:

import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time",  hue="smoker")
g = g.map(sns.stripplot, 'day', "tip", edgecolor="black", 
          linewideth=1, dodge=True, jitter=True, size=10)

And produced the following output without dodge

output no dodge

While most of the keywords were implemented, the hue wasn't dodged.

I was successful with another approach:

kws = dict(s=10, linewidth=1, edgecolor="black")
tips = sns.load_dataset("tips")
sns.factorplot(x='day', y='tip', hue='smoker', col='time', data=tips,
          kind='strip',jitter=True, dodge=True, **kws, legend=False)

This gives the correct output: correct output

In this output, the hue is dodged.

My question is: why did g.map(sns.stripplot...) not dodge the hue?

1

There are 1 answers

1
ImportanceOfBeingErnest On BEST ANSWER

The hue parameter would need to be mapped to the sns.stripplot function via the g.map, instead of being set as hue to the Facetgrid.

import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time")
g = g.map(sns.stripplot, 'day', "tip", "smoker", edgecolor="black", 
          linewidth=1, dodge=True, jitter=True, size=10)

enter image description here

This is because map calls sns.stripplot individually for each value in the time column, and, if hue is specified for the complete Facetgrid, for each hue value, such that dodge would loose its meaning on each individual call.

I can agree that this behaviour is not very intuitive unless you look at the source code of map itself.

Note that the above solution causes a Warning:

lib\site-packages\seaborn\categorical.py:1166: FutureWarning:elementwise comparison failed;
   returning scalar instead, but in the future will perform elementwise comparison
  hue_mask = self.plot_hues[i] == hue_level

I honestly don't know what this is telling us; but it seems not to corrupt the solution for now.