如何根据斜率和截距添加直线

问题描述 投票:0回答:14

在 R 中,有一个名为

abline
的函数,其中可以根据截距(第一个参数)和斜率(第二个参数)的指定在图上绘制一条线。例如,

plot(1:10, 1:10)
abline(0, 1)

其中截距为 0、斜率为 1 的线跨越绘图的整个范围。 Matplotlib中有这样的函数吗?

python matplotlib
14个回答
127
投票

许多解决方案都专注于在图中添加一条适合数据的线。这是一个基于斜率和截距向图中添加任意线的简单解决方案。

import matplotlib.pyplot as plt 
import numpy as np    

def abline(slope, intercept):
    """Plot a line from slope and intercept"""
    axes = plt.gca()
    x_vals = np.array(axes.get_xlim())
    y_vals = intercept + slope * x_vals
    plt.plot(x_vals, y_vals, '--')

48
投票

截至 2021 年,在 matplotlib 3.3.4 中,它支持绘制带有斜率值和点的线。

fig, ax = plt.subplots()

ax.axline((0, 4), slope=3., color='C0', label='by slope')
ax.set_xlim(0, 1)
ax.set_ylim(3, 5) 
ax.legend()

enter image description here


39
投票

我知道这个问题已经有几年了,但由于没有公认的答案,我将添加对我有用的答案。

您可以只在图表中绘制值,然后为最佳拟合线的坐标生成另一组值,并将其绘制在原始图表上。 例如,请参阅以下代码:

import matplotlib.pyplot as plt
import numpy as np

# Some dummy data
x = [1, 2, 3, 4, 5, 6, 7]
y = [1, 3, 3, 2, 5, 7, 9]

# Find the slope and intercept of the best fit line
slope, intercept = np.polyfit(x, y, 1)

# Create a list of values in the best fit line
abline_values = [slope * i + intercept for i in x]

# Plot the best fit line over the actual values
plt.plot(x, y, '--')
plt.plot(x, abline_values, 'b')
plt.title(slope)
plt.show()

15
投票

看起来此功能将成为版本的一部分

3.3.0

matplotlib.axes.Axes.axline

例如,您可以使用

 通过点 
(0, 0)
(1, 1)

绘制一条红线
axline((0, 0), (1, 1), linewidth=4, color='r')

12
投票
X = np.array([1, 2, 3, 4, 5, 6, 7])
Y = np.array([1.1,1.9,3.0,4.1,5.2,5.8,7])

scatter (X,Y)
slope, intercept = np.polyfit(X, Y, 1)
plot(X, X*slope + intercept, 'r')

10
投票

我想不出一种不诉诸回调的方法来做到这一点,但这似乎工作得相当好。

import numpy as np
from matplotlib import pyplot as plt


class ABLine2D(plt.Line2D):

    """
    Draw a line based on its slope and y-intercept. Additional arguments are
    passed to the <matplotlib.lines.Line2D> constructor.
    """

    def __init__(self, slope, intercept, *args, **kwargs):

        # get current axes if user has not specified them
        if not 'axes' in kwargs:
            kwargs.update({'axes':plt.gca()})
        ax = kwargs['axes']

        # if unspecified, get the current line color from the axes
        if not ('color' in kwargs or 'c' in kwargs):
            kwargs.update({'color':ax._get_lines.color_cycle.next()})

        # init the line, add it to the axes
        super(ABLine2D, self).__init__([], [], *args, **kwargs)
        self._slope = slope
        self._intercept = intercept
        ax.add_line(self)

        # cache the renderer, draw the line for the first time
        ax.figure.canvas.draw()
        self._update_lim(None)

        # connect to axis callbacks
        self.axes.callbacks.connect('xlim_changed', self._update_lim)
        self.axes.callbacks.connect('ylim_changed', self._update_lim)

    def _update_lim(self, event):
        """ called whenever axis x/y limits change """
        x = np.array(self.axes.get_xbound())
        y = (self._slope * x) + self._intercept
        self.set_data(x, y)
        self.axes.draw_artist(self)

6
投票

我想对于

(intercept, slope)
(0, 1)
的情况,可以使用和扩展以下函数以适应其他斜率和截距,但如果更改轴限制或重新打开自动缩放,则不会重新调整。

def abline():
    gca = plt.gca()
    gca.set_autoscale_on(False)
    gca.plot(gca.get_xlim(),gca.get_ylim())

import matplotlib.pyplot as plt
plt.scatter(range(10),range(10))
abline()
plt.draw()

6
投票

我想扩展大卫·马克思的答案,我们确保斜线不会扩展到原始绘图区域。 由于 x 轴限制用于计算斜线的 y 数据,因此我们需要确保计算出的 y 数据不会扩展给定的 ymin - ymax 范围。如果它确实裁剪了显示的数据。

def abline(slope, intercept,**styles):
    """Plot a line from slope and intercept"""

    axes = plt.gca()
    xmin,xmax = np.array(axes.get_xlim())
    ymin,ymax = np.array(axes.get_ylim()) # get also y limits
    x_vals = np.linspace(xmin,xmax,num=1000) #increased sampling (only actually needed for large slopes)
    y_vals = intercept + slope * x_vals
    locpos = np.where(y_vals<ymax)[0] # if data extends above ymax
    locneg = np.where(y_vals>ymin)[0] # if data extends below ymin
    # select most restricitive condition 
    if len(locpos) >= len(locneg):
        loc = locneg
    else: 
        loc = locpos
    plt.plot(x_vals[loc], y_vals[loc], '--',**styles)
    return y_vals

2
投票

这是我想出的一个可能的解决方法:假设我将截距坐标存储为

x_intercept
y_intercept
,并将斜率 (m) 保存为
my_slope
,这是通过著名的方程 找到的m = (y2-y1)/(x2-x1),或者以任何你设法找到它的方式。

使用另一个著名的直线一般方程 y = mx + q,我定义了函数

find_second_point
,它首先计算 q(因为 mxy 是已知),然后计算属于该线的另一个随机点。

一旦我有了两个点(最初的

x_intercept
y_intercept
和新发现的
new_x
new_y
),我只需通过这两个点绘制线段。这是代码:

import numpy as np
import matplotlib.pyplot as plt

x_intercept = 3  # invented x coordinate
y_intercept = 2  # invented y coordinate
my_slope = 1  # invented slope value

def find_second_point(slope,x0,y0):
    # this function returns a point which belongs to the line that has the slope 
    # inserted by the user and that intercepts the point (x0,y0) inserted by the user
    q = y0 - (slope*x0)  # calculate q
    new_x = x0 + 10  # generate random x adding 10 to the intersect x coordinate
    new_y = (slope*new_x) + q  # calculate new y corresponding to random new_x created

    return new_x, new_y  # return x and y of new point that belongs to the line

# invoke function to calculate the new point
new_x, new_y = find_second_point(my_slope , x_intercept, y_intercept)

plt.figure(1)  # create new figure
plt.plot((x_intercept, new_x),(y_intercept, new_y), c='r', label='Segment')
plt.scatter(x_intercept, y_intercept, c='b', linewidths=3, label='Intercept')
plt.scatter(new_x, new_y, c='g', linewidths=3, label='New Point')
plt.legend()  # add legend to image

plt.show()

这是代码生成的图像:

result image


1
投票

简短回答,灵感来自 kite.com

plt.plot(x, s*x + i) 

可重现的代码:

import numpy as np
import matplotlib.pyplot as plt
i=3        # intercept
s=2        # slope
x=np.linspace(1,10,50)      # from 1 to 10, by 50
plt.plot(x, s*x + i)        # abline
plt.show()

2x+3


1
投票

您可以通过将斜率截距形式转换为 2 点形式来编写一个简单的函数。

def mxline(slope, intercept, start, end):
    y1 = slope*start + intercept
    y2 = slope*end + intercept
    plt.plot([start, end], [y1, y2])

调用函数

mxline(m,c, 0, 20)

输出

Graph of a Line


0
投票

可以简单地创建一个列表,其中包含从特定截距和斜率获得的直线方程。将这些值放入列表中,并将其与您想要的任何数字集进行比较。例如 - (Lr 是线性回归模型)

te= []
for i in range(11):
    te.append(Lr.intercept_ + Lr.coef_*i)
plt.plot(te, '--')

完成工作。


0
投票

Matplotlib 有一个绘制无限长线的函数,matplotlib.pyplot.axline。您可以传递给它两个点来绘制线条,也可以传递一个点和一个斜率值。鉴于截距只是 x = 0 处直线的 y 值,您可以通过以下方式绘制所需的直线:

import matplotlib.pyplot as plt
plt.axline((0, intercept), slope=slope)
plt.show()

其中 截距斜率 是您各自的截距和斜率值。


0
投票

我参加聚会迟到了,但为什么不尝试以下方法,请参阅此链接

传统方法

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# find the line of best fit
m, c = np.polyfit(x, y, deg=1) # polynomial degree 1 for straight line fit

where:
y = m*x + c

然后将

m
c
插入斜率和截距图中,如下所示:

plt.plot(x, y, 'bo')
plt.plot(x, m*x+c, linestyle='--') # gives you the best fit line

首选方法

import pandas as pd
import numpy as np
from numpy.polynomial import Polynomial
import matplotlib.pyplot as plt

# find the line of best fit
p = Polynomial.fit(x, y, deg=1)

print(p)

请注意

the coefficients are given in the scaled domain ... convert can be used to get the coefficients in the unscaled data domain

你必须转换它们,像这样:

c, m = p.convert()

然后将

m
c
插入斜率和截距图中,就像以前一样:

plt.plot(x, y, 'bo')
plt.plot(x, m*x+c, linestyle='--') # gives you the best fit line
© www.soinside.com 2019 - 2024. All rights reserved.