我发现另一个用户发布的解决方案。此函数用于按您选择的因子调整所创建图形中所有对象的宽度。
from matplotlib.patches import PathPatch
def adjust_box_widths(g, fac):
"""
Adjust the withs of a seaborn-generated boxplot.
"""
# iterating through Axes instances
for ax in g.axes:
# iterating through axes artists:
for c in ax.get_children():
# searching for PathPatches
if isinstance(c, PathPatch):
# 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:
if np.all(l.get_xdata() == [xmin, xmax]):
l.set_xdata([xmin_new, xmax_new])
例如:fig = plt.figure(figsize=(15, 13))
bp = sns.boxplot(#insert data and everything)
adjust_box_widths(fig, 0.9)
如果你想让这个适用于箱线图或盒形图,这里是答案。我已经使用了来自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]))