2016-03-23 35 views
2

私の目的は、海底:sns.lmplotcol=またはrow=に分割して作成したプロットで、y = 0に水平な赤線を描くことです。あなたの助けのためのSeabornで散布線を描く

enter image description here

おかげで、

EDITを:私たちは、プロットの配列の最後のプロットは、赤線でマークされていることを見ることができます

import numpy as np, seaborn as sns, pandas as pd 
np.random.seed(5) 

myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100),\ 
'z' : ['a','b']*50, 'w':np.random.poisson(0.15,100)}) 


sns.lmplot("x", "y", col="z", row="w", data=myData, fit_reg=False) 
plt.plot(np.linspace(-20,120,1000), [0]*1000, 'r-') 

は、col=および/またはrow=を使用してプロットの配列を生成し、各プロットでその線をトレースしたい場合の問題を説明しました。

答えて

4

だから、このコードの塊は、私たちがcol=を使用する一般的なケースのために働くrow=、およびhue=

import numpy as np, seaborn as sns, pandas as pd 
np.random.seed(5) 

myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100),\ 
'z' : ['a','b']*50, 'w':np.random.poisson(0.15,100), 'hueMe':['q','w','e','r','t']*20}) 

myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5) 
myPlot = myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15)) 
myPlot = myPlot.map_dataframe(plt.plot, [-20,120], [0,0], 'r-').add_legend().set_axis_labels("x", "y") 
plt.show() 

enter image description here

水平線の色は、個々のプロットに使用された最後の色として出てくる理由はわからないが、私は今のところ:)これにあきらめ

1

Seabornは実際にはmatplotlibのインターフェイスなので、標準のmatplotlib関数もすべて使用できます。海賊プロットをインポートして、私のために赤い水平線をプロットした後、pyplotをインポートします。

import numpy as np, seaborn as sns, pandas as pd 
import matplotlib.pyplt as plt 
np.random.seed(5) 

myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100)}) 

sns.lmplot("x", "y", data=myData, line_kws={'xdata': '0,1','ydata': '0,0','color': 'k', 'linestyle':'-', 'linewidth':'5'}, fit_reg=False) 
plt.plot(np.linspace(-20,120,1000), [0]*1000, 'r') 

私のイメージはここにある - http://i.imgur.com/J7Lvt52.png

+1

ありがとうございましたTim、それは私たちが1つのプロットを持っている場合に適しています。しかし、 'sns'から' col = 'と' row = 'というパラメータを使ってデータを分割するとどうなりますか? (元の質問の編集をご覧ください) –

3

私が来たので、これは答えを探して、ここで私が最終的に発見したより一般的な答えです:

map_dataframeは、ユーザー定義の関数を受け入れる(そしてこの関数にデータフレームを渡します)あなたがファセットグリッドに何かを描くことができるからです。 OPケースの場合:

def plot_hline(y,**kwargs): 
    data = kwargs.pop("data") #get the data frame from the kwargs 
    plt.axhline(y=y, c='red',linestyle='dashed',zorder=-1) #zorder places the line underneath the other points 

myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5) 
myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15)) 
myPlot.map_dataframe(plot_hline,y=0) 
plt.show() 

私の問題は、各ファセットに異なる水平線が必要だったので、少し複雑でした。

私の場合を複製するには、 'z'変数に2つのサンプル(aとb)があり、それぞれ観測値 'obs'(これは以下のmyDataに追加しました)を持っているとします。 'hueMe'は、各サンプルのモデル化された値を表します。

myData = pd.DataFrame({'x' : np.arange(1, 101), 
         'y': np.random.normal(0, 4, 100), 
         'z' : ['a','b']*50, 
         'w':np.random.poisson(0.15,100), 
         'hueMe':['q','w','e','r','t']*20, 
         'obs':[3,2]*50}) 

あなたはplot_hlineにデータフレームを渡すときは、axhlineだけyのために単一の値を取ることができますので、それぞれの「Z」のサンプルのための「OBS」が重複する値をドロップする必要があります。 (私たちの場合、各サンプルには1つの観測値 'obs'がありますが、複数のモデル化された 'hueMe'値があります)。さらに、yはスカラーでなければなりません(シリーズではありません)ので、値自体を抽出するためにデータフレームにインデックスを付ける必要があります。

def plot_hline(y,z, **kwargs): 
    data = kwargs.pop("data") #the data passed in through kwargs is a subset of the original data - only the subset for the row and col being plotted. it's a for loop in disguise. 
    data = data.drop_duplicates([z]) #drop the duplicate rows 
    yval = data[y].iloc[0] #extract the value for your hline. 
    plt.axhline(y=yval, c='red',linestyle='dashed',zorder=-1) 


myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5) 
myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15)) 
myPlot.map_dataframe(plot_hline,y='obs',z='z') 
plt.show() 

resulting plot

今seabornはFacetGridの各ファセットに、あなたの関数からの出力をマップします。注:axhlineとは異なるプロット関数を使用している場合、系列から値を抽出する必要はない場合があります。

これが誰かを助けることを願っています!