Python Pandas数据框绘制95%置信区间误差线图

11

我想用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,因为两个标准差大约是95%,或者使用pandas quantile方法计算0.025和0.975分位数。 - MaxNoe
@MaxNoe 我应该如何使用2*std? - user7040867
3个回答

20

使用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()

结果:

result

使用百分位数

如果你的分布是偏斜的,最好使用不对称的误差条,并从百分位数中获取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开始索引。 - mirgee
2
正态分布的95%置信区间不是95%置信水平下的均值标准误差(SEM)吗?即约为2 sigma/根号N,其中N是样本数量。我从未将2sigma绘制为95% CI。显然,这不是这篇文章的主题,但我觉得推荐将2 sigma作为误差线绘制很奇怪。 - n3rd
2
我认为你在这里混淆了几件事情。对于正态分布的任何值,95%置信区间就是那个区间,在其中95%的值落在其中。你似乎混淆了从样本计算出的均值的95%置信区间。 - MaxNoe

8
正态分布中,约95%的值在距离平均值4个标准差的窗口内,换句话说,95%的值在距离平均值正负2个标准差之内。例如,请参见68-95-99.7法则plt.errorbaryerr参数指定单侧误差棒的长度。因此,取
plt.errorbar(x,y,yerr=2*std)

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


你发布的链接帮了很大的忙。 - GoingMyWay

1
要获得95%的置信区间,您需要定义一个函数。
微调:从样本数据计算置信区间
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)

最后使用你选择的库进行绘图,例如:plotly。
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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接