2016-07-27 97 views
1

我有一個數據幀熊貓其在下面示出一個片段: -繪製facetgrid在seaborn地塊與平滑

pandas dataframe 我希望重新創建Seaborn下面所示的曲線圖。這些圖是使用ggplot在R中創建的,但我正在使用pandas/matplotlib/seaborn。 ggplot graphs with smoothing

本質上,圖表總結了根據傳感器ID分組的變量(mi,steps,st ...),其中x軸上的事件數小時。此外,最重要的是,ggplot中的stat_smooth()會執行平滑操作。我已經包含了我的ggplot代碼片段。

step.plot <- ggplot(data=cdays, aes(x=dfc, y=steps, col=legid)) + 
    ggtitle('time to event' + 
    labs(x="Days from event", y='Number of steps') + 
    stat_smooth(method='loess', span=0.2, formula=y~x) + 
    geom_vline(mapping=aes(xintercept=0), color='blue') + 
    theme(legend.position="none") 

回答

2

這裏是我如何做到這一點。請記住,我必須對數據結構做出假設,因此請在應用之前查看我所做的事情。

創建一些模擬數據

subject = np.repeat(np.repeat([1, 2, 3, 4, 5], 4), 31) 
time = np.tile(np.repeat(np.arange(-15, 16, 1), 4), 5) 
sensor = np.tile([1, 2, 3, 4], 31*5) 
measure1 = subject*20 + time*(5-sensor) - time**2*(sensor-2)*0.1 + (time >= 0)*np.random.normal(100*(sensor-2), 10, 620) + np.random.normal(0, 10, 620) 
measure2 = subject*10 + time*(2-sensor) - time**2*(sensor-4)*0.1 + (time >= 0)*np.random.normal(50*(sensor-1), 10, 620) + np.random.normal(0, 8, 620) 
measure3 = time**2*(sensor-1)*0.1 + (time >= 0)*np.random.normal(50*(sensor-3), 10, 620) + np.random.normal(0, 8, 620) 
measure4 = time**2*(sensor-1)*0.1 + np.random.normal(0, 8, 620) 

把它在一個長表數據集繪製

df = pd.DataFrame(dict(subject=subject, time=time, sensor=sensor, measure1=measure1, 
         measure2=measure2, measure3=measure3, measure4=measure4)) 

df = pd.melt(df, id_vars=["sensor", "subject", "time"], 
      value_vars=["measure1", "measure2","measure3", "measure4"], 
      var_name="measure") 

創建的情節,不平滑

g = sns.FacetGrid(data=df, col="measure", col_wrap=2) 
g.map_dataframe(sns.tsplot, time="time", value="value", condition="sensor", unit="subject", color="deep") 
g.add_legend(title="Sensor Number") 
g.set_xlabels("Days from Event") 
g.set_titles("{col_name}") 
plt.show() 

Plotted data, before smoothing

繪製的數據,平滑

現在讓我們使用statsmodels平滑數據之前。

請檢查這個部分,這是我對取樣單元(我假設採樣單元是主題,因此將傳感器和測量類型作爲條件)進行假設的地方。

from statsmodels.nonparametric.smoothers_lowess import lowess 
dfs = [] 
for sens in df.sensor.unique(): 
    for meas in df.measure.unique(): 
     # One independent smoothing per Sensor/Measure condition. 
     df_filt = df.loc[(df.sensor == sens) & (df.measure == meas)] 
     # Frac is equivalent to span in R 
     filtered = lowess(df_filt.value, df_filt.time, frac=0.2) 
     df_filt["filteredvalue"] = filtered[:,1] 
     dfs.append(df_filt) 
df = pd.concat(dfs) 

Plotted data, after smoothing

繪製的數據,平滑

從那裏後,你可以調整你的情節,只要你喜歡。告訴我,如果你有任何問題。

+0

謝謝你的迴應,這就是我一直在尋找的。我重新創建了自己的步驟,並獲得了與您所展示的類似的數據框。但是,當試圖繪圖時,我得到錯誤ValueError:索引包含重複的條目,無法重塑這是它破壞的行: - plot.map_dataframe(sns.tsplot,time ='hrs_to_calving',value ='value',condition = 'sensor_id',unit ='subject',color ='deep') – xjackx

+0

這是因爲您的數據每個時間/條件/單位/度量必須有一個唯一的點。如果你有不止一個,tsplot在長整形你的數據時會遇到一個錯誤(IE每行一次/條件/單位/度量一行) – Andreq

+0

謝謝,這很有道理,爲了進一步解釋,我的主題的最後兩個字母是我有3種類型,即BL,BR和FL的sensor_ids。我在想,也許我需要爲每種類型的sensor_id找到每個時間的平均值,以實現我想要的。你介意看看我的數據框的csv轉儲,看看是否有另一種方式來實現這一目標?https://github.com/xjackx/Programming-Projects_Assignments/blob/master/jupyter%20notebooks/24hr_plotdata.csv – xjackx