seaborn icon indicating copy to clipboard operation
seaborn copied to clipboard

Feature request: scatterplot, allow facecolor="none" and map the hue variable to edgecolor

Open asarmy opened this issue 3 years ago • 1 comments

It would be nice to have a simple way to specify hollow markers in seaborn.scatterplot(). One could map the hue variable to edgecolor by default and add a facecolor parameter.

Currently, adding a facecolor parameter has no effect (probably because hue overrides?). Adding edgecolor works only when "a valid single color nor a color sequence consisting of single character color" is specified.

I also tried circumventing this by changing the default settings as suggested in issue #1751 (using something like with sns.plotting_context(rc={"markerfacecolor": None}): ..., but again it has no effect probably because hue overrides.

asarmy avatar Feb 28 '21 20:02 asarmy

I had been thinking about supporting this by adding a hue_target or similar parameter that could take face or edge, but this is a feasible alternate suggestion. I'd say it could go a bit further and map hue to the edges whenever facecolor is specified at all. (I guess I can't think of an obvious case where that's necessary, but it seems like supporting the general case has no cost, sooo).

Another option would be to add fill={bool}, which is how the distribution plots work. I think the implementation would be a bit simpler. It wouldn't let you map edge with a different face color, but maybe that isn't useful enough.

I'd want this to work consistently across all plots with artists that have facecolor/edgecolor, so barplot, the categorical scatter plots, and others should be included in any work.

A relevant upstream issue is https://github.com/matplotlib/matplotlib/pull/17850. There are some significant complexities in matplotlib here to be aware of.

mwaskom avatar Feb 28 '21 20:02 mwaskom

I'm going to close this as completed in the new objects interface. It's possible that it would get added to the plotting functions in the future as they get refactored to use the objects behind the scenes, but it's not explicitly planned as I'm not yet certain how much extra complexity should get packed into them.

Example with the new interface:

(
    so.Plot(tips, "total_bill", "tip", color="day")
    .add(so.Dot(fill=False, stroke=2, pointsize=8))
)

image

Or (for some reason) map the edge color but maintain a facecolor:

(
    so.Plot(tips, "total_bill", "tip", edgecolor="day")
    .add(so.Dot(color="w", edgewidth=2, pointsize=8))
)

image

mwaskom avatar Sep 13 '22 23:09 mwaskom