2015-01-23 17 views
9

Il seguente codice mi dà un bel violinplot (e un boxplot all'interno).Come meglio adattarsi ai violinplot di Seaborn?

import numpy as np 
import seaborn as sns 
import matplotlib.pyplot as plt 

foo = np.random.rand(100) 
sns.violinplot(foo) 
plt.boxplot(foo) 
plt.show() 

output

Fin qui tutto bene. Tuttavia, quando guardo allo foo, la variabile non contiene valori negativi. La trama seaborn sembra fuorviante qui. Il normale boxplot matplotlib offre qualcosa di più vicino a ciò che mi aspetterei.

Come posso rendere i violinplot più adatti (non mostrando valori falsi negativi)?

+0

Beh, probabilmente non è così facile. Questo è un artefatto di KDE, che non sa che c'è un confine difficile a 0. Se sei interessato al problema, vedi anche: http://stats.stackexchange.com/questions/65866/good-methods-for -density-plots-of-non-negative-variables-in-r? lq = 1 – cel

+0

@cel Grazie. questo è quello che stavo pensando. Ma non potrebbe essere adattato più stretto? – n1000

+1

Ci sono algoritmi per questo. Guarda il risultato impressionante in questa risposta: http://stats.stackexchange.com/a/71291. Tuttavia non l'ho ancora visto in python. – cel

risposta

10

Come si nota dai commenti, questa è una conseguenza (non sono sicuro che lo chiamerei un "artefatto") delle ipotesi sottostanti al KDE gaussiano. Come è stato detto, questo è in qualche modo inevitabile, e se i tuoi dati non soddisfano queste ipotesi, potresti star meglio usando un boxplot, che mostra solo i punti che esistono nei dati reali.

Tuttavia, nella tua risposta ti chiedi se potrebbe essere più "stretto", il che potrebbe significare alcune cose.

Una risposta potrebbe essere quella di modificare la larghezza di banda del kernel di smoothing. Lo fai con l'argomento bw, che in realtà è un fattore di scala; la larghezza di banda che verrà utilizzata è bw * data.std():

data = np.random.rand(100) 
sns.violinplot(y=data, bw=.1) 

enter image description here

Un'altra risposta potrebbe essere quella di troncare il violino agli estremi dei datapoint. Il KDE sarà ancora adatto a con densità che si estendono oltre i limiti dei dati, ma le code non verranno mostrate. Lo fai con il parametro cut, che specifica quante unità di larghezza di banda oltre i valori estremi devono essere disegnati. Per troncare, impostare a 0:

sns.violinplot(y=data, cut=0) 

enter image description here

Tra l'altro, l'API per violinplot è going to change a 0,6, e sto usando la versione di sviluppo qui, ma entrambi gli argomenti bw e cut esistono nella versione attuale rilasciata e si comportano più o meno allo stesso modo.

+1

Non mi piace la soluzione che usa 'cut'. Nasconde il fatto che 'KDE' non può adattarsi correttamente a tali densità. La densità vicino al confine 0 è fuorviante, poiché si otterrà una stima della densità, anche se l'istogramma corrispondente ha il massimo a 0. – cel

+0

Vedere la richiesta di funzionalità all'indirizzo https://github.com/mwaskom/seaborn/issues/ 525 (in attesa di modifiche a monte in statsmodels). – naught101

Problemi correlati