matplotlib Seaborn:注解线性回归方程

tvokkenx  于 2023-06-06  发布在  其他
关注(0)|答案(4)|浏览(327)

我试着拟合波士顿数据集的OLS。我的图表看起来像下面。
如何在直线上方或图中的某个位置注解线性回归方程?如何在Python中打印公式?
我对这个领域相当陌生。探索Python到目前为止如果有人能帮助我,我的学习曲线会加快。
非常感谢!

我也试过这个。

我的问题是-如何在方程格式的图表中注解上面?

t98cgbkg

t98cgbkg1#

您可以使用线性拟合系数来制作图例,如下例所示:

import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats

tips = sns.load_dataset("tips")

# get coeffs of linear fit
slope, intercept, r_value, p_value, std_err = stats.linregress(tips['total_bill'],tips['tip'])

# use line_kws to set line label for legend
ax = sns.regplot(x="total_bill", y="tip", data=tips, color='b', 
 line_kws={'label':"y={0:.1f}x+{1:.1f}".format(slope,intercept)})

# plot legend
ax.legend()

plt.show()

如果使用更复杂的拟合函数,可以使用latex通知:https://matplotlib.org/users/usetex.html

wf82jlnq

wf82jlnq2#

要在使用seabornlmplot的情况下注解多元线性回归线,您可以执行以下操作。

import pandas as pd 
 import seaborn as sns
 import matplotlib.pyplot as plt 

df = pd.read_excel('data.xlsx')
# assume some random columns called EAV and PAV in your DataFrame 
# assume a third variable used for grouping called "Mammal" which will be used for color coding
p = sns.lmplot(x=EAV, y=PAV,
        data=df, hue='Mammal', 
        line_kws={'label':"Linear Reg"}, legend=True)

ax = p.axes[0, 0]
ax.legend()
leg = ax.get_legend()
L_labels = leg.get_texts()
# assuming you computed r_squared which is the coefficient of determination somewhere else
slope, intercept, r_value, p_value, std_err = stats.linregress(df['EAV'],df['PAV'])
label_line_1 = r'$y={0:.1f}x+{1:.1f}'.format(slope,intercept)
label_line_2 = r'$R^2:{0:.2f}$'.format(0.21) # as an exampple or whatever you want[!
L_labels[0].set_text(label_line_1)
L_labels[1].set_text(label_line_2)

结果:

2j4z5cfb

2j4z5cfb3#

更简单的语法..同样的结果。

import seaborn as sns
    import matplotlib.pyplot as plt
    from scipy import stats
        
    slope, intercept, r_value, pv, se = stats.linregress(df['alcohol'],df['magnesium'])
        
    sns.regplot(x="alcohol", y="magnesium", data=df, 
      ci=None, label="y={0:.1f}x+{1:.1f}".format(slope, intercept)).legend(loc="best")
s3fp2yjn

s3fp2yjn4#

我通过@RMS扩展了该解决方案,使其适用于多面板lmplot示例(使用pydataset中可用的sleep-deprivation studyBelenky et. al., J Sleep Res 2003)的数据)。这允许用户具有轴特定的图例/标签,而不必使用例如regplotplt.subplots

编辑:添加了第二个方法,使用FacetGrid()中的map_dataframe()方法,正如Marcos在这里的回答中所建议的那样。

import numpy as np
import scipy as sp
import pandas as pd
import seaborn as sns
import pydataset as pds
import matplotlib.pyplot as plt

# use seaborn theme
sns.set_theme(color_codes=True)

# Load data from sleep deprivation study (Belenky et al, J Sleep Res 2003)
#  ['Reaction', 'Days', 'Subject'] = [reaction time (ms), deprivation time, Subj. No.]
df = pds.data("sleepstudy")
# convert integer label to string
df['Subject'] = df['Subject'].apply(str)

# perform linear regressions outside of seaborn to get parameters
subjects = np.unique(df['Subject'].to_numpy())
fit_str = []
for s in subjects:
    ddf = df[df['Subject'] == s]
    m, b, r_value, p_value, std_err = \
        sp.stats.linregress(ddf['Days'],ddf['Reaction'])
    fs = f"y = {m:.2f} x + {b:.1f}"
    fit_str.append(fs)

method_one = False
method_two = True
if method_one:
    # Access legend on each axis to write equation
    #
    # Create 18 panel lmplot with seaborn
    g = sns.lmplot(x="Days", y="Reaction", col="Subject",
                   col_wrap=6, height=2.5, data=df,
                   line_kws={'label':"Linear Reg"}, legend=True)
    # write string with fit result into legend string of each axis
    axes = g.axes # 18 element list of axes objects
    i=0
    for ax in axes:
        ax.legend()  # create legend on axis
        leg = ax.get_legend()
        leg_labels = leg.get_texts()
        leg_labels[0].set_text(fit_str[i])
        i += 1
elif method_two:
    # use the .map_dataframe () method from FacetGrid() to annotate plot
    #  https://stackoverflow.com/questions/25579227 (answer by @Marcos)
    #
    # Create 18 panel lmplot with seaborn
    g = sns.lmplot(x="Days", y="Reaction", col="Subject",
                   col_wrap=6, height=2.5, data=df)
    def annotate(data, **kws):
        m, b, r_value, p_value, std_err = \
            sp.stats.linregress(data['Days'],data['Reaction'])
        ax = plt.gca()
        ax.text(0.5, 0.9, f"y = {m:.2f} x + {b:.1f}",
                horizontalalignment='center',
                verticalalignment='center',
                transform=ax.transAxes)
    g.map_dataframe(annotate)

# write figure to pdf
plt.savefig("sleepstudy_data_w-fits.pdf")

输出(方法一)

输出(方法二)

更新2022-05-11:与绘图技术无关,事实证明这种数据解释(以及例如在original R repository中提供的数据解释)是不正确的。参见reported issue here。拟合应在第2-9天进行,对应于0至7天的睡眠剥夺(每晚3小时睡眠)。前三个数据点对应于训练日和基线日(均为每晚8小时睡眠)。

相关问题