2017-05-04 2 views
1

kann ich DataFrameGroupBy.boxplot (...) verwenden, um eine boxplot in der folgenden Art und Weise zu erstellen:Warum wirft die DataFrameGroupBy.boxplot-Methode einen Fehler, wenn das Argument "subplots = True/False" übergeben wird?

In [15]: df = pd.DataFrame({"gene_length":[100,100,100,200,200,200,300,300,300], 
...:      "gene_id":[1,1,1,2,2,2,3,3,3], 
...:      "density":[0.4,1.1,1.2,1.9,2.0,2.5,2.2,3.0,3.3], 
...:      "cohort":["USA","EUR","FIJ","USA","EUR","FIJ","USA","EUR","FIJ"]}) 

In [17]: df.groupby("cohort").boxplot(column="density",by="gene_id")

In [18]: plt.show()

Dies ergibt folgendes Bild: enter image description here

Das ist genau das, was ich will, außer, anstatt drei Unterplots zu machen, möchte ich, dass alle Plots in einem Plot liegen (mit unterschiedlichen colo rs für USA, EUR und FIJ). Ich habe versucht,

In [17]: df.groupby("cohort").boxplot(column="density",subplots=False,by="gene_id")

aber es erzeugt den Fehler

KeyError: 'gene_id'

Ich denke, das Problem etwas mit der Tatsache zu tun, dass by="gene_id" ein Keyword an die matplotlib boxplot Methode gesendet wird. Wenn jemand eine bessere Möglichkeit hat, die Handlung zu erzeugen, nach der ich gesucht habe, vielleicht indem Sie stattdessen DataFrame.boxplot (?) Verwenden, antworten Sie bitte hier. Vielen Dank!

Antwort

2

die reinen pandas Funktionen nutzen zu können, ich glaube, Sie sollten nicht GroupBy vor boxplot Aufruf, sondern verlangen, zu einer Gruppe von bestimmten Spalten in dem Aufruf von boxplot auf dem DataFrame selbst:

df.boxplot(column='density',by=['gene_id','cohort']) 

enter image description here

Um ein besseres Ergebnis zu erhalten, sollten Sie die Bibliothek Seaborn in Erwägung ziehen. Es ist so konzipiert, genau mit dieser Art von Aufgaben zu helfen:

sns.boxplot(data=df,x='gene_id',y='density',hue='cohort') 

enter image description here

EDIT unter Berücksichtigung Kommentar nehmen Wenn Sie jede Ihrer Kohorte Boxplots gestapelt/lagert für jede gene_id haben wollen Es ist ein bisschen komplizierter (und Sie könnten mit einer ziemlich hässlichen Ausgabe enden). Sie können dies nicht mit Seaborn, AFAIK tun, aber Sie könnten mit Pandas direkt, indem Sie den position= Parameter zu boxplot (see doc). Sie fangen die richtige Reihenfolge der Positionen ein, um die Boxplots an die gewünschte Position zu bringen, aber Sie müssen die Tick-Beschriftungen und die Legende selbst korrigieren.

pos = [i for i in range(len(df.gene_id.unique())) for _ in range(len(df.cohort.unique()))] 
df.boxplot(column='density',by=['gene_id','cohort'],positions=pos) 

enter image description here

Eine Alternative wäre seaborn.swarmplot zu verwenden, anstatt boxplot zu verwenden. Ein Swarmplot zeichnet jeden Punkt anstelle der synthetischen Darstellung von Boxplots auf, aber Sie können den Parameter split=False verwenden, um die Punkte farbig nach Kohorte zu erhalten, aber für jede gen_id übereinander gestapelt.

sns.swarmplot(data=df,x='gene_id',y='density',hue='cohort', split=False) 

enter image description here

ohne den eigentlichen Inhalt Ihrer Datenrahmen zu wissen (Anzahl der Punkte pro Gen und pro Kohorte, und wie trennen sie sich in jeder Kohorte sind), ist es schwer zu sagen, welche Lösung die meisten wäre angemessen.

+0

Vielen Dank für diese Antwort. Dies ist eine großartige Lösung für den von mir erstellten Spieldatensatz, insbesondere für die Seaborn-Bibliothek. Da mein Datensatz leider 90 Gene enthält, kann ich mir keinen Platz mehr leisten, Kohorten nebeneinander zu gruppieren. Stattdessen müssen sie vertikal übereinander gestapelt werden. Vielleicht erlaubt Seaborn das? – ecneicS

+0

@ecneicS Ich habe meine Antwort abgeschlossen, schau es dir an –

+0

Fantastisch. Vielen Dank! – ecneicS

Verwandte Themen