I created a bar plot with hatches using seaborn
. I was also able to add a legend that included the hatch styles, as shown in the MWE below:
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
hatches = ['\\\\', '//']
fig, ax = plt.subplots(figsize=(6,3))
sns.barplot(data=tips, x="day", y="total_bill", hue="time")
# loop through days
for hues, hatch in zip(ax.containers, hatches):
# set a different hatch for each time
for hue in hues:
hue.set_hatch(hatch)
# add legend with hatches
plt.legend().loc='best'
plt.show()
However, when I try to create a histogram on seaborn
with a legend, the same code does not work; I get the following error: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
I've looked for an answer online, but I haven't been successful at finding one.
How can I add the hatches to the legend of a histogram for the MWE below?
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
hatches = ['\\\\', '//']
fig, ax = plt.subplots(figsize=(6,3))
sns.histplot(data=tips, x="total_bill", hue="time", multiple='stack')
# loop through days
for hues, hatch in zip(ax.containers, hatches):
# set a different hatch for each time
for hue in hues:
hue.set_hatch(hatch)
# add legend with hatches
plt.legend().loc='best' # this does not work
plt.show()
The issue is ax1.get_legend_handles_labels()
returns empty lists for seaborn.histplot. Refer to this answer. Use the explicit interface by adding ax=ax
to seaborn.histplot(...)
. Use ax.get_legend().legend_handles
(.legendHandles
is deprecate) to get the handles for the legend, and add hatches with set_hatch()
.
ax.get_legend().legend_handles
returns the handles in the reverse order compared to the container
, so the order can be reversed with [::-1]
.
Tested in python 3.11.2
, matplotlib 3.7.1
, seaborn 0.12.2
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
hatches = ['\\\\', '//']
fig, ax = plt.subplots(figsize=(6, 3))
sns.histplot(data=tips, x="total_bill", hue="time", multiple='stack', ax=ax) # added ax=ax
# iterate through each container, hatch, and legend handle
for container, hatch, handle in zip(ax.containers, hatches, ax.get_legend().legend_handles[::-1]):
# update the hatching in the legend handle
handle.set_hatch(hatch)
# iterate through each rectangle in the container
for rectangle in container:
# set the rectangle hatch
rectangle.set_hatch(hatch)
plt.show()