简体   繁体   English

Python, Matplotlib: Plot 在打开 blitting 时消失

[英]Python, Matplotlib : Plot disappear when blitting is on

As the title describe, my plot disappear when the option blitting is On.如标题所描述的那样,我的plot在选项打开时消失了。 I explain a bit further: I am making animations to diplay the solution of some differential equations and the code will become more and more heavy.我进一步解释一下:我正在制作动画来显示一些微分方程的解,代码会变得越来越重。 I need the blitting option to have a smooth animation but I also need a button to start/stop the animation.我需要 blitting 选项来获得平滑的 animation,但我还需要一个按钮来启动/停止 animation。 I am using FuncAnimation.我正在使用 FuncAnimation。 The thing is when I stop the animation with the "myAnimation.event_source.stop()" command, the plot disappear as long as the animation is on pause and comes back animated when I restart with "myAnimation.event_source.start()".问题是当我用“myAnimation.event_source.stop()”命令停止 animation 时,只要 Z6F1C25ED1523962F1BBF9DEE_9BE5092BZ 处于暂停状态,plot 就会消失。 I've tried to find the issue in matplotlib documentation: https://matplotlib.org/3.2.1/_modules/matplotlib/animation.html#FuncAnimation however this is too much for me to corner what could be modified.我试图在 matplotlib 文档中找到问题: https://matplotlib.org/3.2.1/_modules/matplotlib/animation.html#FuncAnimation但这对我来说太多了,无法修改可以修改的内容。 Do you have an idea how to solve my problem?你知道如何解决我的问题吗? Code: (funcanimation part and stop button part, A is a matrice for my specific code)代码:(funcanimation部分和停止按钮部分,A是我的具体代码的矩阵)

def update(self,i):
    self.myAnimation.event_source.interval = self.Constants['interv']
    self.k = i%10
    self.n[:,self.k] = self.A*self.n[:,self.k-1]
    self.p.set_ydata(self.n[:,self.k])
    return self.p,
def _stopp(self,event):
    if self.Launch:
        self.myAnimation = aniamtion.FuncAnimation(self.fig, self.update, frames=range(1,self.Constants['N']), interval=self.Constants['interv'],repeat=False)
        self.Launch=False
    else:
        if self.anim_running:
            self.myAnimation.event_source.stop()
            self.anim_running = False 
        else:
            self.myAnimation.event_source.start()
            self.anim_running = True
def add_button(self,left,name):
    axbutton=plt.axes([left,0.88, 0.12, 0.05])
    bstop = Button(axbutton, name)
    self.Launch=True
    self.Button.append(bstop)

The kind developpers of Matplotlib answered me. Matplotlib 的好心开发者回答了我。 " https://matplotlib.org/3.3.0/tutorials/advanced/blitting.html#sphx-glr-tutorials-advanced-blitting-py is probably of use here. " https://matplotlib.org/3.3.0/tutorials/advanced/blitting.html#sphx-glr-tutorials-advanced-blitting-py可能在这里有用。

The issue is that when using bliting, we mark the artists as "animated" via obj.set_animated(True) which means they are excluded from the normal draw process (so that you can get a "clean" background).问题是,当使用 bliting 时,我们通过 obj.set_animated(True) 将艺术家标记为“动画”,这意味着它们被排除在正常的绘制过程之外(这样您可以获得“干净”的背景)。 In FuncAnimation we enable this (just to be on the safe side) to prevent artifacts where a previous data is "stuck" in the animation.在 FuncAnimation 中,我们启用此功能(只是为了安全起见)以防止先前数据“卡”在 animation 中的伪影。 When you pause the animation you do not un-set this state so when the figure redraws it skips rendering the plots (because it is the problem of what ever is managing the animation to do the render + blit)."当您暂停 animation 时,您不会取消设置此 state,因此当图形重绘时,它会跳过渲染图(因为这是管理 Z6F1C25ED1523962F1BBF9DEE9BE59 进行渲染的问题)。

Initial code:初始代码:

import matplotlib.pyplot as plt
import matplotlib.animation as animation

class plotanimation:
    def __init__(self):
        self.fig,self.ax=plt.subplots()
        self.x=np.linspace(-10,10,1000)
        self.N=200
        self.interv=50
        self.n0=1./(4*np.pi*2e-4*0.1)**0.5 * np.exp(-self.x**2/(4*2e-4*0.1))  
        self.p,=self.ax.plot(self.x,self.n0)
        self.anim_running = True
        self.Myanimation=animation.FuncAnimation(self.fig, self.update,frames=self.N,interval=self.interv,blit=True)
    def update(self,i):
        self.n0+=i/100
        self.p.set_ydata(self.n0)
        return self.p,
    def animate(self):
        pause_ax = self.fig.add_axes((0.7, 0.025, 0.1, 0.04))
        pause_button = Button(pause_ax, 'pause', hovercolor='0.975')
        pause_button.on_clicked(self._pause)
        plt.show()
    def _pause(self, event):
        if self.anim_running:
            self.Myanimation.event_source.stop()
            self.anim_running = False
        else:
            self.Myanimation.event_source.start()
            self.anim_running = True


animated_plot = plotanimation()
animated_plot.animate() 

Solution (notice the self.p.set_animated(False/True)):解决方案(注意 self.p.set_animated(False/True)):

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.widgets import Button


class PlotAnimation:
    def __init__(self):
        self.fig, self.ax = plt.subplots()
        self.x = np.linspace(-10, 10, 1000)
        self.N = 200
        self.interv = 50
        self.n0 = (
            1.0
            / (4 * np.pi * 2e-4 * 0.1) ** 0.5
            * np.exp(-self.x ** 2 / (4 * 2e-4 * 0.1))
        )
        (self.p,) = self.ax.plot(self.x, self.n0)
        self.anim_running = True
        self.Myanimation = animation.FuncAnimation(
            self.fig, self.update, frames=self.N, interval=self.interv, blit=True
        )

    def update(self, i):
        self.n0 += i / 100 % 5
        self.p.set_ydata(self.n0 % 20)
        return (self.p,)

    def animate(self):
        pause_ax = self.fig.add_axes((0.7, 0.025, 0.1, 0.04))
        pause_button = Button(pause_ax, "pause", hovercolor="0.975")
        pause_button.on_clicked(self._pause)
        plt.show()

    def _pause(self, event):
        if self.anim_running:
            self.Myanimation.event_source.stop()
            self.p.set_animated(False)
            self.anim_running = False
            self.fig.canvas.draw_idle()
        else:
            self.p.set_animated(True)
            self.Myanimation.event_source.start()
            self.anim_running = True


animated_plot = PlotAnimation()
animated_plot.animate()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM