2015-04-21 21 views
7

Ho visto questo meraviglioso boxplot in this article (Fig.2).Aggiunta di uno spargimento di punti a un boxplot utilizzando matplotlib

A wonderful boxplot

Come si può vedere, si tratta di un grafico a scatole su cui si sovrappongono una dispersione di punti neri: gli indici x dei punti neri (in ordine casuale), Y è la variabile di interesse. Mi piacerebbe fare qualcosa di simile usando Matplotlib, ma non ho idea da dove cominciare. Finora, i grafici a scatole che ho trovato on-line sono il modo meno fresco e simile a questa:

Usual boxplots

Documentazione di matplotlib: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.boxplot

modi per colorare i grafici a scatole: https://github.com/jbmouret/matplotlib_for_papers#colored-boxes

+0

potrebbe essere correlato: http://stackoverflow.com/q/28521828/376454 – Wok

risposta

12

Cosa stai cercando è un modo per aggiungere jitter all'asse x.

Qualcosa di simile a questo tratto da here:

bp = titanic.boxplot(column='age', by='pclass', grid=False) 
for i in [1,2,3]: 
    y = titanic.age[titanic.pclass==i].dropna() 
    # Add some random "jitter" to the x-axis 
    x = np.random.normal(i, 0.04, size=len(y)) 
    plot(x, y, 'r.', alpha=0.2) 

enter image description here

Citando il link:

Un modo per aggiungere ulteriori informazioni a un grafico a scatole è quello di sovrapporre i dati effettivi ; questo è generalmente più adatto con serie di dati di piccole dimensioni o di dimensioni moderate. Quando i dati sono densi, un paio di trucchi utilizzato sopra aiuto visualizzazione:

  1. ridurre il livello alfa per rendere i punti semitrasparenti
  2. aggiungendo "jitter" random lungo l'asse x per evitare overstriking

Il codice simile a questo:

import pylab as P 
import numpy as np 

# Define data 
# Define numBoxes 

P.figure() 

bp = P.boxplot(data) 

for i in range(numBoxes): 
    y = data[i] 
    x = np.random.normal(1+i, 0.04, size=len(y)) 
    P.plot(x, y, 'r.', alpha=0.2) 

P.show() 
+5

risposta Nizza. Ti preghiamo di considerare l'aggiunta di tutte le importazioni necessarie per facilitare la riproduzione del tuo codice da parte degli altri. – cel

3

Ampliando Soluzione di Kyrubas e utilizzo solo di matplotlib per la parte di plottaggio (a volte ho difficoltà a formattare i grafici dei panda con Matplotlib).

from matplotlib import cm 
import matplotlib.pyplot as plt 
import pandas as pd 
import numpy as np 

# initialize dataframe 
n = 200 
ngroup = 3 
df = pd.DataFrame({'data': np.random.rand(n), 'group': map(np.floor, np.random.rand(n) * ngroup)}) 

group = 'group' 
column = 'data' 
grouped = df.groupby(group) 

names, vals, xs = [], [] ,[] 

for i, (name, subdf) in enumerate(grouped): 
    names.append(name) 
    vals.append(subdf[column].tolist()) 
    xs.append(np.random.normal(i+1, 0.04, subdf.shape[0])) 

plt.boxplot(vals, labels=names) 
ngroup = len(vals) 
clevels = np.linspace(0., 1., ngroup) 

for x, val, clevel in zip(xs, vals, clevels): 
    plt.scatter(x, val, c=cm.prism(clevel), alpha=0.4) 

enter image description here

+0

Per gli utenti di Python 3, è necessario avvolgere la mappa in un elenco, in questo modo: ''gruppo': lista (mappa (np.floor, np.random.rand (n) * ngroup))' – jss367