2015-07-19 9 views
6

Ich versuche, einen Abstand zwischen den Boxplots (zwischen den grünen und orangefarbenen Boxen) mit Python Seaborn Modul sns.boxplot() erstellt. In der Grafik sehen Sie, dass die grünen und orangefarbenen Subplot-Boxen aneinander haften und somit optisch nicht besonders ansprechend sind.Abstand zwischen Boxplots in Python-Graphen festlegen Generierte Schachteldarstellungen mit Seaborn?

Kann ich keinen Weg finden, irgendjemand könnte einen Weg finden (Code beigefügt)?

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) 

Die Seaborn boxplot Dokumentation ist hier: http://stanford.edu/~mwaskom/software/seaborn/generated/seaborn.boxplot.html

Antwort

0

die Gefahr laufen, dass diese nicht mehr benötigt wird, fand ich für dieses Problem eine Lösung. Beim Zeichnen von boxplots direkt mit Matplotlib kann die Anordnung der Boxen mit den Schlüsselwörtern width und position gesteuert werden. Wenn jedoch das Bestehen der positions Schlüsselwort sns.factorplot(kind='box',...), so erhält man ein

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

Um dies zu umgehen, kann man die Breite der Felder ‚manuell‘ nach gesetzt die boxplot erstellt wurde. Dies ist ein wenig mühsam, weil die Boxen als PatchPatches innerhalb der einzelnen Axes Instanzen der FacedGrid gespeichert werden, die von sns.factorplot zurückgegeben wird. Anstelle der einfachen (x,y,width,height) Syntax, die Rects haben, verwenden PathPatches Vertices, um die Ecken zu definieren, was etwas mehr Rechenaufwand erfordert, wenn man die Boxen anpassen will. Obendrein enthält die PathPatches, die von matplotlib.boxplot zurückgegeben wird, einen zusätzlichen (ignorierten) Vertex für den Code Path.CLOSEPOLY, der auf (0,0) gesetzt ist und am besten ignoriert wird. Zusätzlich zu der Box ist die horizontale Linie, die den Median markiert, jetzt zu breit und muss ebenfalls angepasst werden.

Im Folgenden werde ich eine Funktion definieren, die durch den Beispielcode des OP erzeugten Breiten der Boxen passt (beachten Sie den zusätzlichen Import):

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]) 

Aufruf dieser Funktion mit

adjust_box_widths(g, 0.9) 

gibt die folgende Ausgabe :

seaborn boxplot with adjusted box width