2017-04-18 4 views
0

Ich habe ein animiertes Python-Diagramm. Während ich jedes Mal eine Anmerkung (Pfeil) hinzufügen kann, wenn der Zähler durch 100 geteilt werden kann, konnte ich nicht herausfinden, wie man den Pfeil auf dem Graphen hält (oder anfügt) (siehe meinen Screenshot). Im Moment funktioniert das add_annotation aber nur für 1 Sekunde und dann verschwindet es (es sollte mindestens noch 10 Sekunden oder so weiter angezeigt werden).Animierte Graphen mit Matplotlib - kann die Annotation nicht unterstützen/anhängen

das Beispiel von here

enter image description here

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

fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

z = np.random.normal(0,1,255) 
u = 0.1 
sd = 0.3 
counter = 0 
price = [100] 
t = [0] 

def add_annotation(annotated_message,value): 
    plt.annotate(annotated_message, 
       xy = (counter, value), xytext = (counter-5, value+20), 
       textcoords = 'offset points', ha = 'right', va = 'bottom', 
       bbox = dict(boxstyle = 'round,pad=0.1', fc = 'yellow', alpha = 0.5), 
       arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 

def getNewPrice(s,mean,stdev): 
    r = np.random.normal(0,1,1) 
    priceToday = s + s*(mean/255+stdev/np.sqrt(225)*r) 
    return priceToday 


def animate(i): 
    global t,u,sd,counter 
    x = t 
    y = price 
    counter += 1 
    x.append(counter) 
    value = getNewPrice(price[counter-1],u,sd) 
    y.append(value) 
    ax1.clear() 

    if counter%100==0: 
     print "ping" 
     add_annotation("100",value) 

    plt.plot(x,y,color="blue") 


ani = animation.FuncAnimation(fig,animate,interval=20) 
plt.show() 

Antwort

0

Es gibt mehrere Probleme mit Ihrem Code genommen umschrieben, ist das wichtigste, dass Sie Ihre Achsen bei jedem Schritt der Animation (ax1.clear()) räumen, und deshalb entfernen Sie Ihre Anmerkungen.

Eine Option wäre, ein Array mit all Ihren Anmerkungen zu behalten und sie jedes Mal neu zu erstellen. Dies ist offensichtlich nicht die eleganteste Lösung.

Der korrekte Weg, um eine Animation zu tun ist Ihr Line2D-Objekt zu erstellen, und verwenden Sie die Line2D.set_data() oder Line2D.set_xdata() und Line2D.set_ydata() die Koordinaten durch Ihre Linie aufgetragen zu aktualisieren.

Beachten Sie, dass die Animationsfunktion eine Liste der Künstler, die geändert wurden, zurückgeben sollte (zumindest wenn Sie Blitting verwenden möchten, was die Leistung verbessern würde). Aus diesem Grund müssen Sie beim Erstellen einer Anmerkung das Objekt Annotation zurückgeben und sie in einer Liste speichern und alle Künstler durch die Animationsfunktion zurückgeben.

Dies wird schnell zusammen geworfen, aber sollten Sie einen Ausgangspunkt geben:

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

fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

ax1.set_xlim((0,500)) 
ax1.set_ylim((0,200)) 

z = np.random.normal(0,1,255) 
u = 0.1 
sd = 0.3 
counter = 0 
price = [100] 
t = [0] 
artists = [] 
l, = plt.plot([],[],color="blue") 


def add_annotation(annotated_message,value): 
    annotation = plt.annotate(annotated_message, 
       xy = (counter, value), xytext = (counter-5, value+20), 
       textcoords = 'offset points', ha = 'right', va = 'bottom', 
       bbox = dict(boxstyle = 'round,pad=0.1', fc = 'yellow', alpha = 0.5), 
       arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 
    return annotation 


def getNewPrice(s,mean,stdev): 
    r = np.random.normal(0,1,1) 
    priceToday = s + s*(mean/255+stdev/np.sqrt(225)*r) 
    return priceToday 


def animate(i): 
    global t,u,sd,counter,artists 
    x = t 
    y = price 
    counter += 1 
    x.append(counter) 
    value = getNewPrice(price[counter-1],u,sd) 
    y.append(value) 
    l.set_data(x,y) 

    if counter%100==0: 
     print(artists) 
     new_annotation = add_annotation("100",value) 
     artists.append(new_annotation) 

    return [l]+artists 


ani = animation.FuncAnimation(fig,animate,interval=20,frames=500) 
Verwandte Themen