在matplotlib中获得轴的绘图区域的真实限制?

时间:2018-06-24 07:59:31

标签: python matplotlib plot axes

我想找出matplotlib Axes对象内数据的确切范围;即它们的最高和最低x值,以及最高和最低y值。 (我的特定应用程序只需要我就能确定最大的x值,且误差小于0.5,但我对一般情况感到好奇。)

您应该使用Axes.get_xlim().get_ylim()来获取轴对象的范围,但是由于有余量,这些限制将略微超出数据限制。例如:

import matplotlib.pyplot as plt

plt.plot(range(100), range(100))
ax = plt.gca()
print(ax.get_xlim()) # prints (-4.95, 103.95)

边距由Axes.margins()给出,是轴的一部分,那么如果减去这些边距怎么办?我们最终低估了极限:

xlim, xmargin = ax.get_xlim(), ax.margins()[0]
width = xlim[1] - xlim[0]
lower_xlim = xlim[0] + width*xmargin # 0.495, should be 0
upper_xlim = xlim[1] - width*xmargin # 98.505, should be 99

通过反复试验,我们发现如果将更正项乘以10/11,我们最终会达到目标:

lower_xlim = xlim[0] + width*xmargin*10/11 # 0.
upper_xlim = xlim[1] - width*xmargin*10/11 # 99.

仔细检查了不同的数据范围和边距大小后,发现实际因素是:

lower_xlim = xlim[0] + width*5/110 # 0.
upper_xlim = xlim[1] - width*5/110 # 99.

非常奇怪,但是效果很好。除非...如果我们使用Axes.imshow()而不是Axes.plot()怎么办?在这种情况下,绘图没有边距(如果Axes.use_sticky_edges()True,这是默认设置),但是Axes.margins()的结果是相同的。另外,这可能会因在当前范围之外添加非数据艺术家(例如文本框)而变得混乱。 (也许。我从未尝试过。)

我知道查找数据限制的简单方法是遍历Axes对象中的所有数据并计算其最大值和最小值。这可以通过使用Axes.get_children()查找Axes对象的艺术家,并从提供方法.get_data()的艺术家那里获取数据来完成。但这在计算上非常昂贵。

有更好的方法吗?还是我的5/110骇客再好不过了?为什么甚至需要5/110系数?为什么不依赖xmargin? (我应该先打Axes.autoscale()吗?)

1 个答案:

答案 0 :(得分:1)

这应该正常工作:

lower_xlim = xlim[0] + (0.5 * xmargin) / (0.5 + xmargin) * width
upper_xlim = xlim[1] - (0.5 * xmargin) / (0.5 + xmargin) * width