绘制Seaborn实验的多个记录的统计信息

时间:2019-01-05 19:43:30

标签: python pandas plot seaborn

我有一个随机算法,可以重复几次,因此可以进行统计评估。来自实验的数据帧可以分组以计算平均值和中位数。

现在,我想用Seaborn绘制原始信息以及我也计算出的统计数据。所以我最多有100个数据框架,像这样的数据。

module, coverage, timestamp
examples.monkey, 32.142857142857146, 1546513589.59586
examples.monkey, 35.714285714285715, 1546513589.609822
examples.monkey, 35.714285714285715, 1546513589.617172
...
util.container, 27.586206896551722 ,1546513594.559889
util.container, 27.586206896551722 ,1546513594.579989
util.container, 27.586206896551722 ,1546513594.598491

我可以简单地使用线图打印多个时间序列,如下所示。

sns.set(style="darkgrid")
for df in dfs:
    min_timestamp = df['timestamp'].min()
    df["time"] = df["timestamp"] - min_timestamp

keys = ["Run " + str(i) for i in range(len(dfs))]
glued = pd.concat(dfs, keys=keys).reset_index(level=0).rename(columns={'level_0': 'run'})
ax = sns.lineplot(hue="module", x="time", y="coverage", ci="sd", units="run", estimator=None, data=glued)
plt.show()

这将导致如下图所示:Plot from different algorithm runs

然后我可以计算平均值并将其添加到图中,如下所示:

sns.set(style="darkgrid")
for df in dfs:
    min_timestamp = df['timestamp'].min()
    df["time"] = df["timestamp"] - min_timestamp

keys = ["Run " + str(i) for i in range(len(dfs))]
glued = pd.concat(dfs, keys=keys).reset_index(level=0).rename(columns={'level_0': 'Run'})
sns.lineplot(hue="module", x="time", y="coverage", ci="sd", units="Run", estimator=None, data=glued)

means = glued.groupby(by=["module", "time"], as_index=False).mean()
means["run"] = "Mean"
sns.lineplot(hue="module", x="time", y="coverage", estimator="mean", palette=sns.xkcd_palette(["red", "black"]),  err_style="band", data=means)

plt.show()

但是,由此产生的情节是毫无用处的。看起来像这样。

Plot from different algorithm runs with mean

我更希望对seaborn的示例感兴趣,在这些示例中,我的测量结果打印为一个区域,均值清晰可见。 Seaborn examples

现在,我怀疑我得到了这张丑陋的图像,因为具有均值的数据框具有更多的数据点。该算法以随机间隔进行测量,因此时间戳在大多数时间不会重叠。由于测量值之间的距离非常近,并且在它们之间画了一条线,因此我们可以看到宽笔画的图片。

我现在的具体问题是,线图在这里是否还有意义,并且如果是正确的方法,请事先自己计算平均值? 如果方法正确,那么我该如何解决?如果不正确,您还要使用什么?

如果您想尝试的话,我还在此处将一些示例结果作为csv文件上传:1 2 3 4 5

1 个答案:

答案 0 :(得分:1)

我不确定您在第二个示例中是否正确使用了lineplot。重点是让Seaborn为您计算统计数据并绘制图形估计量±ci。我看不出要在数据框中计算平均值,然后让seaborn绘制数据框平均值的意义。

但是无论如何,您的问题是seaborn仅聚合具有完全相同的x值的y值。来自the documentation

  

默认情况下,该图在每个值上的多个y值上聚合   x并显示对集中趋势的估计和置信度   该估算的时间间隔。

正如您正确猜测的那样,您的值过于随机且很少重叠,这意味着seaborn无法计算有意义的均值。我认为,解决方案是降低测量的时间分辨率,以使在(假设)0.1个时间单位的时间内进行的所有测量都具有相同的时间值,这将使Seaborn将它们平均在一起。

glued["roundtime"] = glued["time"].round(1)  # 1 significant digit
ax = sns.lineplot(hue="module", x="roundtime", y="coverage", ci="sd", estimator='mean', data=glued)

enter image description here