2015-07-26 7 views
8

Sto cercando di personalizzare alcune figure con il modulo Seaborn in Python, ma non ho avuto la fortuna di creare etichette o annotazioni personalizzate. Ho un po 'di codice che genera il seguente dato:Personalizzazione dell'annotazione con FacetGrid di Seaborn

plot = sns.FacetGrid(data = data, col = 'bot', margin_titles = True).set_titles('Human', 'Bot') 
bins = np.linspace(0, 2000, 15) 
plot = plot.map(plt.hist, 'friends_count', color = 'black', lw = 0, bins = bins) 
plot.set_axis_labels('Number Following', 'Count') 
sns.despine(left = True, bottom = True) 

enter image description here

mi piacerebbe fare due cose: 1. Sostituire le etichette fattore di default, ad esempio, 'bot = 0.0', con testo significativo, e 2. traccia linee verticali al numero medio seguente per ogni categoria.

Ecco un self-contained esempio:

import pandas as pd 
import seaborn as sns 
import matplotlib.pyplot as plt 

fake = pd.DataFrame({'val': [1, 2, 2, 3, 3, 2, 1, 1, 2, 3], 'group': [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}) 
plot = sns.FacetGrid(data = fake, col = 'group', margin_titles = True).set_titles('zero', 'one') 
plot = plot.map(plt.hist, 'val', color = 'black', lw = 0) 
sns.despine(left = True, bottom = True) 

Qualcuno sa come personalizzare FacetGrids?

+0

check out il metodo 'FacetGrid.set_titles'. – mwaskom

+1

Sì, l'ho provato, ma niente lo rende. Qualche idea su come creare linee verticali in punti diversi su ciascuna? –

+2

Non so cosa significhi "niente rendering". Se hai provato le cose e non hai funzionato, dovresti aggiungere anche la domanda. Inoltre è molto più semplice aiutare quando la tua domanda ha un esempio autonomo che qualcuno può copiare e incollare per costruire. Forse potresti utilizzare uno dei set di dati Seaborn di esempio che vengono utilizzati nel tutorial. – mwaskom

risposta

12

Alcune informazioni su set_titles.

In primo luogo, i titoli di default sono disegnati nel metodo FacetGrid.map, quindi se si desidera modificare i titoli, devi chiamare set_titlesdopo tracciato, altrimenti verranno sovrascritti.

In secondo luogo, se si guarda la docstring per il metodo, non prende solo una lista arbitraria di titoli. Esso fornisce un modo per cambiare il modo il titolo è resa utilizzando il nome della variabile di colonna e il valore:

template : string 
    Template for all titles with the formatting keys {col_var} and 
    {col_name} (if using a `col` faceting variable) and/or {row_var} 
    and {row_name} (if using a `row` faceting variable). 

Quindi il modo più semplice per avere "testo significativo" è quello di utilizzare i dati significativi nella vostra dataframe. Prendete questo esempio con dati casuali:

df = pd.DataFrame({'val': np.random.randn(100), 
        'group': np.repeat([0, 1], 50)}) 

Se si vuole "gruppo" di essere zero e one, si dovrebbe solo cambiare quella colonna, o fare uno nuovo:

df["group"] = df["group"].map({0: "zero", 1; "one"}) 

poi dici don 't vogliono avere il nome della variabile nel titolo, il modo corretto di utilizzare FacetGrid.set_titles sarebbe

g = sns.FacetGrid(data=df, col='group') 
g.map(plt.hist, 'val', color='black', lw=0) 
g.set_titles('{col_name}') 

some bar graphs

Se non si desidera modificare i dati che stai tramando, allora dovrete impostare gli attributi sul matplotlib assi direttamente, qualcosa di simile:

for ax, title in zip(g.axes.flat, ['zero', 'one']): 
    ax.set_title(title) 

Si noti che questo è meno preferibile al metodo precedente perché devi stare molto attento a verificare che l'ordine della tua lista sia corretto e che non cambierà, mentre ottenere le informazioni dal dataframe stesso sarà molto più robusto.

Per tracciare la media, è necessario creare una piccola funzione che può essere passata a FacetGrid.map. Ci sono multiple examples su come farlo nel tutorial.In questo caso, è abbastanza facile:

def vertical_mean_line(x, **kwargs): 
    plt.axvline(x.mean(), **kwargs) 

Poi tutto quello che serve è quello di ri-plot:

g = sns.FacetGrid(data=df, col='group') 
g.map(plt.hist, 'val', color='black', lw=0) 
g.map(vertical_mean_line, 'val') 
g.set_titles('{col_name}') 

some more bar graphs

+0

Ottima risposta. IMO il problema con i dati di codifica con le etichette che utilizzeresti per la visualizzazione è che preclude l'applicazione delle trasformazioni sui dati in seguito (senza ricodificare ripetutamente). Ad esempio, se volessi centrare e ridimensionare dovrei riconvertire quelle etichette in [0, 1]. Sperando di vedere un supporto migliore per l'etichettatura delle figure e l'annotazione in futuro. Sarebbe bello avere qualcosa di elegante e potente come ggplot2 per Python. –

+4

* Commento da [Coby Viner] (http://stackoverflow.com/users/5339699/): * Dovrebbe '{col_value}' essere stato '{col_name}' (in 'g.set_titles ('{col_value}')) 'frammento di codice '? Non sembra esserci alcun codice template '{col_value}'. –

+0

@erinshellman hai visto la libreria ggplot di yhat? http://ggplot.yhathq.com/docs/facet_grid.html –