python matplotlib 如何将blit应用于坐标轴或图形边侧?
我正在尝试在每次进行一次拟合操作时,刷新我在图形界面(gui)中显示的一些图表。而且,这些图表是在一个可以调整大小的框架内,所以在调整大小后,坐标轴、标签等都需要重新绘制。因此,我想知道有没有人知道如何使用像 plot.figure.canvas.copy_from_bbox
和 blit
这样的方式来更新图形的边缘。看起来这只会复制和更新绘图区域的背景(也就是画线的地方),而不会更新图形或图表的边缘(也就是标签和刻度的位置)。我一直在通过反复尝试和阅读mpl的文档来让我的图表更新,但到目前为止,我的代码变得非常复杂,比如 self.this_plot.canvas_of_plot..etc.etc.. .plot.figure.canvas.copy_from_bbox
... 这可能太复杂了。
我知道我的表达可能有点不太准确,但我一直在努力阅读matplotlib的文档,关于Figure、canvas、graph、plot、figure.Figure等之间的区别,已经让我有点搞不清楚了。所以我最想问的第一个问题是:
1 - 如何更新matplotlib图表周围的刻度和标签。
其次,因为我想更好地理解这个问题的答案,
2 - 在图形界面中,plot、figure、canvas等之间的区别是什么?
非常感谢你的帮助。
1 个回答
一开始,这些内容可能会让人感到有点困惑!
首先,如果你在不断地更新坐标轴的刻度等内容,那么使用“blitting”就没什么意义了。blitting其实就是一种避免重新绘制所有内容的方法,适用于只有部分内容在变化的情况。如果所有内容都在变化,那就直接重新绘制图表吧。
简单来说,你只需要用 fig.canvas.draw()
或 plt.draw()
就可以了。
至于你第一个问题的答案,在大多数情况下,你不需要手动更新这些内容。如果你改变了坐标轴的范围,它们会自动更新。你遇到的问题是因为你只在更新坐标轴内部的内容,而不是重新绘制整个图表。
关于你的第二个问题,一个很好的详细介绍是 Matplotlib 用户指南 中的 艺术家教程。
简单来说,Matplotlib 有两个不同的层次。一个层次负责将内容分组,这些内容是你在绘图时需要关注的(比如图形、坐标轴、坐标、线条等),另一个层次则负责整体的渲染和绘制(画布和渲染器)。
在 Matplotlib 的图表中,你能看到的任何东西都是一个 Artist
。比如文本、线条、坐标轴,甚至整个图形本身。一个艺术家 a) 知道如何自己绘制,b) 可以包含其他艺术家。
为了让一个艺术家自己绘制,它会使用渲染器(一个特定于后端的模块,你几乎不会直接接触)在 FigureCanvas
,也就是“画布”上进行绘制(画布是一个围绕矢量页面或像素缓冲区的抽象)。要绘制图形中的所有内容,你需要调用 canvas.draw()
。
由于艺术家可以是其他艺术家的组合,所以它们之间是有层级关系的。基本上,情况大致是这样的(当然,这个结构会有所不同):
Figure
Axes (0-many) (An axes is basically a plot)
Axis (usually two) (x-axis and y-axis)
ticks
ticklabels
axis label
background patch
title, if present
anything you've plotted, e.g. Line2D's
希望这些解释能让事情变得稍微清晰一些。
如果你真的想用 blitting 来更新刻度标签等内容,你需要获取并恢复包含它们的完整区域。这个区域有点难以获取,因为它的确切位置直到绘制完成后才会知道(在 Matplotlib 中渲染文本比渲染其他内容更复杂,因为需要支持 latex 等)。你可以做到这一点,如果你真的想要,我很乐意提供一个例子,但通常这样做并不会比直接绘制所有内容更快。(唯一的例外是如果你只更新一个包含多个子图的图形中的一个子图。)