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

2024-04-29 05:07:42 发布

您现在位置:Python中文网/ 问答频道 /正文

Matplotlib轴具有axhlineaxvline功能,分别用于在给定的y或x坐标上绘制水平线或垂直线,与轴上的数据比例无关。

有没有类似的函数来绘制一个恒定的对角线?例如,如果我有一个具有类似域的变量散点图,那么知道它们是否位于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]坐标中的^{轴绘制xy坐标。


Tags: 数据代码功能matplotlib绘制情况axmean
3条回答

从屏幕左下角到右上角绘制对角线非常简单,您只需使用ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3")。方法ax.get_xlim()将简单地返回x轴的当前值(对于y轴也是如此)。

但是,如果您希望能够使用图形进行缩放,则会变得稍微复杂一些,因为您绘制的对角线不会更改为与新的xlims和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(...

从图的左下角到右上角画一条对角线可以通过以下方法完成

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

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

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

相关问题 更多 >