2016-11-27 2 views
0

Ich versuche, eine 3. Variable der Streupunktfarbe im Seaborn lmplot zuzuordnen. Also total_bill auf x, tip auf y und Punktfarbe als Funktion von size.Wie man verschiedene Scatter-Kwarts an Facetten in lmplot in Seaborn übergibt

Es funktioniert, wenn kein Facetting aktiviert ist, schlägt jedoch fehl, wenn col verwendet wird, da die Größe des Farbarrays nicht mit der Größe der Daten übereinstimmt, die in jeder Facette gezeichnet werden.

Dies ist mein Code

import matplotlib as mpl 
    import seaborn as sns 
    sns.set(color_codes=True) 

    # load data 
    data = sns.load_dataset("tips") 

    # size of data 
    print len(data.index) 

    ### we want to plot scatter point colour as function of variable 'size' 

    # first, sort the data by 'size' so that high 'size' values are plotted 
    # over the smaller sizes (so they are more visible) 

    data = data.sort_values(by=['size'], ascending=True) 

    scatter_kws = dict() 
    cmap = mpl.cm.get_cmap(name='Blues') 

    # normalise 'size' variable as float range needs to be 
    # between 0 and 1 to map to a valid colour 
    scatter_kws['c'] = data['size']/data['size'].max() 

    # map normalised values to colours 
    scatter_kws['c'] = cmap(scatter_kws['c'].values) 

    # colour array has same size as data 
    print len(scatter_kws['c']) 

    # this works as intended 
    g = sns.lmplot(data=data, x="total_bill", y="tip", scatter_kws=scatter_kws) 

Die deutlich über Werke und produziert die folgenden (nicht erlaubt Bilder enthalten noch hier so ist der Link):

lmplot with point colour as function of size

Allerdings, wenn ich fügen Sie col='sex' zu lmplot (versuchen Sie Code unten), das Problem ist, dass das Farbfeld die Größe des ursprünglichen Datasets hat, die größer ist als die Größe der Daten in jeder Facette aufgetragen. So hat beispielsweise col='male' 157 Datenpunkte, also werden zuerst 157 Werte aus dem Farbfeld den Punkten zugeordnet (und diese sind nicht einmal die richtigen). Siehe unten:

lmplot with point colour as function of size with col=sex

g = sns.lmplot(data=data, x="total_bill", y="tip", col="sex", scatter_kws=scatter_kws) 

Im Idealfall würde Ich mag ein Array von scatter_kws zum lmplot passieren, so daß jede Facette der richtige Farbe Array verwendet (was ich berechnen würde, bevor lmplot vorbei) . Aber das scheint keine Option zu sein.

Jede andere Ideen oder Abhilfen, die mich immer noch erlauben, die Funktionalität von Seaborn der lmplot (Bedeutung zu verwenden, ohne Rückgriff lmplot Funktionalität von FacetGrid?

+0

ich nicht ganz verstehen, was Sie versuchen zu erreichen. Vielleicht würde es hilfreich sein, wenn Sie die Frage aktualisieren und klar angeben, welche Spalten des Datenrahmens für welche Art von Visualisierung verwendet werden sollen. – ImportanceOfBeingErnest

+0

Editiert für Klarheit. Danke :) – pistachio

+0

Ich denke nicht, wonach du fragst, ist leicht möglich, da die "scatter_kws" gleichzeitig auf beide Streudiagramme übertragen werden, die eine (möglicherweise) unterschiedliche Anzahl von Punkten haben. Was genau ist die Funktionalität von "lmplot", die Sie brauchen? – ImportanceOfBeingErnest

Antwort

0

Im Prinzip ist die lmplot mit unterschiedlichen cols neu zu erstellen scheint nur zu sein, Wrapper für mehr regplot s. Also statt einem lmplot wir regplots zwei nutzen könnten, ein für jeden sex.

wir müssen daher den ursprünglichen Datenrahmen in male trennen eine nd female, der Rest ist eher geradlinig.

import matplotlib.pyplot as plt 
import seaborn as sns 

data = sns.load_dataset("tips") 

data = data.sort_values(by=['size'], ascending=True) 
# make a new dataframe for males and females 
male = data[data["sex"] == "Male"] 
female = data[data["sex"] == "Female"] 

# get normalized colors for all data 
colors = data['size'].values/float(data['size'].max()) 
# get colors for males/females 
colors_male = colors[data["sex"].values == "Male"] 
colors_female = colors[data["sex"].values == "Female"] 
# colors are values in [0,1] range 


fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(9,4)) 

#create regplot for males, put it to left axes 
#use colors_male to color the points with Blues cmap 
sns.regplot(data=male, x="total_bill", y="tip", ax=ax1, 
      scatter_kws= {"c" : colors_male, "cmap":"Blues"}) 
# same for females 
sns.regplot(data=female, x="total_bill", y="tip", ax=ax2, 
      scatter_kws={"c" : colors_female, "cmap":"Greens"}) 
ax1.set_title("Males") 
ax2.set_title("Females") 
for ax in [ax1, ax2]: 
    ax.set_xlim([0,60]) 
    ax.set_ylim([0,12]) 
plt.tight_layout() 
plt.show() 

enter image description here

+0

Danke. Das ist mir nicht in den Sinn gekommen und es ist ein wirklich guter Workaround – pistachio

Verwandte Themen