【问题标题】:Plot 95% confidence interval errorbar python pandas dataframes绘制 95% 置信区间误差线 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?

标签: python pandas matplotlib


【解决方案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% 置信区间的误差线。

    【讨论】:

    • 您发布的链接很有帮助。
    猜你喜欢
    • 2020-11-16
    • 1970-01-01
    • 2019-11-08
    • 2018-03-09
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 2021-07-05
    • 2021-12-01
    相关资源
    最近更新 更多