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))
这当然可以通过抓取轴限制(ax.get_xlim()
等)以编程方式完成,但是a)需要一些额外的步骤而b)在更多数据可能最终结束的情况下是脆弱的情节和转移限制。 (实际上在某些情况下,只需添加常量线就会拉伸轴)。
最好只做例如ax.axdline(ls="--", c=".3")
,但不清楚matplotlib代码库中是否存在类似的内容。您需要做的就是修改axhline
代码,以便从[0, 1]
和x
的轴坐标中y
进行绘制,我认为
答案 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
,提供的x
和y
坐标将被解释为轴坐标,而不是数据坐标。
正如@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
使用示例:
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)