Closed eeeXun closed 5 months ago
It's possible that matplotlib changed the underlying data model as ax.artists
is empty in your example script. But you can access the box patches more directly at ax.patches
. Also seaborn v0.13 started packaging the boxplot artists in a container and storing it at ax.containers
which is another way of making your post-processing a bit more explicit.
Thanks. Changing ax.artists
to ax.patches
works for me.
from itertools import cycle
from matplotlib import pyplot as plt
import seaborn as sns; sns.set()
# Load dataset
tips = sns.load_dataset('tips')
# Define some hatches
hatches = cycle(['///', 'x'])
# Boxplot
ax = sns.boxplot(x="day", y="total_bill", hue="sex", data=tips)
for i, patch in enumerate(ax.patches):
# Boxes from left to right
hatch = next(hatches)
patch.set_hatch(hatch)
ax.legend()
plt.show()
But what do you mean ax.containers
? Changing ax.artists
to ax.containers
gives the error that BoxPlotContainer
has no attribute set_hatch
. Do I call it the wrong way?
Do I call it the wrong way?
Yes — do e.g.
bxp = ax.containers[0]
bxp.boxes
[<matplotlib.patches.PathPatch at 0x12b095a50>,
<matplotlib.patches.PathPatch at 0x12b0a4950>,
<matplotlib.patches.PathPatch at 0x12b0602d0>,
<matplotlib.patches.PathPatch at 0x12b0636d0>]
Oh, I get it. Thank you for answering me so quickly. Appreciate!
Hi @mwaskom, after trying again. ax.containers
is exactly what I want.
from matplotlib import pyplot as plt
import seaborn as sns; sns.set()
# Load dataset
tips = sns.load_dataset('tips')
# Define some hatches
hatches = ['///', 'x']
# Boxplot
ax = sns.boxplot(x="day", y="total_bill", hue="sex", data=tips)
for i in range(2):
for box in ax.containers[i].boxes:
box.set_hatch(hatches[i % len(hatches)])
ax.legend()
plt.show()
But the legend did not get the hatch style. Is there any way to do that?
You can modify those artists too, i think it's something like ax.get_legend().legend_handles
from matplotlib import pyplot as plt
import seaborn as sns; sns.set()
# Load dataset
tips = sns.load_dataset('tips')
# Define some hatches
hatches = ['///', 'x']
# Boxplot
ax = sns.boxplot(x="day", y="total_bill", hue="sex", data=tips)
ax.legend()
for i in range(2):
for box in ax.containers[i].boxes:
box.set_hatch(hatches[i % len(hatches)])
ax.get_legend().legend_handles[i].set_hatch(hatches[i % len(hatches)])
plt.show()
Thank you again for your help!
Hi, I just follow this code to use the
set_hatch
inboxplot
. But it doesn't seem to work for me.My
python
version is3.10.12
.seaborn
version is0.13.2
.matplotlib
version is3.9.0
. Is there any change in theset_hatch
or it just break bymatplotlib
?