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

时间:2014-02-28 19:33:01

标签: python numpy matplotlib

Matplotlib轴具有函数axhlineaxvline,用于在给定的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))

enter image description here

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

最好只做例如ax.axdline(ls="--", c=".3"),但不清楚matplotlib代码库中是否存在类似的内容。您需要做的就是修改axhline代码,以便从[0, 1]x坐标中y进行绘制,我认为

4 个答案:

答案 0 :(得分:31)

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

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

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

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()

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

答案 1 :(得分:26)

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

完成

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

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

正如@fqq指出的那样,这只是xy限制相等时的身份行。要绘制线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

使用示例:

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()

答案 2 :(得分:3)

从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点用于非线性比例。

答案 3 :(得分:1)

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

ident = [0.0, 1.0]
plt.plot(ident,ident)