Python 使用statsmodel(pandas/matplotlib)在散点图上绘制p值

Python 使用statsmodel(pandas/matplotlib)在散点图上绘制p值,python,pandas,matplotlib,statsmodels,p-value,Python,Pandas,Matplotlib,Statsmodels,P Value,我需要帮助将p值添加到我的数字中,但我有三个问题。1) 每当我使用statsmodel计算p值时,我会得到两个p值,一个用于“截距”,一个用于y变量(我要绘制的变量)。2) 我正在使用循环一次创建多个图形。3) 我不知道如何分离我要绘制的特定p值,因为当我打印p值时,它会为我准备的每个图形显示两个p值。这是我的代码,以防您想了解我对这两个p值的意思: ###(this is sample data in case you are trying to recreate the code) impo

我需要帮助将p值添加到我的数字中,但我有三个问题。1) 每当我使用
statsmodel
计算
p值
时,我会得到两个
p值
,一个用于“截距”,一个用于y变量(我要绘制的变量)。2) 我正在使用循环一次创建多个图形。3) 我不知道如何分离我要绘制的特定
p值
,因为当我打印p值时,它会为我准备的每个图形显示两个
p值
。这是我的代码,以防您想了解我对这两个
p值的意思:

###(this is sample data in case you are trying to recreate the code)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.formula.api as smf
import statsmodels.api as sm

dpm=pd.DataFrame({'pm10_3135_2018':[30,34,32,44,45,46,59,54,59,30],
'nox_3135(ppb)':[20,29,27,31,33,33,34,23,32,31],
'CO_3135(ppm)':[0.8,0.9,0.1,0.2,0.5,0.5,0.7,0.8,0.9,0.3],
'O3_mda8_3135':[42,45,47,51,52,52,57,67,69,70],
'pm25_3135_2018':[6,7,6,7,4,5,2,11,9,18]})

##PM2.5 vs variables - whole year

dpm = dpm.reset_index()

x = [dpm.pm10_3135_2018,dpm['nox_3135(ppb)'],dpm['CO_3135(ppm)'],dpm.O3_mda8_3135]
y = dpm.pm25_3135_2018
xlab = ["PM10 (ug/m^3)", "NOx (ppb)", "CO (ppm)", "O3 MDA8 (ppb)"]
fnames = ['NOMR2_PM10vsPM25_yr_2018.png','NOMR2_NOxvsPM25_yr_2018.png','NOMR2_COvsPM25_yr_2018.png','NOMR2_O3vsPM25_yr_2018.png']

for xcol,lab,fname in zip(x,xlab,fnames):

    correlation_matrix1 = np.corrcoef(xcol, y)
    correlation_xy1 = correlation_matrix1[0,1]
    R2_1 = correlation_xy1**2
    m, b = np.polyfit(xcol,y,1)
    equation = 'y = ' + str(round(m,4)) + 'x' ' + ' + str(round(b,4))
    R2 = '$R^2$ =' + str(round(R2_1,3))
    fig, ax = plt.subplots()
    ax.plot(xcol, y, color='xkcd:red',linestyle='None',marker='o')
    ax.set_xlabel(lab,fontsize=15)
    ax.set_ylabel('PM2.5 (ug/m^3)',fontsize=15)
    ax.set_ylim(0,)
    ax.set_xlim(0,)
    plt.text(0.75, 0.65, equation, horizontalalignment='center',
             verticalalignment='center',
             transform=ax.transAxes)
    plt.text(0.7, 0.6, R2, horizontalalignment='center',
         verticalalignment='center',
         transform=ax.transAxes)
    model = smf.ols('xcol ~ y', data=dpm).fit()
    print(model.summary())
    print(model.pvalues)
对于代码的下一部分,我有这个,但我需要一种方法,从
statsmodel
函数调用
y
变量
p-values
,并创建一个新变量
p
来表示那些
p-values
,然后在图上绘制
p
,但我不知道怎么做(免责声明,这不是我的实际数据,因此数据点之间没有太多相关性,但过程是相同的)。

plt.text(0.7, 0.55, P, horizontalalignment='center',
     verticalalignment='center',
     transform=ax.transAxes)

fig.tight_layout()
#plt.savefig(fname)

model.pvalues
是一个熊猫系列(即使用
type(model.pvalues)
进行检查,因此如果要提取
y
的p值,只需执行以下操作

model.pvalues['y']
要将p值添加到绘图中,可以添加:

print(model.pvalues)
plt.text(0.7, 0.8, "y p-values: %.2f" %(model.pvalues['y']), horizontalalignment='center',
     verticalalignment='center',
     transform=ax.transAxes)
在这里,我添加了一些文本格式
“y p-value..”
,以便更清楚地显示正在打印的内容

下面是完整的循环:

for xcol,lab,fname in zip(x,xlab,fnames):

    correlation_matrix1 = np.corrcoef(xcol, y)
    correlation_xy1 = correlation_matrix1[0,1]
    R2_1 = correlation_xy1**2
    m, b = np.polyfit(xcol,y,1)
    equation = 'y = ' + str(round(m,4)) + 'x' ' + ' + str(round(b,4))
    R2 = '$R^2$ =' + str(round(R2_1,3))
    fig, ax = plt.subplots()
    ax.plot(xcol, y, color='xkcd:red',linestyle='None',marker='o')
    ax.set_xlabel(lab,fontsize=15)
    ax.set_ylabel('PM2.5 (ug/m^3)',fontsize=15)
    ax.set_ylim(0,)
    ax.set_xlim(0,)
    plt.text(0.75, 0.65, equation, horizontalalignment='center',
             verticalalignment='center',
             transform=ax.transAxes)
    plt.text(0.7, 0.6, R2, horizontalalignment='center',
         verticalalignment='center',
         transform=ax.transAxes)
    model = smf.ols('xcol ~ y', data=dpm).fit()
    print(model.summary())
    print(model.pvalues)

    #added code:
    plt.text(0.7, 0.8, "y p-values: %.2f" %(model.pvalues['y']), horizontalalignment='center',
         verticalalignment='center',
         transform=ax.transAxes)
另外,如果我正确地解释了您的代码、注释和标准统计信息,那么您的公式应该是

model=smf.ols('y~xcol',data=dpm).fit()


在本例中,您希望提取x变量的p值,以便使用
model.pvalues[xcol]修改上述代码

这当然是主观的,但通常情况下,
y
是因变量,
x
是自变量,所以公式应该是
y~xcol
,由此你可以估算y=常数+bx+误差。我只想确保你估算的是你真正想要估算的。这有帮助吗:
p=model.pvalues['y']
然后
plt.text(0.7,0.55,P.)
?谢谢!还有一件事,这很有效,但p值大约有15个小数位,有没有办法将其压缩为仅绘制的3个小数位?这就是字符串格式方便的地方。您应该使用我在代码中提供的注释。要打印到3个小数位,您需要编写;
“p值:%.3f”%(model.pvalues['y']
。通常,如果要打印小数,最好使用字符串格式,即
print(“小数四舍五入到4位:%.4f”%.02212313)