2015-07-26 13 views
8

Próbuję dostosować niektóre figury z modułem Seaborn w Pythonie, ale nie miałem szczęścia tworzenia niestandardowych etykiet i adnotacji. Mam niektóre kodu, który generuje następujący rysunek:Dostosowywanie adnotacji z FacetGrid 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

chciałbym zrobić dwie rzeczy: 1. Wymień etykiety czynników, na przykład domyślne "bot = 0,0", z tekstem znaczącym i 2. narysuj linie pionowe o średniej następującej po każdej kategorii.

Oto samowystarczalny przykład:

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) 

Ktoś wie jak dostosować FacetGrids?

+0

Zapoznaj się z 'metoda FacetGrid.set_titles'. – mwaskom

+1

Tak, próbowałem, ale nic nie renderuje. Jakieś myśli na temat tworzenia pionowych linii w różnych punktach na każdym? –

+2

Nie jestem pewien, co oznacza "nic nie renderuje". Jeśli próbowałeś rzeczy i nie działałeś, powinieneś dodać to samo. Znacznie łatwiej jest ci pomóc, gdy Twoje pytanie zawiera samodzielny przykład, na którym można kopiować i wklejać. Być może możesz użyć jednego z przykładowych zbiorów danych seaborn, które są używane w samouczku. – mwaskom

Odpowiedz

12

Kilka rzeczy o set_titles.

pierwsze tytuły domyślne są rysowane w sposób FacetGrid.map, więc jeśli chcesz zmienić tytuły, trzeba zadzwonić set_titlespo kreślenia, albo zostaną one nadpisane.

Po drugie, jeśli spojrzysz na docstring dla metody, nie bierze ona tylko arbitralnej listy tytułów. Jest to sposób, aby zmienić sposób tytuł wydanego przy użyciu nazwy zmiennej i wartość kolumna:

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). 

więc najprostszym sposobem, aby mieć „znaczący tekst” jest użycie znaczących danych w dataframe. Weźmy ten przykład z losowych danych:

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

Jeśli chcesz „grupa” będzie zero i one, należy po prostu zmienić tę kolumnę, albo zrobić nowe:

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

Wtedy powiedzieć don „t chcą mieć nazwę zmiennej w tytule właściwy sposób wykorzystywać FacetGrid.set_titles byłoby

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

some bar graphs

Jeśli nie chcesz zmienić dane masz kreślenia, następnie trzeba będzie ustawić atrybuty na matplotlib osiach bezpośrednio, coś takiego:

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

pamiętać, że jest mniej korzystne do powyższej metody, ponieważ trzeba być bardzo ostrożnym w upewnianiu się, że kolejność na liście jest poprawna i że nie ulegnie ona zmianie, natomiast uzyskanie informacji z samej ramki danych będzie znacznie bardziej niezawodne.

Aby narysować średnią, musisz utworzyć małą funkcję, którą można przekazać do FacetGrid.map. Jest multiple examples, jak to zrobić w samouczku.W tym przypadku jest to dość proste:

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

Wtedy wszystko, co potrzebne jest do ponownego działki:

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

Świetna odpowiedź. IMO kłopot z kodowaniem danych za pomocą etykiet, których używasz do wizualizacji, polega na tym, że uniemożliwia to późniejszą transformację danych (bez wielokrotnego ponownego kodowania). Na przykład, jeśli chciałbym wyśrodkować i skalować, musiałbym zamienić te etykiety z powrotem na [0, 1]. Mając nadzieję na lepsze wsparcie dla etykietowania postaci i adnotacji w przyszłości. Byłoby wspaniale mieć coś eleganckiego i potężnego, jak ggplot2 dla Pythona. –

+4

* Komentarz od [Coby Viner] (http://stackoverflow.com/users/5339699/): * Powinien mieć wartość '{col_value}' '{col_name}' (w 'g.set_titles ('{col_value}')) 'fragment kodu)? Nie istnieje żaden kod szablonu "{col_value}". –

+0

@erinshellman widziałeś już bibliotekę ghplota? http://ggplot.yhathq.com/docs/facet_grid.html –