Seaborn
模块的 sns.boxplot()
创建的箱线图之间(绿色和橙色框之间)设置一个空格。请参阅附图,绿色和橙色的子图框彼此粘在一起,使其在视觉上不是最吸引人的。
找不到办法做到这一点,任何人都可以找到办法(附有代码)?
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
sns.set(style="ticks", palette='Set2', font='Roboto Condensed')
sns.set_context("paper", font_scale=1.1, rc={"lines.linewidth": 1.1})
g=sns.factorplot(x="time", y="total_bill", hue="smoker",
col="day", data=tips, kind="box", size=4, aspect=0.5,
width=0.8,fliersize=2.5,linewidth=1.1, notch=False,orient="v")
sns.despine(trim=True)
g.savefig('test6.png', format='png', dpi=600)
Seaborn
箱线图文档位于:http://stanford.edu/~mwaskom/software/seaborn/ generated/seaborn.boxplot.html
冒着不再需要这个的危险,我找到了解决这个问题的方法。当直接使用 matplotlib 绘制
boxplots
时,可以使用 width
和 position
关键字控制框的排列。然而,当将 positions
关键字传递给 sns.factorplot(kind='box',...)
时,会得到
TypeError: boxplot() got multiple values for keyword argument 'positions'
为了解决这个问题,可以在创建箱线图之后“手动”设置框的宽度。这有点乏味,因为这些框作为 PatchPatches
存储在由
Axes
返回的 FacedGrid
的各个 sns.factorplot
实例中。与 (x,y,width,height)
所具有的简单 Rects
语法不同,PathPatches
使用顶点来定义角,当想要调整框时,这会涉及更多的计算。最重要的是, PathPatches
返回的 matplotlib.boxplot
包含 Path.CLOSEPOLY
代码的额外(忽略)顶点,该顶点设置为 (0,0)
并且最好忽略。除了方框之外,标记中位数的水平线现在也太宽,也需要调整。 下面我定义了一个函数来调整OP示例代码生成的框的宽度(注意额外的导入):
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.flatten():
##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])
用调用此函数
adjust_box_widths(g, 0.9)
给出以下输出: