Seaborn regplot fit line does not match calculated fit from stats.linregress or stats model

Viewed 524

I am trying to fit a xlog-linear regression. I used Seaborn regplot to plot the fit, which looks like a good fit (green line). Then, because regplot does not provide the coefficients. I used stats.linregress to find the coefficients. However, that plotted line (purple) does not match the fit from Seaborn regplot. I also used stats model to get the coefficients which matched the lineregress output. Is there a better way to get the coefficients that match the regplot line. I am unable to reproduce the Seaborn regplot line. I need the coefficients to report the fit for the model.

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

sns.regplot(x, y,x_bins=100, logx=True,n_boot=2000, scatter_kws={"color": "black"},
        ci=None,label='logfit',line_kws={"color": "green"})

#Find the coefficients slope and intercept
slope, intercept, r_value, pv, se = stats.linregress(y, np.log10(x))

yy= np.linspace(-.01, 0.05, 400)
xx = 10**(slope*yy+intercept)
plt.plot(xx,yy,marker='.',color='purple')

#Label Figure
plt.tick_params(labelsize=18)
plt.xlabel('insitu', fontsize=22)
plt.ylabel('CI', fontsize=22)

output from code shows lines do not overlay

I also used stats model for the fit and got the same results as stats.linregress for the coefficients. I'm unable to reproduce Seaborn regplot line.

 import statsmodels as sm
 import statsmodels.formula.api as smf

 results = smf.ols('np.log10(x) ~ (y)', data=df_data).fit()
 # Inspect the results
 print(results.summary())
1 Answers

There are two issues with your attempt to recreate what seaborn is doing:

  • you have the arguments to stats.linregress backwards
  • that's not how yhat is computed

Here's how you could recreate the seaborn logx regression line:

diamonds = sns.load_dataset("diamonds").sample(500, random_state=0)

x = diamonds["price"]
y = diamonds["carat"]

ax = sns.regplot(x=x, y=y, logx=True, line_kws=dict(color="g", lw=10))

fit = stats.linregress(np.log(x), y)
grid = np.linspace(x.min(), x.max())
ax.plot(grid, fit.intercept + fit.slope * np.log(grid), color="r", lw=5)

enter image description here

Related