2015-01-21 16 views
10

Chcę stworzyć zestaw ramek, które można wykorzystać do animowania fabuły rosnącej linii. W przeszłości zawsze używałam plt.draw() i set_ydata() do przerysowywania danych y, które zmieniały się w czasie. Tym razem chciałbym narysować "rosnącą" linię, przesuwając się po wykresie z czasem. Z tego powodu set_ydata nie działa (xdata zmienia długość). Na przykład:Animowanie "rosnącego" wykresu liniowego w Pythonie/Matplotlib

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

plt.figure() 
for n in range(len(x)): 
    plt.plot(x[:n], y[:n], color='k') 
    plt.axis([0, 10, 0, 1]) 
    plt.savefig('Frame%03d.png' %n) 

Podczas gdy to działa, staje się bardzo powolne w miarę skalowania. Czy jest to szybszy sposób?

+0

Czy masz próbkę (link) do grafiki, którą chcesz odtworzyć? Istnieje pakiet pakietów animacji w Pythonie, którego możesz użyć. –

+0

@MylesBaker Oto przykład tego, jak będzie wyglądać (dla powyższego kodu): http://media.giphy.com/media/3xz2BD48KS3fOGzAJ2/giphy.gif – Blink

+0

Czy chcesz zaktualizować ograniczenia wykresu, ponieważ więcej danych jest narażony? (Tj. Przerysować wykres)? Czy znana jest Twoja domena i zasięg? –

Odpowiedz

19

Kilka uwag:

Po pierwsze, dlatego, że rzeczy stają się coraz wolniej, jest to, że jesteś rysunek coraz więcej i więcej nakładających się linii w tej samej pozycji.

Quick Fix jest oczyszczenie działki za każdym razem:

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

plt.figure() 
for n in range(len(x)): 
    plt.cla() 
    plt.plot(x[:n], y[:n], color='k') 
    plt.axis([0, 10, 0, 1]) 
    plt.savefig('Frame%03d.png' %n) 

Jeszcze lepiej jednak aktualizować zarówno xiy dane w tym samym czasie:

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

fig, ax = plt.subplots() 
line, = ax.plot(x, y, color='k') 

for n in range(len(x)): 
    line.set_data(x[:n], y[:n]) 
    ax.axis([0, 10, 0, 1]) 
    fig.canvas.draw() 
    fig.savefig('Frame%03d.png' %n) 

a jeśli” lubię używać modułu animacji (notatka boczna: blit=True może nie działać poprawnie w niektórych serwerach (np. OSX), więc spróbuj blit=False, jeśli masz problemy):

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

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

fig, ax = plt.subplots() 
line, = ax.plot(x, y, color='k') 

def update(num, x, y, line): 
    line.set_data(x[:num], y[:num]) 
    line.axes.axis([0, 10, 0, 1]) 
    return line, 

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y, line], 
           interval=25, blit=True) 
ani.save('test.gif') 
plt.show() 

enter image description here

+1

Rozwiązanie 'set_data' jest tak eleganckie. Żałuję, że nie mogłem uprowadzić 10 razy. –

Powiązane problemy