python matplotlib blit到图的轴或侧面?

时间:2021-06-22 23:40:13

I'm trying to refresh some plots that I have within a gui everytime I go once through a fitting procedure. Also, these plots are within a framw which can be resized, so the axes and labels etc need to be redrawn after the resizing. So was wondering if anyone knew how to update the sides of a figure using something like plot.figure.canvas.copy_from_bbox and blit. This appears to only copy and blit the background of the graphing area (where the lines are being drawn) and not to the sides of the graph or figure (where the labels and ticks are). I have been trying to get my graphs to update by trial and error and reading mpl documentation, but so far my code has jst become horrendously complex with things like self.this_plot.canvas_of_plot..etc.etc.. .plot.figure.canvas.copy_from_bbox... which is probably far too convoluted. I know that my language might be a little off but I've been trying to read through the matplotlb documentation and the differences between Figure, canvas, graph, plot, figure.Figure, etc. are starting to evade me. So my first and foremost question would be:

每次我通过一个合适的程序,我试图刷新一些gui中的一些情节。此外,这些图是在一个可以调整大小的framw内,因此在调整大小后需要重新绘制轴和标签等。因此想知道是否有人知道如何使用plot.figure.canvas.copy_from_bbox和blit等更新图形的边。这似乎只复制和blit图形区域的背景(绘制线条的位置),而不是图形或图形的边(标签和刻度线的位置)。我一直试图让我的图表通过反复试验和阅读mpl文档来更新,但到目前为止,我的代码已经变得非常复杂,像self.this_plot.canvas_of_plot..etc.etc .. .plot.figure.canvas .copy_from_bbox ...这可能太复杂了。我知道我的语言可能有些偏差,但我一直在尝试阅读matplotlb文档,图,画布,图形,情节,图形等之间的差异开始躲避我。所以我的首要问题是:

1 - How do you update the ticks and labels around a matplotlib plot.

1 - 如何更新matplotlib图周围的刻度和标签。

and secondly, since I would like to have a better grasp on what the answer to this question,

第二,既然我想更好地掌握这个问题的答案,

2 - What is the difference between a plot, figure, canvas, etc. in regards to the area which they cover in the GUI.

2 - 关于它们在GUI中覆盖的区域,图,图,画布等之间有什么区别。

Thank you very much for the help.

非常感谢你的帮助。

1 个解决方案

#1


17  

All this can certainly be rather confusing at first!

所有这些一开始肯定会让人感到困惑!

To begin with, if you're chaining the ticks, etc, there isn't much point in using blitting. Blitting is just a way to avoid re-drawing everything if only some things are changing. If everything is changing, there's no point in using blitting. Just re-draw the plot.

首先,如果你正在链接蜱等,那么使用blitting没什么意义。如果只是某些事情发生变化,Blitting只是避免重新绘制所有内容的一种方法。如果一切都在变化,那么使用blitting是没有意义的。重新绘制情节。

Basically, you just want fig.canvas.draw() or plt.draw()

基本上,你只需要fig.canvas.draw()或plt.draw()

At any rate, to answer your first question, in most cases you won't need to update them manually. If you change the axis limits, they'll update themselves. You're running into problems because you're blitting just the inside of the axes instead of redrawing the plot.

无论如何,要回答您的第一个问题,在大多数情况下您不需要手动更新它们。如果更改轴限制,它们将自行更新。你遇到了问题,因为你只是在轴内部进行布局,而不是重新绘制图。

As for your second question, a good, detailed overview is the Artist Tutorial of the Matplotlib User's Guide.

至于你的第二个问题,一个好的,详细的概述是Matplotlib用户指南的Artist Tutorial。

In a nutshell, there are two separate layers. One deals with grouping things into the parts that you'll worry about when plotting (e.g. the figure, axes, axis, lines, etc) and another that deals with rendering and drawing in general (the canvas and renderer).

简而言之,有两个单独的层。一个是处理将事物分组到绘图时要担心的部分(例如图形,轴,轴,线等),另一个处理渲染和绘图(画布和渲染器)。

Anything you can see in a matplotlib plot is an Artist. (E.g. text, a line, the axes, and even the figure itself.) An artist a) knows how to draw itself, and b) can contain other artists.

您在matplotlib图中可以看到的任何东西都是艺术家。 (例如,文本,线条,轴,甚至是图形本身。)艺术家a)知道如何绘制自己,b)可以包含其他艺术家。

For an artist to draw itself, it uses the renderer (a backend-specific module that you'll almost never touch directly) to draw on a FigureCanvas a.k.a. "canvas" (an abstraction around either a vector-based page or a pixel buffer). To draw everything in a figure, you call canvas.draw().

对于一个艺术家来绘制自己,它使用渲染器(一个你几乎不会直接触摸的后端特定模块)来绘制一个FigureCanvas aka“canvas”(围绕基于矢量的页面或像素缓冲区的抽象) 。要绘制图中的所有内容,请调用canvas.draw()。

Because artists can be groups of other artists, there's a hierarchy to things. Basically, something like this (obviously, this varies):

因为艺术家可以是其他艺术家的群体,所以事物的层次结构。基本上,这样的事情(显然,这会有所不同):

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

Hopefully that makes things a touch clearer, anyway.

无论如何,希望这会使事情变得更加清晰。

If you really do want to use blitting to update the tick labels, etc, you'll need to grab and restore the full region including them. This region is a bit tricky to get, because it isn't exactly known until after draw-time (rendering text in matplotlib is more complicated than rendering other things due to latex support, etc). You can do it, and I'll be glad to give an example if it's really what you want, but it's typically not going to yield a speed advantage over just drawing everything. (The exception is if you're only updating one subplot in a figure with lots of subplots.)

如果你真的想使用blitting来更新刻度标签等,你需要抓住并恢复包括它们在内的完整区域。这个区域有点棘手,因为直到绘制时间之后才知道它(在matplotlib中渲染文本比由于乳胶支持等渲染其他东西更复杂)。你可以做到,如果它真的是你想要的话,我会很高兴给出一个例子,但它通常不会比仅仅绘制所有东西产生速度优势。 (例外情况是,如果您只更新包含大量子图的图中的一个子图。)

#1


17  

All this can certainly be rather confusing at first!

所有这些一开始肯定会让人感到困惑!

To begin with, if you're chaining the ticks, etc, there isn't much point in using blitting. Blitting is just a way to avoid re-drawing everything if only some things are changing. If everything is changing, there's no point in using blitting. Just re-draw the plot.

首先,如果你正在链接蜱等,那么使用blitting没什么意义。如果只是某些事情发生变化,Blitting只是避免重新绘制所有内容的一种方法。如果一切都在变化,那么使用blitting是没有意义的。重新绘制情节。

Basically, you just want fig.canvas.draw() or plt.draw()

基本上,你只需要fig.canvas.draw()或plt.draw()

At any rate, to answer your first question, in most cases you won't need to update them manually. If you change the axis limits, they'll update themselves. You're running into problems because you're blitting just the inside of the axes instead of redrawing the plot.

无论如何,要回答您的第一个问题,在大多数情况下您不需要手动更新它们。如果更改轴限制,它们将自行更新。你遇到了问题,因为你只是在轴内部进行布局,而不是重新绘制图。

As for your second question, a good, detailed overview is the Artist Tutorial of the Matplotlib User's Guide.

至于你的第二个问题,一个好的,详细的概述是Matplotlib用户指南的Artist Tutorial。

In a nutshell, there are two separate layers. One deals with grouping things into the parts that you'll worry about when plotting (e.g. the figure, axes, axis, lines, etc) and another that deals with rendering and drawing in general (the canvas and renderer).

简而言之,有两个单独的层。一个是处理将事物分组到绘图时要担心的部分(例如图形,轴,轴,线等),另一个处理渲染和绘图(画布和渲染器)。

Anything you can see in a matplotlib plot is an Artist. (E.g. text, a line, the axes, and even the figure itself.) An artist a) knows how to draw itself, and b) can contain other artists.

您在matplotlib图中可以看到的任何东西都是艺术家。 (例如,文本,线条,轴,甚至是图形本身。)艺术家a)知道如何绘制自己,b)可以包含其他艺术家。

For an artist to draw itself, it uses the renderer (a backend-specific module that you'll almost never touch directly) to draw on a FigureCanvas a.k.a. "canvas" (an abstraction around either a vector-based page or a pixel buffer). To draw everything in a figure, you call canvas.draw().

对于一个艺术家来绘制自己,它使用渲染器(一个你几乎不会直接触摸的后端特定模块)来绘制一个FigureCanvas aka“canvas”(围绕基于矢量的页面或像素缓冲区的抽象) 。要绘制图中的所有内容,请调用canvas.draw()。

Because artists can be groups of other artists, there's a hierarchy to things. Basically, something like this (obviously, this varies):

因为艺术家可以是其他艺术家的群体,所以事物的层次结构。基本上,这样的事情(显然,这会有所不同):

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

Hopefully that makes things a touch clearer, anyway.

无论如何,希望这会使事情变得更加清晰。

If you really do want to use blitting to update the tick labels, etc, you'll need to grab and restore the full region including them. This region is a bit tricky to get, because it isn't exactly known until after draw-time (rendering text in matplotlib is more complicated than rendering other things due to latex support, etc). You can do it, and I'll be glad to give an example if it's really what you want, but it's typically not going to yield a speed advantage over just drawing everything. (The exception is if you're only updating one subplot in a figure with lots of subplots.)

如果你真的想使用blitting来更新刻度标签等,你需要抓住并恢复包括它们在内的完整区域。这个区域有点棘手,因为直到绘制时间之后才知道它(在matplotlib中渲染文本比由于乳胶支持等渲染其他东西更复杂)。你可以做到,如果它真的是你想要的话,我会很高兴给出一个例子,但它通常不会比仅仅绘制所有东西产生速度优势。 (例外情况是,如果您只更新包含大量子图的图中的一个子图。)