2016-11-27 4 views
0

Seabornのlmplotのスキャッタポイントの色に第3の変数をマップしようとしています。したがって、x上のtotal_bill,tip上のyおよび点の色は、sizeの関数である。Seabornのlmplotでファセットに異なる散乱kwargsを渡す方法

ファセットが有効になっていないときに機能しますが、カラー配列のサイズが各ファセットにプロットされたデータのサイズと一致しないため、colを使用すると失敗します。

これは、上記の私のコード

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) 

でうまく機能して(画像を含めることが許さまだ、ので、ここでは、リンクのない)以下を生成します:ときに私、

lmplot with point colour as function of size

しかし、 col='sex'をlmplot(以下のコードを試してください)に追加すると、カラー配列のデータセットのサイズが各ファセットにプロットされたデータのサイズよりも大きくなるという問題があります。したがって、例えばcol='male'には157のデータポイントがあるので、カラー配列からの最初の157の値はポイントにマッピングされます(そしてこれらも正しいものではありません)。下記参照:

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) 

理想的には、私は各ファセットが(私はlmplotに渡す前に計算するだろう)正しい色のアレイを使用するようにlmplotにscatter_kwsの配列を渡したいです。しかし、それはオプションではないようです。原則として

まだ私がFacetGridから再作成lmplot機能に頼ることなく、Seabornのlmplot(意味の機能を使用できるようにする他のアイデアや回避策?

+0

私は完全にあなたが達成しようとしているのかを理解していません。おそらく、データフレームのどの列をどのタイプの視覚化に使用すべきかを明示して、質問を更新すると助けになるかもしれません。 – ImportanceOfBeingErnest

+0

明瞭にするために編集されました。ありがとう:) – pistachio

+0

'scatter_kws 'は(おそらく)異なるポイント数を持つ両方の散布図に同時に渡されるので、あなたが求めているものは簡単には可能ではないと思います。あなたが必要とする 'lmplot'の機能は何ですか? – ImportanceOfBeingErnest

答えて

0

は異なるcolslmplotがちょうどAのようですいくつかのregplot sのためのラッパー。だから、代わりに1 lmplot我々は2 regplots、各sexのための1つを使用することができます。

従って、我々はmale Aに元データフレームを分離する必要がありますnd female、残りはかなり単純です。

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

ありがとうございます。それは私には起こりませんでした。それは本当に良い回避策です – pistachio

関連する問題