Ich versuche, ein Streudiagramm zu animieren (es muss ein Streudiagramm sein, da ich die Kreisgrößen variieren möchte). Ich habe das matplotlib-Dokumentationstutorial matplotlib documentation tutorial in meiner PyQT-Anwendung erhalten, möchte aber Blitting in die Gleichung einfügen, da meine Anwendung wahrscheinlich auf langsameren Maschinen läuft, auf denen die Animation möglicherweise nicht so flüssig ist.Python, QT und Matplotlib Streudiagramme mit Blitting
Ich habe mir viele Beispiele von Animationen mit Blitting angeschaut, aber keines benutzt jemals ein Streudiagramm (sie benutzen Plot oder Linien) und so habe ich wirklich Mühe herauszufinden, wie man die Animation initialisiert (die Bits, die don nicht jedes Mal neu gerendert) und diejenigen, die das tun. Ich habe einige Dinge ausprobiert und scheint nirgendwohin zu kommen (und ich bin mir sicher, dass sie mehr Verwirrung als Hilfe verursachen würden!). Ich nehme an, dass ich etwas ziemlich Grundlegendes verpasst habe. Hat jemand das schon mal gemacht? Könnte mir jemand helfen, die Figur in die Teile zu teilen, die initiiert werden müssen, und diejenigen, die Updates erhalten?
Der folgende Code funktioniert, aber nicht blit. Anfügen
blit=True
bis zum Ende der Animation Aufruf ergibt die folgende Fehlermeldung:
RuntimeError: The animation function must return a sequence of Artist objects.
Jede Hilfe wäre toll.
Grüße
FP
import numpy as np
from PyQt4 import QtGui, uic
import sys
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupAnim()
self.show()
def setupAnim(self):
self.fig = plt.figure(figsize=(7, 7))
self.ax = self.fig.add_axes([0, 0, 1, 1], frameon=False)
self.ax.set_xlim(0, 1), self.ax.set_xticks([])
self.ax.set_ylim(0, 1), self.ax.set_yticks([])
# Create rain data
self.n_drops = 50
self.rain_drops = np.zeros(self.n_drops, dtype=[('position', float, 2),
('size', float, 1),
('growth', float, 1),
('color', float, 4)])
# Initialize the raindrops in random positions and with
# random growth rates.
self.rain_drops['position'] = np.random.uniform(0, 1, (self.n_drops, 2))
self.rain_drops['growth'] = np.random.uniform(50, 200, self.n_drops)
# Construct the scatter which we will update during animation
# as the raindrops develop.
self.scat = self.ax.scatter(self.rain_drops['position'][:, 0], self.rain_drops['position'][:, 1],
s=self.rain_drops['size'], lw=0.5, edgecolors=self.rain_drops['color'],
facecolors='none')
self.animation = FuncAnimation(self.fig, self.update, interval=10)
plt.show()
def update(self, frame_number):
# Get an index which we can use to re-spawn the oldest raindrop.
self.current_index = frame_number % self.n_drops
# Make all colors more transparent as time progresses.
self.rain_drops['color'][:, 3] -= 1.0/len(self.rain_drops)
self.rain_drops['color'][:, 3] = np.clip(self.rain_drops['color'][:, 3], 0, 1)
# Make all circles bigger.
self.rain_drops['size'] += self.rain_drops['growth']
# Pick a new position for oldest rain drop, resetting its size,
# color and growth factor.
self.rain_drops['position'][self.current_index] = np.random.uniform(0, 1, 2)
self.rain_drops['size'][self.current_index] = 5
self.rain_drops['color'][self.current_index] = (0, 0, 0, 1)
self.rain_drops['growth'][self.current_index] = np.random.uniform(50, 200)
# Update the scatter collection, with the new colors, sizes and positions.
self.scat.set_edgecolors(self.rain_drops['color'])
self.scat.set_sizes(self.rain_drops['size'])
self.scat.set_offsets(self.rain_drops['position'])
if __name__== '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
Das ist großartig. Danke Jean, sehr geschätzt. Interessant, die Kollision mit der "update" -Methode zu beachten. Wenn ich darüber nachdachte, war es wahrscheinlich das, was mich davon abhielt, es ein paar Mal zum Laufen zu bringen. Do! Hinweis an mich selbst: Verwenden Sie keine allgemeinen Begriffe für Funktionsnamen! – fp1991