【发布时间】:2018-06-24 07:59:30
【问题描述】:
我想找出 matplotlib Axes 对象中数据的确切范围;即,它们的最高和最低 x 值,以及最高和最低 y 值。 (我的具体应用只需要我能够确定误差小于0.5的最高x值,但我对一般情况很好奇。)
您应该使用 Axes.get_xlim() 和 .get_ylim() 来获取 Axes 对象的范围,但由于边距,这些限制会稍微超出数据限制。例如:
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 hack 是下一个最好的东西?为什么甚至需要 5/110 因子?为什么不依赖xmargin? (我应该先打电话给Axes.autoscale()吗?)
【问题讨论】:
-
我怀疑是否有统一的方法,因为我可以在您的示例中将 xlim 设置为 (-2, -1) 并且不会绘制任何对象。条形图的最小值是多少?中心,因为它是实际值吗?左栏的左边框?
-
哦,好点,可以设置 lims。这把一切都搞砸了。对于条形图,它将是中心;我正在寻找进入情节的数据的限制,无论它是哪种情节。
-
没有这样的事情,因为情节包含艺术家,而不是数据。你需要知道艺术家和数据之间的关系,这取决于艺术家的类型,然后还有更多的东西——如果条形图是直方图怎么办?相关的 x 数据不是中心,而是 bin 边缘。
-
@Goyo 我的问题的目的是询问有关从每个艺术家那里收集数据然后获取最小值/最大值的捷径。确实,该数据与绘图限制之间的关系非常重要,因此您不能使用绘图限制,除非在特殊情况下,但我想我认为绘图必须在某处跟踪这些数字。
标签: python matplotlib plot axes