Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seaborn stripplot set edgecolor based on hue/palette

I'm trying to create a figure like this one from the seaborn documentation but with the edgecolor of the stripplot determined by the hue. This is my attempt:

import seaborn as sns
df = sns.load_dataset("tips")
ax = sns.stripplot(x="sex", y="tip", hue="day", data=df, jitter=True,
                   edgecolor=sns.color_palette("hls", 4),
                   facecolors="none", split=False, alpha=0.7)

enter image description here

But the color palettes for male and female appear to be different. How do I use the same color palette for both categories?

I'm using seaborn 0.6.dev

like image 223
bnelsj Avatar asked Aug 31 '25 06:08

bnelsj


1 Answers

The edgecolor parameter is just passed straight through to plt.scatter. Currently you're giving it a list of 4 colors. I'm not exactly sure what I would expect it to do in that case (and I am not exactly sure why you end up with what you're seeing here), but I would not have expected it to "work".

The ideal way to have this work would be to have a "hollow circle" marker glyph that colors the edges based on the color (or facecolor) attribute rather than the edges. While it would be nice to have this as an option in core matplotlib, there are some inconsistencies that might make that unworkable. However, it's possible to hack together a custom glyph that will do the trick:

import numpy as np
import matplotlib as mpl
import seaborn as sns

sns.set_style("whitegrid")
df = sns.load_dataset("tips")

pnts = np.linspace(0, np.pi * 2, 24)
circ = np.c_[np.sin(pts) / 2, -np.cos(pts) / 2]
vert = np.r_[circ, circ[::-1] * .7]

open_circle = mpl.path.Path(vert)

sns.stripplot(x="sex", y="tip", hue="day", data=df,
              jitter=True, split=False,
              palette="hls", marker=open_circle, linewidth=0)

enter image description here

FWIW I should also mention that it's important to be careful when using this approach because the colors become much harder to distinguish. The hls palette exacerbates the problem as the lime green and cyan middle colors end up quite similar. I can imagine situations where this would work nicely, though, for instance a hue variable with two levels represented by gray and a bright color, where you want to emphasize the latter.

like image 107
mwaskom Avatar answered Sep 03 '25 18:09

mwaskom