[Python / matplotlib] FuncAnimation verstehen und verwenden

Es gibt zwei Möglichkeiten, Animationen mit matplotlib zu erstellen: matplotlib.animation.ArtistAnimation und matplotlib.animation.FuncAnimation. ArtistAnimation ist einfacher und Sie können es nach Ihren Wünschen erstellen. Es gab jedoch ein Problem, dass es schwer war, weil alle Elemente im Voraus erstellt und im Speicher gespeichert wurden. FuncAnimation scheint leichter zu sein, weil es nacheinander generiert wird, aber ich verstehe das Verhalten nicht gut und es ist immer problematisch Ich habe die Seriennummernbilder ausgeschrieben und sie später in mp4 konvertiert. Deshalb habe ich mit viel Mühe studiert, um sie zu verstehen und zu verwenden. Dies ist eine Zusammenfassung.

Basic

Wenn Sie die zum Erstellen einer Animation erforderlichen Informationen an matplotlib.animation.FuncAnimation übergeben, wird die Animation erstellt. Sie müssen also die Argumente und das Verhalten dieser Funktion verstehen.

Die ersten beiden Argumente sind erforderlich, und Sie werden normalerweise zusätzlich die Argumente "Frames" und "Intervall" festlegen.

Die Idee von FuncAnimation

Die Idee von "FuncAnimation" wird im folgenden Codebeispiel zusammengefasst. (Zitiert aus API doc)

for d in frames:
   artists = func(d, *fargs)
   fig.canvas.draw_idle()
   fig.canvas.start_event_loop(interval)

Das heißt, drehen Sie den Iterator "Frames", übergeben Sie jeden "Frame-Namen" "d" an die Funktion "func" und zeichnen Sie den zurückgegebenen "Künstler". Nach dieser Zeit "Intervall" endet "Frames". Wiederholen, bis Sie es tun. Das war's.

Beispiel 1: Bewegungspunkt P.

Machen wir es jetzt. Erstellen wir eine Animation des Punktes P, der 0, 1, 2, ... auf der x-Achse bewegt. Wird es sein?

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig = plt.figure()
ax = fig.add_subplot(111)

def update(frame):
    ax.plot(frame, 0, "o")

anim = FuncAnimation(fig, update, frames=range(8), interval=1000)

anim.save("c01.gif", writer="imagemagick") #Wenn Sie es auf dem Bildschirm anzeigen möchten, plt.show()Ist gut
plt.close()

Klicken Sie hier für die Ergebnisse.

c01.gif

Es ist nicht das, was ich beabsichtigt habe. Was anders ist, ist, dass die vergangene Position des im vorherigen Frame gezeichneten Punktes P immer noch gezeichnet wird. Um dies zu beheben, update Es scheint, dass alle in Achsen geschriebenen Elemente zu Beginn der Funktion gelöscht werden sollten.

Beispiel 2: Bewegungspunkt P (nach Änderung)

Hier ist also der geänderte Code und die Ausführungsergebnisse.

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig = plt.figure()
ax = fig.add_subplot(111)

def update(frame):
    ax.cla() #Klare Axt
    ax.plot(frame, 0, "o")

anim = FuncAnimation(fig, update, frames=range(8), interval=1000)

anim.save("c02.gif", writer="imagemagick")
plt.close()

c02.gif

Die Animation wurde wie vorgesehen durchgeführt.

Beachten Sie, dass beim Aufrufen von "ax.cla ()" auch die Achsenbezeichnung "ax.set_xlabel ()", die Gitterlinie "ax.grid ()" und der Zeichenbereich "ax.set_xlim ()" gelöscht werden. Sie müssen neu konfigurieren, nachdem Sie "ax.cla ()" gelesen haben.

Anwendung

Nur bestimmte Künstler löschen

Im obigen Beispiel wurden alle Zeichnungsinhalte an jedem Frame gelöscht, aber ich denke, dass Sie häufig nur einige Künstler löschen möchten. Das folgende Beispiel ist beispielsweise ein Punkt, der sich auf dem Einheitskreis P bewegt Obwohl es sich um eine Animation von handelt, scheint sie nutzlos zu sein, da ich jedes Mal ein Gitter und einen Einheitskreis zeichne.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig = plt.figure()
ax = fig.add_subplot(111, aspect=1)

theta = np.linspace(0, 2*np.pi, 128)

def update(f):
    ax.cla() #Klare Axt
    ax.grid()
    ax.plot(np.cos(theta), np.sin(theta), c="gray")
    ax.plot(np.cos(f), np.sin(f), "o", c="red")

anim = FuncAnimation(fig, update, frames=np.pi*np.arange(0,2,0.25), interval=200)

anim.save("c03.gif", writer="imagemagick")
plt.close()

c03.gif

In diesem Fall können Sie Ihr Ziel erreichen, anstatt alles zu löschen, indem Sie den Künstler, den Sie löschen möchten, explizit entfernen.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig = plt.figure()
ax = fig.add_subplot(111, aspect=1)

theta = np.linspace(0, 2*np.pi, 128)
p = []
ax.grid()
ax.plot(np.cos(theta), np.sin(theta), c="gray")
    
def update(f):
    if len(p) > 0:
        item = p.pop(0)
        ax.lines.remove(item)
    p.append( ax.plot([np.cos(f)], [np.sin(f)], "o", c="red")[0] )

anim = FuncAnimation(fig, update, frames=np.pi*np.arange(0,2,0.25), interval=200)

anim.save("c03.gif", writer="imagemagick")
plt.close()

Ich bin mir jedoch nicht sicher, welches dieser beiden Beispiele hinsichtlich der Zeichengeschwindigkeit besser ist, obwohl es besser erscheint, es mit "blit = True" im FuncAnimation-Argument zu verwenden.

Animation mit mehreren Nebenhandlungen

Wenn Sie "plt.cla ()" verwenden, um den Zeichnungsinhalt zu löschen, hat dies dieselbe Bedeutung wie "ax.cla ()" ("ax" sind die Achsen, die Sie unmittelbar zuvor berührt haben), also mehrere Unterzeichnungen Animationen mit haben einige Unterzeichnungen, die nicht löschen, was angezeigt wird. Lassen Sie uns für alle Achsen "ax.cla ()".

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig = plt.figure()
axs = [
    fig.add_subplot(121),
    fig.add_subplot(122, aspect=1),
]
theta = np.linspace(0, 4*np.pi, 128)

def update(f):
    for ax in axs:
        ax.cla() #Klare Axt
        ax.grid()
    axs[0].set_xlim([0, 4*np.pi])
    axs[0].plot(theta, np.cos(theta - f), c="blue")
    axs[0].plot(0, np.cos(f), "o", c="blue")

    axs[1].plot(np.cos(theta), np.sin(theta), c="gray")
    axs[1].plot(np.cos(f), np.sin(f), "o", c="blue")
    axs[1].plot(np.cos(f), 0        , "o", c="blue")
    axs[1].plot([np.cos(f), np.cos(f)], [0, np.sin(f)], c="blue")

anim = FuncAnimation(fig, update, frames=np.pi*np.arange(0,2,0.1), interval=200)

anim.save("c04.gif", writer="imagemagick")
plt.close()

c04.gif

Verweise

Recommended Posts

[Python / matplotlib] FuncAnimation verstehen und verwenden
Verwenden Sie matplotlib unter Ubuntu 12 und Python
Lernen Sie Python-Pakete und -Module kennen
Installation von SciPy und matplotlib (Python)
Lesen und verwenden Sie Python-Dateien aus Python
[Python] Verwenden Sie und und oder beim Erstellen von Variablen
So installieren und verwenden Sie pandas_datareader [Python]
Verwenden Sie PIL oder Pillow mit Cygwin Python
Python: Verwendung von Einheimischen () und Globalen ()
Verwendung von Python zip und Aufzählung
[Python] Verstehen, wie rekursive Funktionen verwendet werden
Verstehen Sie Python-Listen, Wörterbücher und so weiter.
Verwendung ist und == in Python
Verwenden Sie Python und MeCab mit Azure-Funktionen
# Python-Grundlagen (#matplotlib)
Meine Matplotlib (Python)
Firebase: Verwenden Sie Cloud Firestore und Cloud Storage von Python
Python-Entwicklungsumgebung - Verwendung von Pyenv und Virtualenv-
[Python] Verwendung von Hash-Funktion und Taple.
Verwenden Sie Python und word2vec (gelernt) mit Azure Databricks
Python> Nach Nummer sortieren und nach Alphabet sortieren> Sortiert verwenden ()
Verwenden Sie libsixel, um Sixel in Python auszugeben und das Matplotlib-Diagramm an das Terminal auszugeben.
[Python] Komprimieren und dekomprimieren
Verwenden Sie thingspeak aus Python
Python- und Numpy-Tipps
Verwenden Sie config.ini mit Python
[Python] [Django] Verwendung des Auswahlfelds und Hinzufügen von Optionen
[Python] Pip und Wheel
Verwenden Sie fließend Python
Ich habe versucht zusammenzufassen, wie man Matplotlib von Python verwendet
Verwenden Sie Datumsangaben in Python
Python-Pakete und -Module
Vue-Cli- und Python-Integration
Verwenden Sie Valgrind mit Python
Verwenden Sie MySQL aus Python
Verstehen Sie die Exponentialverteilung sorgfältig und zeichnen Sie in Python
Verwenden Sie Mecab mit Python 3
Ruby, Python und Map
Verwenden Sie LiquidTap Python Client ③
Schließen Sie externe Kv-Dateien in Python Kivy ein und verwenden Sie sie
Verwenden Sie DynamoDB mit Python
Verwenden Sie SQL Alchemy und Multiprocessing
Zeichnen und verstehen Sie die multivariate Normalverteilung in Python
Heatmap von Python + matplotlib
Python-Eingabe und Ausgabe
Verstehe die Poisson-Distribution sorgfältig und zeichne in Python
Python und Ruby teilen sich
% Und str.format () in Python. Welches benutzt du?
Verwenden Sie Python 3.8 mit Anaconda
Wie benutzt man Matplotlib?
Methodische Verwendung im [Python] -Format
Verwenden Sie Python mit Docker
Verwenden Sie MySQL aus Python
Verwenden Sie LiquidTap Python Client ②
Ubuntu 20.04 auf Himbeer-Pi 4 mit OpenCV und mit Python verwenden
Verwenden Sie BigQuery aus Python.
Verwenden Sie den Profiler in Python
matplotlib dies und das