2016-05-12 10 views
3

Ich versuche, einen Box-Plot in Python 2.7 für jeden kategorischen Wert in der Spalte E von dem Pandas Datenrahmen unterPython Side-by-Side-Box-Plots auf derselben Figur

  A   B   C   D E 
0 0.647366 0.317832 0.875353 0.993592 1 
1 0.504790 0.041806 0.113889 0.445370 2 
2 0.769335 0.120647 0.749565 0.935732 3 
3 0.215003 0.497402 0.795033 0.246890 1 
4 0.841577 0.211128 0.248779 0.250432 1 
5 0.045797 0.710889 0.257784 0.207661 4 
6 0.229536 0.094308 0.464018 0.402725 3 
7 0.067887 0.591637 0.949509 0.858394 2 
8 0.827660 0.348025 0.507488 0.343006 3 
9 0.559795 0.820231 0.461300 0.921024 1 

ich bereit wäre zu erzeugen, zu tun dies mit Matplotlib oder einer anderen Plot-Bibliothek. Bis jetzt kann der obige Code alle Kategorien, die auf einem Diagramm kombiniert sind, grafisch darstellen. Hier ist der Code ist es, die oben genannten Daten zu erzeugen, und die Handlung zu erzeugen:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
fig, ax = plt.subplots() 

# Data 
df = pd.DataFrame(np.random.rand(10,4),columns=list('ABCD')) 
df['E'] = [1,2,3,1,1,4,3,2,3,1] 

# Boxplot 
bp = ax.boxplot(df.iloc[:,:-1].values, widths=0.2) 
plt.show() 

In diesem Beispiel sind die Kategorien 1,2,3,4. Ich möchte separate Boxplots Seite an Seite auf der gleichen Figur für nur die Kategorien 1 und 2 darstellen und die Kategorienamen in der Legende zeigen.

Gibt es eine Möglichkeit, dies zu tun?

Weitere Informationen:

Der Ausgang der dritten Figur von here ähnlich aussehen sollte - ersetzen Sie "Ja", "Nein" von "1", "2".

+0

Dieses Beispiel funktioniert nicht Weil Matplotlib die Daten nach Spalten abbildet, gibt es 4 Boxplots mit den Bezeichnungen A, B, C und D. –

+0

Ja, das stimmt. Ich hätte gerne 4 Boxplots für Kategorie 1 und 4 Boxplots für Kategorie 2. Ich fügte einen Link zum OP hinzu, der etwas ähnliches an anderer Stelle zeigt. Ich suche nach einer ähnlichen Handlung dazu. –

Antwort

7

mit diesem Start:

import numpy 
import pandas 
from matplotlib import pyplot 
import seaborn 
seaborn.set(style="ticks") 

# Data 
df = pandas.DataFrame(numpy.random.rand(10,4), columns=list('ABCD')) 
df['E'] = [1, 2, 3, 1, 1, 4, 3, 2, 3, 1] 

Sie haben ein paar Optionen. Wenn getrennte Achsen sind in Ordnung,

fig, axes = pyplot.subplots(ncols=4, figsize=(12, 5), sharey=True) 
df.query("E in [1, 2]").boxplot(by='E', return_type='axes', ax=axes) 

enter image description here

Wenn Sie 1 Achsen, denke ich Seaborn leichter sein wird. Sie müssen nur Ihre Daten bereinigen.

ax = (
    df.set_index('E', append=True) # set E as part of the index 
     .stack()      # pull A - D into rows 
     .to_frame()     # convert to a dataframe 
     .reset_index()    # make the index into reg. columns 
     .rename(columns={'level_2': 'quantity', 0: 'value'}) # rename columns 
     .drop('level_0', axis='columns') # drop junk columns 
     .pipe((seaborn.boxplot, 'data'), x='E', y='value', hue='quantity', order=[1, 2]) 
) 
seaborn.despine(trim=True) 

enter image description here

Die kühle Sache über Seaborn ist, dass die Parameter leicht zwicken eine Menge in Bezug auf die Handlung des Layout erreichen können. Wenn wir unsere hue und x Variablen wechseln, erhalten wir:

ax = (
    df.set_index('E', append=True) # set E as part of the index 
     .stack()      # pull A - D into rows 
     .to_frame()     # convert to a dataframe 
     .reset_index()    # make the index into reg. columns 
     .rename(columns={'level_2': 'quantity', 0: 'value'}) # rename columns 
     .drop('level_0', axis='columns') # drop junk columns 
     .pipe((seaborn.boxplot, 'data'), x='quantity', y='value', hue='E', hue_order=[1, 2]) 
) 
seaborn.despine(trim=True) 

Wenn Sie neugierig sind, ist die resultierende Datenrahmen etwa wie folgt aussieht:

E quantity  value 
0 1  A 0.935433 
1 1  B 0.862290 
2 1  C 0.197243 
3 1  D 0.977969 
4 2  A 0.675037 
5 2  B 0.494440 
6 2  C 0.492762 
7 2  D 0.531296 
8 3  A 0.119273 
9 3  B 0.303639 
10 3  C 0.911700 
11 3  D 0.807861 
+0

Wenn ich versuche 'df = df.set_index ('E', append = True) .stack(). To_frame(). Rename (Spalten = {'level_2': 'quantity', 0: 'value'}). Drop ('level_0', axis = 'columns') 'Ich bekomme einen Fehler 'ValueError: labels [' level_0 '] nicht in axis' enthalten. Ich würde es vorziehen, in der Lage zu sein, den Datenrahmen zu sehen, bevor ich ihn grafiere. Ist es möglich, den Pandas DF zuerst zu erzeugen, bevor der Boxplot generiert wird? Ist es auch möglich, Dinge wie Whiskergröße, Kappengröße, Fliegergröße/Farbe in Seaborn anzupassen? –

+1

Ja. Nur nicht in seaborn.boxplot pipen und den Aufruf separat machen. –

+0

Danke das hat funktioniert. Ist es möglich, Dinge wie Whiskergröße, Kappengröße, Fliegergröße/Farbe in Seaborn anzupassen? Z.B. in Matplotlib hätte ich 'bp = ax.boxplot()' und dann Whisker in bp ['whiskers']: whisker gemacht.setze (lw = 0.5, linestyle = '-'). Wenn ich dies mit 'bp = sns.boxplot() 'versuche, bekomme ich' TypeError:' Axes 'Objekt hat kein Attribut' __getitem __ ''. Können diese Anpassungen vorgenommen werden? –