在Python Graphs中使用Seaborn生成嵌套框图中的箱形图之间的空间?

时间:2015-07-19 07:13:04

标签: python matplotlib boxplot seaborn

我正在尝试在使用Python Seaborn模块sns.boxplot()创建的箱图(绿色和橙色框之间)之间设置空格。请参见附图,绿色和橙色子图框相互粘连,使其在视觉上不是最吸引人的。

无法找到办法,任何人都可以找到方法(代码附加)?

Seaborn Boxplots

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 boxplot文档位于:http://stanford.edu/~mwaskom/software/seaborn/generated/seaborn.boxplot.html

1 个答案:

答案 0 :(得分:1)

冒着不再需要这种危险的危险,我找到了解决这个问题的方法。使用matplotlib直接绘制boxplots时,可以使用widthposition关键字控制框的排列。但是,将positions关键字传递给sns.factorplot(kind='box',...)时,会得到一个

TypeError: boxplot() got multiple values for keyword argument 'positions'

要解决这个问题,可以手动设置框的宽度' 之后创建了boxplot。这有点单调乏味,因为这些框在PatchPatches的{​​{1}}个Axes实例中存储为FacedGrid。而不是sns.factorplot具有的简单(x,y,width,height)语法,Rects使用顶点来定义角点,当需要调整框时,这涉及更多的计算。除此之外,PathPatches返回的PathPatches包含matplotlib.boxplot代码的额外(忽略)顶点,该代码设置为Path.CLOSEPOLY,最好被忽略。除了框之外,标记中位数的水平线现在太宽,需要进行调整。

下面我定义一个函数来调整OP示例代码生成的框的宽度(注意额外的导入):

(0,0)

调用此函数
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])

给出以下输出:

seaborn boxplot with adjusted box width