绘制 95% 置信区间误差线 python pandas dataframes

Posted

技术标签:

【中文标题】绘制 95% 置信区间误差线 python pandas dataframes【英文标题】:Plot 95% confidence interval errorbar python pandas dataframes 【发布时间】:2017-11-20 01:54:04 【问题描述】:

我想用 Python pandas、matpolib 显示 95% 的置信区间... 但我卡住了,因为通常.std() 我会这样做:

import pandas as pd
import numpy as np

import matplotlib

matplotlib.use('Agg')

import matplotlib.pyplot as plt
import math

data = pd.read_table('output.txt',sep=r'\,', engine='python')
Ox = data.groupby(['Ox'])['Ox'].mean()
Oy = data.groupby(['Ox'])['Oy'].mean()
std = data.groupby(['Ox'])['Oy'].std()

plt.plot(Ox, Oy , label = 'STA = '+ str(x))
plt.errorbar(Ox, Oy, std, label = 'errorbar', linewidth=2)

plt.legend(loc='best', prop='size':9.2)

plt.savefig('plot.pdf')
plt.close()

但是我在 pandas 方法中没有找到可以帮助我的东西。有人知道吗?

【问题讨论】:

你可以使用 2*std,因为两个 simga 大约是 95% 或者使用 pandas 分位数方法来计算 0.025 和 0.975 分位数。 @MaxNoe 我应该如何使用 2*std? 【参考方案1】:

要获得 95% 的置信区间,您需要定义一个函数。

调整:Compute a confidence interval from sample data

def mean_confidence_interval(data, confidence=0.95):
    a = 1.0 * np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * scipy.stats.t.ppf((1 + confidence) / 2., n-1)
    return m

def bound_confidence_interval(data, confidence=0.95):
    a = 1.0 * np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * scipy.stats.t.ppf((1 + confidence) / 2., n-1)
    return h

然后定义:

mean = df.groupby(by='yourquery').agg(mean_confidence_interval)
bound = df.groupby(by='yourquery').agg(bound_confidence_interval)

最后使用您选择的库进行绘图:例如巧妙地

import plotly.graph_objects as go

   fig = go.Figure(data=go.Scatter(
        x=mean[yourquery],
        y=mean[yourquery2],
        error_y=dict(
            type='data', # value of error bar given in data coordinates
            array=bound[yourquery2],
            visible=True)
    ))
    fig.show()

【讨论】:

【参考方案2】:

使用 2 * std 估计 95 % 区间

在正态分布中,区间 [μ - 2σ, μ + 2σ] 覆盖 95.5 %,所以 您可以使用 2 * std 来估计 95 % 的间隔:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame()
df['category'] = np.random.choice(np.arange(10), 1000, replace=True)
df['number'] = np.random.normal(df['category'], 1)

mean = df.groupby('category')['number'].mean()
std = df.groupby('category')['number'].std()

plt.errorbar(mean.index, mean, xerr=0.5, yerr=2*std, linestyle='')
plt.show()

结果:

使用百分位数

如果您的分布有偏差,最好使用非对称误差线并从百分位数获得 95% 的区间。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import skewnorm

df = pd.DataFrame()
df['category'] = np.random.choice(np.arange(10), 1000, replace=True)
df['number'] = skewnorm.rvs(5, df['category'], 1)

mean = df.groupby('category')['number'].mean()
p025 = df.groupby('category')['number'].quantile(0.025)
p975 = df.groupby('category')['number'].quantile(0.975)

plt.errorbar(
    mean.index,
    mean,
    xerr=0.5,
    yerr=[mean - p025, p975 - mean],
    linestyle='',
)
plt.show()

结果:

【讨论】:

请注意,在 0.19.2 中,由于某种原因,yerr 必须从 0 开始索引。 正态分布的 95% 置信区间不是 95% 置信度的均值标准误 (SEM) 吗?即 ~ 2 sigma/root(N) 其中 n 是样本数。我从不将 2sigma 绘制为 95% CI。显然,这不是这篇文章的内容,但我觉得建议将 2 sigma 绘制为误差线很奇怪。 我认为您在这里混淆了几件事。正态分布的任何值的 95% 置信区间就是 95% 值落在其中的区间。您似乎与从样本计算的平均值的 95 % 置信区间混为一谈。【参考方案3】:

对于正态分布,约 95% 的值位于平均值周围 4 个标准差的窗口内,换句话说,95% 的值在平均值的正/负 2 个标准差范围内。见,例如68–95–99.7-rule.

plt.errorbaryerr 参数指定单面误差条的长度。从而采取

plt.errorbar(x,y,yerr=2*std)

其中std 是标准差,显示 95% 置信区间的误差线。

【讨论】:

您发布的链接很有帮助。

以上是关于绘制 95% 置信区间误差线 python pandas dataframes的主要内容,如果未能解决你的问题,请参考以下文章

绘制 lm 对象的 95% 置信区间

使用绘图子图时绘制自定义误差线

在 R 中以 95% 的置信区间绘制密度图

Python 绘制线性回归散点图和置信区间线

Python 绘制线性回归散点图和置信区间线

Python 绘制线性回归散点图和置信区间线