Suche…


Einführung

Mit Python Matplotlib können Sie animierte Grafiken erstellen.

Grundanimation mit FuncAnimation

Das Paket matplotlib.animation bietet einige Klassen zum Erstellen von Animationen. FuncAnimation erstellt Animationen durch wiederholtes Aufrufen einer Funktion. Hier verwenden wir eine Funktion animate() , die die Koordinaten eines Punktes im Graphen einer Sinusfunktion ändert.

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

TWOPI = 2*np.pi

fig, ax = plt.subplots()

t = np.arange(0.0, TWOPI, 0.001)
s = np.sin(t)
l = plt.plot(t, s)

ax = plt.axis([0,TWOPI,-1,1])

redDot, = plt.plot([0], [np.sin(0)], 'ro')

def animate(i):
    redDot.set_data(i, np.sin(i))
    return redDot,

# create animation using the animate() function
myAnimation = animation.FuncAnimation(fig, animate, frames=np.arange(0.0, TWOPI, 0.1), \
                                      interval=10, blit=True, repeat=True)

plt.show()

Geben Sie hier die Bildbeschreibung ein

Animation in GIF speichern

In diesem Beispiel verwenden wir die save , um ein Animation mit ImageMagick zu speichern.

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

# make sure the full paths for ImageMagick and ffmpeg are configured
rcParams['animation.convert_path'] = r'C:\Program Files\ImageMagick\convert'
rcParams['animation.ffmpeg_path'] = r'C:\Program Files\ffmpeg\bin\ffmpeg.exe'

TWOPI = 2*np.pi

fig, ax = plt.subplots()

t = np.arange(0.0, TWOPI, 0.001)
s = np.sin(t)
l = plt.plot(t, s)

ax = plt.axis([0,TWOPI,-1,1])

redDot, = plt.plot([0], [np.sin(0)], 'ro')

def animate(i):
    redDot.set_data(i, np.sin(i))
    return redDot,

# create animation using the animate() function with no repeat
myAnimation = animation.FuncAnimation(fig, animate, frames=np.arange(0.0, TWOPI, 0.1), \
                                      interval=10, blit=True, repeat=False)

# save animation at 30 frames per second 
myAnimation.save('myAnimation.gif', writer='imagemagick', fps=30)

Interaktive Steuerelemente mit matplotlib.widgets

Für die Interaktion mit Plots bietet Matplotlib GUI-neutrale Widget . Widgets erfordern ein matplotlib.axes.Axes Objekt.

Hier ist eine Slider-Widget-Demo, die die Amplitude einer Sinuskurve ändert. Die Aktualisierungsfunktion wird durch das Ereignis on_changed() des Sliders ausgelöst.

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

TWOPI = 2*np.pi

fig, ax = plt.subplots()

t = np.arange(0.0, TWOPI, 0.001)
initial_amp = .5
s = initial_amp*np.sin(t)
l, = plt.plot(t, s, lw=2)

ax = plt.axis([0,TWOPI,-1,1])

axamp = plt.axes([0.25, .03, 0.50, 0.02])
# Slider
samp = Slider(axamp, 'Amp', 0, 1, valinit=initial_amp)

def update(val):
    # amp is the current value of the slider
    amp = samp.val
    # update curve
    l.set_ydata(amp*np.sin(t))
    # redraw canvas while idle
    fig.canvas.draw_idle()

# call update function on slider value change
samp.on_changed(update)

plt.show()

Geben Sie hier die Bildbeschreibung ein Andere verfügbare Widgets:

Live-Daten von Pipe mit Matplotlib darstellen

Dies kann nützlich sein, wenn Sie eingehende Daten in Echtzeit visualisieren möchten. Diese Daten könnten zum Beispiel von einem Mikrocontroller stammen, der ein analoges Signal kontinuierlich abtastet.

In diesem Beispiel erhalten wir unsere Daten von einer Named Pipe (auch als FIFO bezeichnet). In diesem Beispiel sollten die Daten in der Pipe Zahlen enthalten, die durch Zeilenumbrüche getrennt sind. Sie können dies jedoch an Ihre Wünsche anpassen.

Beispieldaten:

100
123.5
1589

Weitere Informationen zu Named Pipes

Wir werden auch den Datentyp deque aus den Standardbibliothekensammlungen verwenden. Ein Deque-Objekt funktioniert ziemlich ähnlich wie eine Liste. Mit einem Deque-Objekt ist es jedoch recht einfach, etwas an das Objekt anzuhängen, während das Deque-Objekt auf einer festen Länge bleibt. Dies ermöglicht es uns, die x-Achse auf einer festen Länge zu halten, anstatt den Graphen immer zu vergrößern und zu zerquetschen. Weitere Informationen zu Deque-Objekten

Die Wahl des richtigen Backends ist entscheidend für die Leistung. Prüfen Sie, welche Backends auf Ihrem Betriebssystem funktionieren, und wählen Sie ein schnelles aus. Für mich funktionierten nur qt4agg und das Standard-Backend, aber der Standard war zu langsam. Weitere Informationen zu den Backends in Matplotlib

Dieses Beispiel basiert auf dem Matplotlib-Beispiel für das Aufzeichnen von Zufallsdaten .

Keines der 'Zeichen in diesem Code soll entfernt werden.

import matplotlib
import collections
#selecting the right backend, change qt4agg to your desired backend
matplotlib.use('qt4agg')
import matplotlib.pyplot as plt
import matplotlib.animation as animation

#command to open the pipe
datapipe = open('path to your pipe','r')

#amount of data to be displayed at once, this is the size of the x axis
#increasing this amount also makes plotting slightly slower
data_amount = 1000

#set the size of the deque object
datalist = collections.deque([0]*data_amount,data_amount)

#configure the graph itself
fig, ax = plt.subplots()
line, = ax.plot([0,]*data_amount)

#size of the y axis is set here
ax.set_ylim(0,256)

def update(data):
        line.set_ydata(data)
        return line,

def data_gen():
    while True:
        """
        We read two data points in at once, to improve speed
        You can read more at once to increase speed
        Or you can read just one at a time for improved animation smoothness
        data from the pipe comes in as a string,
        and is seperated with a newline character,
        which is why we use respectively eval and rstrip.
        """
        datalist.append(eval((datapipe.readline()).rstrip('\n')))
        datalist.append(eval((datapipe.readline()).rstrip('\n')))
        yield datalist

ani = animation.FuncAnimation(fig,update,data_gen,interval=0, blit=True)
plt.show()

Wenn Ihr Diagramm nach einiger Zeit verzögert wird, fügen Sie weitere Daten von datalist.append hinzu, sodass in jedem Frame mehr Zeilen gelesen werden. Oder wählen Sie ein schnelleres Backend, wenn Sie können.

Dies funktionierte mit 150 Hz-Daten aus einer Pipe auf meinem 1,7-GHz-i3 4005u.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow