如何在Matplotlib中基于斜率和截距添加线?

hat*_*rix 46 python matplotlib

在R中,有一个函数被调用abline,其中可以根据截距(第一个参数)和斜率(第二个参数)的规范在图上绘制一条线.例如,

plot(1:10, 1:10)
abline(0, 1)
Run Code Online (Sandbox Code Playgroud)

截距为0且斜率为1的直线横跨整个绘图范围.Matplotlib中有这样的功能吗?

Dav*_*arx 54

很多这些解决方案都专注于在适合数据的图中添加一条线.这是一个简单的解决方案,可以根据斜率和截距在绘图中添加任意一条线.

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, '--')
Run Code Online (Sandbox Code Playgroud)

  • @ijoseph 欢迎来到分享和关怀的世界!“每一个优秀的软件作品都始于抓住开发人员的个人渴望” - Eric S. Raymond。去向【Matplotlib 项目】(https://github.com/matplotlib/matplotlib) 发送 pull request! (3认同)
  • 我不敢相信`matplotlib`中没有直接包含此功能。如果制作这样的程序包,似乎可能会实现的第一件事。 (2认同)

ted*_*511 44

截至 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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Ste*_*eve 30

我知道这个问题已有几年了,但由于没有接受的答案,我会补充一些对我有用的问题.

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

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()
Run Code Online (Sandbox Code Playgroud)


ali*_*i_m 9

我不知道如何在不诉诸回调的情况下做到这一点,但这似乎工作得相当好.

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)
Run Code Online (Sandbox Code Playgroud)


mok*_*ok0 9

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')
Run Code Online (Sandbox Code Playgroud)


lin*_*lof 8

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

matplotlib.axes.Axes.axline

例如,您将能够通过点绘制一条红线(0, 0)(1, 1)使用

axline((0, 0), (1, 1), linewidth=4, color='r')
Run Code Online (Sandbox Code Playgroud)


hat*_*rix 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()
Run Code Online (Sandbox Code Playgroud)

  • 好吧,如果你只想要一条从左下角到右上角的线,无论你如何缩放,那么你可以只做`plt.plot([0,1],[0,1] , 变换=plt.gca().transAxes)`。不过,这并不代表数据坐标中的 1 比 1 斜率,而且无论您放大到什么位置,它_总是_从左下角到右上角......不过,就像你说的,一个更通用的“abline”替换对于交互使用来说比较困难...... (2认同)

Mat*_*ras 5

我想扩展大卫·马克思的答案,我们确保斜线不会扩展到原始绘图区域。由于 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
Run Code Online (Sandbox Code Playgroud)