Python, Matplotlib: График исчезает при включенном блиттинге - PullRequest
1 голос
/ 18 июня 2020

Как описано в заголовке, мой сюжет исчезает, когда опция blitting включена. Я поясню немного дальше: я делаю анимацию, чтобы показать решение некоторых дифференциальных уравнений, и код будет становиться все более тяжелым. Мне нужна опция блиттинга для плавной анимации, но мне также нужна кнопка для запуска / остановки анимации. Я использую FuncAnimation. Дело в том, что когда я останавливаю анимацию с помощью команды «myAnimation.event_source.stop ()», сюжет исчезает, пока анимация находится в состоянии паузы, и возвращается анимированной при перезапуске с помощью «myAnimation.event_source.start ()». Я попытался найти проблему в документации matplotlib: https://matplotlib.org/3.2.1/_modules/matplotlib/animation.html#FuncAnimation, но это слишком много для меня, чтобы заглянуть в угол, что можно изменить. У тебя есть идеи, как решить мою проблему? Код: (часть funcanimation и часть кнопки остановки, A - матрица для моего кода c)

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)

1 Ответ

1 голос
/ 19 июня 2020

Мне ответили добрые разработчики Матплотлиба. "https://matplotlib.org/3.3.0/tutorials/advanced/blitting.html#sphx -glr-tutorials-advanced-blitting-py , вероятно, здесь пригодится.

Проблема в том, что при использовании блейтинга мы помечаем художников как« анимированные »через obj .set_animated (True), что означает, что они исключены из обычного процесса отрисовки (чтобы вы могли получить «чистый» фон). В FuncAnimation мы включаем это (на всякий случай), чтобы предотвратить артефакты, в которых находятся предыдущие данные. "застрял" в анимации. Когда вы приостанавливаете анимацию, вы не сбрасываете это состояние, поэтому когда фигура redr aws пропускает рендеринг графиков (потому что это проблема того, что когда-либо управляет анимацией для рендеринга + blit). "

Исходный код:

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() 

Решение (обратите внимание на 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...