2015-10-01 8 views
6

Oto mój wysiłek, aby wykreślić wykres pairgrid które używają kdeplot w dolnej części z 2 odcieniach:Seaborn pairgrid: using kdeplot 2 odcieniach

enter image description here

Mój skrypt brzmi:

import seaborn as sns 
g = sns.PairGrid(df2,hue='models') 
g.map_upper(plt.scatter) 
g.map_lower(sns.kdeplot) 
g.map_diag(sns.distplot) 

Czy istnieje u seaborn 0.6.0 sposób na użycie większej liczby skal kolorów w kdeplotu map_lower zgodnie z hue?

W tym przypadku odcień ma tylko 2 wartości. Może brakuje mi czegoś oczywistego.

+0

Będziesz potrzebować małej funkcji owijania dla 'kdeplot', aby zrozumiał parametr" kolor "w kontekście dwuwymiarowego wykresu i użył go do wybrania odpowiedniej mapy kolorów, np. używając 'sns.dark_palette'. Podam przykład później, kiedy mam czas, ale to może pomóc. – mwaskom

Odpowiedz

4

Będziesz musiał utworzyć własną funkcję fabuły wywoływaną przez PairGrid, z formularzem myplot (x, y, ** kws). kws zawiera pole "color" utworzone automatycznie przez PairGrid lub podane przez ciebie w argumencie Palette w PairGrid.

Aby kontrolować sposób wybierania mapy kolorów z palety kolorów, lepiej ustawić tę wartość ręcznie za pomocą słownika, który łączy wartości zmiennych przekazanych do odcienia z wybranymi kolorami.

Oto przykład tylko 4 kolorów: czerwonego, zielonego, niebieskiego i magenta. Prowadzi do map kolorów: Czerwoni, Zieloni, Blues i Purples.

wywnioskować cmap od koloru

def infer_cmap(color): 
    if color == (0., 0., 1.): 
     return 'Blues' 
    elif color == (0., 0.5, 0.): 
     return 'Greens' 
    elif color == (1., 0., 0.): 
     return 'Reds' 
    elif color == (0.75, 0., 0.75): 
     return 'Purples' 

dodać kolor odcień na działce kde

def kde_hue(x, y, **kws): 
    ax = plt.gca() 
    cmap = infer_cmap(kws['color']) 
    sns.kdeplot(data=x, data2=y, ax=ax, shade=True, shade_lowest=False, cmap=cmap, **kws) 
    return ax 

utworzyć PairGrid

colors = ['b', 'g', 'r', 'm'] 
var = 'models' 

color_dict = {} 
for idx, v in enumerate(np.unique(df2[var])): 
    color_dict[v] = colors[idx] 
g = sns.PairGrid(df2, hue=var, palette=color_dict) 
g = g.map_diag(sns.kdeplot) 
g = g.map_upper(plt.scatter) 
g = g.map_lower(kde_hue) 
g = g.add_legend() 
plt.show() 
plt.close() 
0

dostałem na to pytanie podczas próby użycia hue na kdeplot() lub distplot() który nie jest obsługiwany metr. Działa to

g = sns.FacetGrid(df_rtn, hue="group") 
g = g.map(sns.kdeplot, "variable") 
# or 
g = g.map(sns.distplot, "variable") 
0

Jak widać na przykładzie Marcina, funkcja otoki musi być stworzony, aby poinstruować sns.kdeplot na jaki kolor mapy do użycia. Oto podobny przykład, który powinien być łatwiejszy do zrozumienia:

# We will use seaborn 'Set1' color pallet 

>>> print(sns.color_palette('Set1')) 

[(0.89411765336990356, 0.10196078568696976, 0.10980392247438431), 
(0.21602460800432691, 0.49487120380588606, 0.71987698697576341), 
(0.30426760128900115, 0.68329106055054012, 0.29293349969620797), 
(0.60083047361934883, 0.30814303335021526, 0.63169552298153153), 
(1.0, 0.50591311045721465, 0.0031372549487095253), 
(0.99315647868549117, 0.9870049982678657, 0.19915417450315812)] 

Mapa kolorów przyjmuje kolor oparty na palecie. Domyślna paleta jest zielona - (0., 0., 1.) i niebieska - (0., 0.5, 0.). Jednakże używamy powyższej palety, która ma różne krotki RBG.

def infer_cmap(color): 
    hues = sns.color_palette('Set1') 
    if color == hues[0]: 
     return 'Reds' 
    elif color == hues[1]: 
     return 'Blues' 

def kde_color_plot(x, y, **kwargs): 
    cmap = infer_cmap(kwargs['color']) 
    ax = sns.kdeplot(x, y, shade=True, shade_lowest=False, cmap=cmap, **kwargs) 
    return ax 

g = sns.PairGrid(df, hue='left', vars=['satisfaction_level', 'last_evaluation'], palette='Set1') 
g = g.map_upper(plt.scatter, s=1, alpha=0.5) 
g = g.map_lower(kde_color_plot) 
g = g.map_diag(sns.kdeplot, shade=True); 

enter image description here

1

Myślę, że przy użyciu hue_kwds w PairGrid jest dużo easyer. Znalazłem ładne wyjaśnienie tutaj Plotting on data-aware grids, ponieważ doc w PairGrid nie jest dla mnie wystarczająco jasne.

Można również poinformować inne aspekty fabuły różnią się w poszczególnych poziomach zmiennej odcień , które mogą być pomocne przy tworzeniu wykresów, które będzie bardziej zrozumiały po wydrukowaniu w biały czarno-.Aby to zrobić, należy przekazać słownik do hue_kws, gdzie klucze są nazwami funkcji drukowania, a wartości są listami wartości słów kluczowych, po jednym dla każdego poziomu zmiennej hue.

Zasadniczo, hue_kws jest dyktowaniem list. Słowo kluczowe jest przekazywane do pojedynczych funkcji drukowania z wartościami z ich listy, po jednym dla każdego poziomu zmiennej hue. Zobacz przykład kodu poniżej.

Używam kolumn liczbowych dla odcienia w mojej analizie, ale powinno również działać tutaj. Jeśli nie, możesz łatwo odwzorować każdą unikalną wartość "modeli" na liczbę całkowitą.

Kradzież z miłą odpowiedź od Martin Perez chciałbym zrobić coś takiego:

EDIT: kompletny przykładowy kod

EDIT 2: Okazało się, że kdeplot nie gra dobrze z etykiet numerycznych. Odpowiednio zmieniając kod.

# generate data: sorry, I'm lazy and sklearn make it easy. 
n = 1000 
from sklearn.datasets.samples_generator import make_blobs 
X, y = make_blobs(n_samples=n, centers=3, n_features=3,random_state=0) 

df2 = pd.DataFrame(data=np.hstack([X,y[np.newaxis].T]),columns=['X','Y','Z','model']) 
# distplot has a problem witht the color being a number!!! 
df2['model'] = df2['model'].map('model_{}'.format) 

list_of_cmaps=['Blues','Greens','Reds','Purples'] 
g = sns.PairGrid(df2,hue='model', 
     # this is only if you use numerical hue col 
#  vars=[i for i in df2.columns if 'm' not in i], 
    # the first hue value vill get cmap='Blues' 
    # the first hue value vill get cmap='Greens' 
    # and so on 
    hue_kws={"cmap":list_of_cmaps}, 
    ) 
g.map_upper(plt.scatter) 
g.map_lower(sns.kdeplot,shade=True, shade_lowest=False) 
g.map_diag(sns.distplot) 
# g.map_diag(plt.hist) 
g.add_legend() 

enter image description here

Sortowanie list_of_cmaps powinieneś być w stanie przypisać konkretny odcień do określonego poziomu zmiennej kategorycznego.

Uaktualnienie polegałoby na dynamicznym utworzeniu list_of_cmaps w zależności od wymaganej liczby poziomów.