【问题标题】:How to use custom error bar in seaborn lineplot如何在 seaborn 线图中使用自定义误差线
【发布时间】:2022-01-17 00:54:07
【问题描述】:

我正在使用seaborn.lineplot 生成一些时间序列图。我在两个列表中预先计算了一种特定类型的误差线,例如upper=[1,2,3,4,5] lower=[0,1,2,3,4]。有没有办法可以在这里自定义错误栏,而不是在lineplot 中使用 CI 或 Std 错误栏?

【问题讨论】:

  • 仅供参考:彻底回答问题非常耗时。如果您的问题已解决,请通过接受最适合您的需求的解决方案表示感谢。✔ 位于答案左上角的 ▲/▼ 箭头下方。如果出现更好的解决方案,则可以接受新的解决方案。如果您的声望超过 15,您还可以使用 ▲/▼ 箭头对答案的有用性进行投票。 如果解决方案无法回答问题,请发表评论。 What should I do when someone answers my question?。谢谢。

标签: matplotlib data-visualization seaborn


【解决方案1】:

如果您想要seaborn.lineplot 提供的错误带/条,您必须自己绘制它们。下面是几个示例,说明如何在 matplotlib 中绘制误差带和误差条,并获得与 seaborn 中相似的绘图。它们是使用作为 pandas 数据框导入的 fmri 示例数据集构建的,并且基于 lineplot function 上的 seaborn 文档中显示的示例之一。

import numpy as np                 # v 1.19.2
import pandas as pd                # v 1.1.3
import matplotlib.pyplot as plt    # v 3.3.2
import seaborn as sns              # v 0.11.0

# Import dataset as a pandas dataframe
df = sns.load_dataset('fmri')

# display(df.head(3))
  subject  timepoint event    region    signal
0     s13         18  stim  parietal -0.017552
1      s5         14  stim  parietal -0.080883
2     s12         18  stim  parietal -0.081033

此数据集包含一个名为 timepoint 的时间变量,在 19 个时间点中的每一个时间点对 信号 进行了 56 次测量。我使用默认估计器,即平均值。为了简单起见,我没有使用平均值的标准误差的置信区间作为不确定性(又名误差)的度量,而是使用每个时间点的测量值的标准偏差。这是通过传递ci='sd'lineplot 中设置的,误差扩展到平均值每一侧的一个标准差(即对称)。下面是带有误差带的 seaborn 线图(默认情况下):

# Draw seaborn lineplot with error band based on the standard deviation
fig, ax = plt.subplots(figsize=(9,5))
sns.lineplot(data=df, x="timepoint", y="signal", ci='sd')
sns.despine()
plt.show()

现在假设我更希望有一个误差带,该误差带跨越平均值两侧每个时间点测量值的标准差的一半。由于在调用 lineplot 函数时无法设置此首选项,据我所知,最简单的解决方案是使用 matplotlib 从头开始​​创建绘图。

# Matplotlib plot with custom error band

# Define variables to plot
y_mean = df.groupby('timepoint').mean()['signal']
x = y_mean.index

# Compute upper and lower bounds using chosen uncertainty measure: here
# it is a fraction of the standard deviation of measurements at each
# time point based on the unbiased sample variance
y_std = df.groupby('timepoint').std()['signal']
error = 0.5*y_std
lower = y_mean - error
upper = y_mean + error

# Draw plot with error band and extra formatting to match seaborn style
fig, ax = plt.subplots(figsize=(9,5))
ax.plot(x, y_mean, label='signal mean')
ax.plot(x, lower, color='tab:blue', alpha=0.1)
ax.plot(x, upper, color='tab:blue', alpha=0.1)
ax.fill_between(x, lower, upper, alpha=0.2)
ax.set_xlabel('timepoint')
ax.set_ylabel('signal')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.show()

如果您更喜欢有误差线,这就是 seaborn 线图的样子:

# Draw seaborn lineplot with error bars based on the standard deviation
fig, ax = plt.subplots(figsize=(9,5))
sns.lineplot(data=df, x="timepoint", y="signal", ci='sd', err_style='bars')
sns.despine()
plt.show()

以下是如何使用自定义误差线获得与 matplotlib 相同类型的绘图:

# Matplotlib plot with custom error bars

# If for some reason you only have lists of the lower and upper bounds
# and not a list of the errors for each point, this seaborn function can
# come in handy:
# error = sns.utils.ci_to_errsize((lower, upper), y_mean)

# Draw plot with error bars and extra formatting to match seaborn style
fig, ax = plt.subplots(figsize=(9,5))
ax.errorbar(x, y_mean, error, color='tab:blue', ecolor='tab:blue')
ax.set_xlabel('timepoint')
ax.set_ylabel('signal')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.show()

# Note: in this example, y_mean and error are stored as pandas series
# so the same plot can be obtained using this pandas plotting function:
# y_mean.plot(yerr=error)

Matplotlib 文档:fill_betweenspecify error barssubsample error bars

熊猫文档:error bars

【讨论】:

    【解决方案2】:

    我可以通过在 lineplot 本身返回的轴上调用 fill_between 来实现这一点:

    from seaborn import lineplot
    
    ax = lineplot(data=dataset, x=dataset.index, y="mean", ci=None)
    ax.fill_between(dataset.index, dataset.lower, dataset.upper, alpha=0.2)
    

    生成的图像:

    作为参考,datasetpandas.DataFrame,看起来像:

                             lower       mean      upper
    timestamp                                           
    2022-01-14 12:00:00  55.575585  62.264151  68.516173
    2022-01-14 12:20:00  50.258980  57.368421  64.185814
    2022-01-14 12:40:00  49.839738  55.162242  60.369063
    

    【讨论】:

      【解决方案3】:

      是的,seaborn 只是在幕后使用 matplotlib,因此您基本上可以做任何您想做的事情,包括使用 matplotlib 的 plt.errorbar 添加您自己的自定义错误栏,或者如果您愿意,甚至可以创建自己的对象...

      话虽如此,您可能可以先尝试调整 seaborn 的选项。根据我的经验,它提供了非常广泛的自定义面板,并且具有生成非常整洁的视觉效果的优势。

      如果您对 seaborn 不满意但又不想深入了解 matplotlib API,另一个选择是使用 seaborn 创建错误栏,然后在您方便时对其进行调整(正如我所说,它们只是 matplotlib 对象)

      如果你提供一个更具体的例子,我可能会提供更多帮助

      【讨论】:

        猜你喜欢
        • 2015-08-03
        • 2019-03-16
        • 1970-01-01
        • 2021-02-23
        • 2021-11-19
        • 2022-01-01
        • 2019-06-01
        相关资源
        最近更新 更多