Here is the answer if you want this to work for boxplots or boxenplots. I've tested this with axes from sns.catplot().
def new_adjust_box_widths(axes, fac=0.9):
"""
Adjust the widths of a seaborn-generated boxplot or boxenplot.
Notes
-----
- thanks https://github.com/mwaskom/seaborn/issues/1076
"""
from matplotlib.patches import PathPatch
from matplotlib.collections import PatchCollection
if isinstance(axes, list) is False:
axes = [axes]
# iterating through Axes instances
for ax in axes:
# iterating through axes artists:
for c in ax.get_children():
# searching for PathPatches
if isinstance(c, PathPatch) or isinstance(c, PatchCollection):
if isinstance(c, PathPatch):
p = c.get_path()
else:
p = c.get_paths()[-1]
# getting current width of box:
# p = c.get_path()
verts = p.vertices
verts_sub = verts[:-1]
xmin = np.min(verts_sub[:, 0])
xmax = np.max(verts_sub[:, 0])
xmid = 0.5 * (xmin + xmax)
xhalf = 0.5 * (xmax - xmin)
# setting new width of box
xmin_new = xmid - fac * xhalf
xmax_new = xmid + fac * xhalf
verts_sub[verts_sub[:, 0] == xmin, 0] = xmin_new
verts_sub[verts_sub[:, 0] == xmax, 0] = xmax_new
# setting new width of median line
for l in ax.lines:
try:
if np.all(l.get_xdata() == [xmin, xmax]):
l.set_xdata([xmin_new, xmax_new])
except:
# /tmp/ipykernel_138835/916607433.py:32: DeprecationWarning: elementwise comparison failed;
# this will raise an error in the future.
# if np.all(l.get_xdata() == [xmin, xmax]):
pass
pass
g = sns.catplot(*args, kind='box', **kwargs) # or kind='boxen'
new_adjust_box_widths(list(g.axes[0]))