我想找出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()
吗?)
答案 0 :(得分:1)
这应该正常工作:
lower_xlim = xlim[0] + (0.5 * xmargin) / (0.5 + xmargin) * width
upper_xlim = xlim[1] - (0.5 * xmargin) / (0.5 + xmargin) * width