matplotlib是否具有在轴坐标中绘制对角线的功能?

mwa*_*kom 37 python numpy matplotlib

Matplotlib轴具有函数axhline,axvline用于在给定的y或x坐标(分别)上绘制水平或垂直线,与Axes上的数据比例无关.

绘制恒定对角线是否有类似的功能?例如,如果我有一个具有相似域的变量的散点图,通常有用的是知道它们是否高于或低于以下行y = x:

mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1
f, ax = plt.subplots(figsize=(6, 6))
ax.scatter(x, y, c=".3")
ax.plot([-3, 3], [-3, 3], ls="--", c=".3")
ax.set(xlim=(-3, 3), ylim=(-3, 3))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这当然可以通过抓取轴限制(ax.get_xlim()等等)以编程方式完成,但是a)需要一些额外的步骤而b)在更多数据可能最终出现在图上并改变极限的情况下是脆弱的.(实际上在某些情况下,只需添加常量线就可以拉伸轴).

例如,最好是这样做,ax.axdline(ls="--", c=".3")但是不清楚matplotlib代码库中是否存在这样的东西.所有你需要做的是修改axhline代码绘制[0, 1]轴上的坐标两xy,我想.

Ffi*_*ydd 33

根据屏幕的左下角到右上角绘制对角线非常简单,您可以简单地使用ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3").该方法ax.get_xlim()将简单地返回x轴的当前值(并且类似地针对y轴).

但是,如果您希望能够使用图表进行缩放,那么它会变得稍微棘手,因为您绘制的对角线不会更改以匹配您的新xlim和ylims.

在这种情况下,您可以使用回调来检查xlims(或ylims)何时发生更改并相应地更改对角线中的数据(如下所示).我在这个例子中找到了回调的方法.更多信息也可以在这里找到

import numpy as np
import matplotlib.pyplot as plt

mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1

f, ax = plt.subplots(figsize=(6, 6))

ax.scatter(x, y, c=".3")
ax.set(xlim=(-3, 3), ylim=(-3, 3))

# Plot your initial diagonal line based on the starting
# xlims and ylims.
diag_line, = ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3")

def on_change(axes):
    # When this function is called it checks the current
    # values of xlim and ylim and modifies diag_line
    # accordingly.
    x_lims = ax.get_xlim()
    y_lims = ax.get_ylim()
    diag_line.set_data(x_lims, y_lims)

# Connect two callbacks to your axis instance.
# These will call the function "on_change" whenever
# xlim or ylim is changed.
ax.callbacks.connect('xlim_changed', on_change)
ax.callbacks.connect('ylim_changed', on_change)

plt.show()
Run Code Online (Sandbox Code Playgroud)

请注意,如果您不希望通过缩放更改对角线,则只需删除下面的所有内容即可 diag_line, = ax.plot(...


Jam*_*ore 30

从图的左下角到右上角绘制对角线将通过以下方式完成

ax.plot([0, 1], [0, 1], transform=ax.transAxes)

使用时transform=ax.transAxes,提供的xy坐标被解释为轴坐标而不是数据坐标.

正如@fqq指出的那样,当你x和你的y限制相等时,这只是身份线.要绘制线条y=x使其始终延伸到绘图的极限,类似于@Ffisegydd给出的方法将起作用,并且可以写为以下函数.

def add_identity(axes, *line_args, **line_kwargs):
    identity, = axes.plot([], [], *line_args, **line_kwargs)
    def callback(axes):
        low_x, high_x = axes.get_xlim()
        low_y, high_y = axes.get_ylim()
        low = max(low_x, low_y)
        high = min(high_x, high_y)
        identity.set_data([low, high], [low, high])
    callback(axes)
    axes.callbacks.connect('xlim_changed', callback)
    axes.callbacks.connect('ylim_changed', callback)
    return axes
Run Code Online (Sandbox Code Playgroud)

用法示例:

import numpy as np
import matplotlib.pyplot as plt

mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1

f, ax = plt.subplots(figsize=(6, 6))
ax.scatter(x, y, c=".3")
add_identity(ax, color='r', ls='--')

plt.show()
Run Code Online (Sandbox Code Playgroud)

  • 这不会绘制y = x线,这是OP所要求的. (2认同)
  • 这是正确的,它从我的答案中所述的情节的左下角到右上角画了一条线.我在辩论是否要包括你必须确保情节的x和y限制相等的警告.我认为,如果您正在绘制身份线,那么设置相等的x和y限制通常是一种好习惯. (2认同)

vol*_*ssa 10

如果轴在范围内 [0,1],则可以通过以下方式解决:

ident = [0.0, 1.0]
plt.plot(ident,ident)
Run Code Online (Sandbox Code Playgroud)


mwa*_*kom 8

从 matplotlib 3.3.0 开始,它将:https://matplotlib.org/3.3.0/api/_as_gen/matplotlib.axes.Axes.axline.html

Axes.axline(self, xy1, xy2=None, *,lope=None, **kwargs) 添加一条无限长的直线。

这条线可以由两点 xy1 和 xy2 定义,也可以由一个点 xy1 和一个斜率定义。

这将在“屏幕上”绘制一条直线,无论 x 和 y 比例如何,因此也适用于在半对数图中绘制指数衰减,在对数图中绘制幂律等。但是,斜率只能与线性比例一起使用; 它对所有其他量表没有明确的意义,因此行为未定义。请使用点 xy1、xy2 为非线性标度指定线。

  • 事实上, `ax.axline((1, 1), slip=1)` 应该可以做到 (7认同)
  • 对我来说这不起作用。我收到 attributeError: 'AxesSubplot' 对象没有属性 'axline'。如果我尝试稍微不同的设置,我会得到: AttributeError: moule 'matplotlib.pyplot' has no attribute 'axline. 我在这两个设置中使用 hline 和 vline 没有问题。 (5认同)