绘制seaborn中的facetgrid图并进行平滑处理

时间:2016-07-27 09:09:56

标签: pandas matplotlib ggplot2 seaborn facet

我有一个pandas数据帧,其片段如下所示: -

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")

1 个答案:

答案 0 :(得分:3)

这是我将如何做到这一点。请记住,我必须对数据的结构做出假设,因此请在应用之前查看我所做的事情。

创建一些模拟数据

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

平滑后绘制的数据

从那里你可以根据自己的需要调整你的情节。如果您有任何疑问,请告诉我。