-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sns.histplot has a mystery/ghost patch, new with update from 0.11.2--> 0.12.2 #3241
Comments
Please convert this to a reproducible example and simplify (do you need the complicated hatching business to demonstrate it? etc.) |
this is as simple as I can make it i think. thank you! |
or I guess this is even simpler
My guess is that blue is the default value and somehow even when passing in another color, it uses blue instead. for example either a hard code issue that was meant to be temporary? just a guess |
Calling |
okay I thought that was a good assumption but I guess not. They make that assumption at least for line order in the matplotlib documentation directly copied below.
what is best practice for sns.histplot? should I explicitly make the patches? normally I would just put |
As Seaborn creates rather complicated plots with many options, and tries to have legends with compact information, legends are build up from custom elements. Matplotlib's default legend, on the other hand, searches for labeled graphical elements in the plot. Or, when only given labels are provided, matplotlib searches for all suitable elements. A real best practice doesn't exist for what you want to achieve. Below is an approach that works with the current Seaborn/matplotlib versions, but still depends on where in the import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
colors_in = ['y', 'r']
tmp1 = pd.DataFrame([[1., 1.], [1., 0.], [9., 7.], [-10., 1.], [5., 2.], [0., 0.], [0., 0.]],
columns=['name_1', 'name_2'])
ax = sns.histplot(data=tmp1, kde=True, multiple='layer', palette=colors_in, alpha=.5)
ax.lines[0].set_label('KDE 1') # leave this out if it's not needed in the legend
ax.lines[1].set_label('KDE 2')
for bar in ax.containers[1]:
bar.set_hatch('//')
ax.containers[1].set_label('name_1')
ax.containers[2].set_label('name_2')
ax.legend(loc='upper right', bbox_to_anchor=(1, 1), fontsize=12)
plt.show() |
Okay makes sense! thanks you so much, I didn't even know about thank you both for your help, I'll close the issue now. |
I'd actually suggest a slightly different approach which would be to add hatches to artists based on their color and to modify the legend handles themselves directly: from matplotlib.colors import same_color, to_rgb
tmp1 = pd.DataFrame([[ 1., 1.],
[ 1., 0.],
[ 9., 7.],
[-10., 1.],
[ 5., 2.],
[ 0., 0.],
[ 0., 0.]])
colors_in = ['y', 'r']
hatch_color = colors_in[-1]
ax = sns.histplot(data=tmp1, palette=colors_in)
for patch in ax.patches:
if same_color(to_rgb(patch.get_facecolor()), hatch_color):
patch.set_hatch("//")
legend = ax.get_legend()
for h in legend.legend_handles:
if isinstance(h, mpl.patches.Rectangle) and same_color(to_rgb(h.get_facecolor()), hatch_color):
h.set_hatch("//") This way you're not making any assumptions about artist order and will ensure that the hatching information represents the same variable as the color information. BTW the underlying issue here is something that we can address (#3246) but I'd still strongly recommend learning how to make any post-hoc manipulations like this explicit rather than implicit, because otherwise you're bound to get yourself into trouble at some point. |
Thanks for the the detailed approach! I see your point and will be careful to not make that assumption again, much appreciated! |
the problem is outlined here in this colab notebook
https://colab.research.google.com/drive/1i69qTX1SPSPKogUBa2tMUmjC3cHO_VPn?usp=sharing
sns.version, mpl.version
('0.11.2', '3.2.2')
displot and histplot display correct patched when finding the patched plotted as a hist (used for key)
sns.version, mpl.version
('0.12.2', '3.6.3')
there is a blue patch somewhere only for histplot but not for displot
The text was updated successfully, but these errors were encountered: