Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use `lmplot` to plot linear regression without intercept?

Tags:

The lmplot in seaborn fit regression models with intercept. However, sometimes I want to fit regression models without intercept, i.e. regression through the origin.

For example:

In [1]: import numpy as np    ...: import pandas as pd    ...: import seaborn as sns    ...: import matplotlib.pyplot as plt    ...: import statsmodels.formula.api as sfa    ...:   In [2]: %matplotlib inline In [3]: np.random.seed(2016) In [4]: x = np.linspace(0, 10, 32) In [5]: y = 0.3 * x + np.random.randn(len(x)) In [6]: df = pd.DataFrame({'x': x, 'y': y}) In [7]: r = sfa.ols('y ~ x + 0', data=df).fit() In [8]: sns.lmplot(x='x', y='y', data=df, fit_reg=True) Out[8]: <seaborn.axisgrid.FacetGrid at 0xac88a20> 

enter image description here

The figure what I wanted:

In [9]: fig, ax = plt.subplots(figsize=(5, 5))    ...: ax.scatter(x=x, y=y)    ...: ax.plot(x, r.fittedvalues)    ...:  Out[9]: [<matplotlib.lines.Line2D at 0x5675a20>] 

enter image description here

like image 860
Eastsun Avatar asked Jan 11 '16 15:01

Eastsun


People also ask

How do you plot a regression line in Seaborn?

Regression plots in seaborn can be easily implemented with the help of the lmplot() function. lmplot() can be understood as a function that basically creates a linear model plot. lmplot() makes a very simple linear regression plot.It creates a scatter plot with a linear fit on top of it.

How do you change the intercept to zero in a linear regression in Python?

Typically, you'd use numpy. polyfit to fit a line to your data, but in this case you'll need to do use numpy. linalg. lstsq directly, as you want to set the intercept to zero.

What is the difference between Regplot and Lmplot?

While regplot() always shows a single relationship, lmplot() combines regplot() with FacetGrid to provide an easy interface to show a linear regression on “faceted” plots that allow you to explore interactions with up to three additional categorical variables.


1 Answers

The seaborn API does not directly allow to change the linear regression model.

The call chain is:

  • at some point _RegressionPlotter.plot() is called to produce the plot
  • which calls _RegressionPlotter.lineplot() to perform the fit plot
  • which itselfs calls fit_regression which is located in the regression module
  • which in turn calls many seaborn regression methods such as self.fit_fast(grid) in your case.

To use a different regression model, you may:

  • monkey patch the _RegressionPlotter class and change the lineplot() behavior
  • monkey patch the fit_regression() or fit_fast() method in regression module

To do such a seaborn monkey patch, you can refer to an answer I made a while ago that does the same type of hack. This bad, and Santa may not be happy. This means you dynamically modify seaborn for your intended purpose.

Of course, you would need to implement your own regression model to have a law in the for y = a * x instead of y = (a * x) + b. importanceofbeingernest alreadypointed out in a comment this SO question for that matter.


An elegant way around would be to build your own plot, but you already answered that part in your own question.

Quoting your own question (I did not check the code provided):

import numpy as np import pandas as pd import matplotlib.pyplot as plt import statsmodels.formula.api as sfa  np.random.seed(2016) x = np.linspace(0, 10, 32) y = 0.3 * x + np.random.randn(len(x)) df = pd.DataFrame({'x': x, 'y': y}) r = sfa.ols('y ~ x + 0', data=df).fit() fig, ax = plt.subplots(figsize=(5, 5)) ax.scatter(x=x, y=y) ax.plot(x, r.fittedvalues) 
like image 71
LoneWanderer Avatar answered Sep 28 '22 21:09

LoneWanderer