183 votes

matplotlib Mettre à jour un tracé

J'ai des problèmes pour redessiner le chiffre ici. Je permets à l'utilisateur de spécifier les unités dans l'échelle de temps (axe des x), puis je recalcule et appelle cette fonction tracés (). Je veux simplement que l'intrigue se mette à jour et non pas en annexant une autre.

 def plots():
    global vlgaBuffSorted
    cntr()

    result = collections.defaultdict(list)
    for d in vlgaBuffSorted:
        result[d['event']].append(d)

    result_list = result.values()

    f = Figure()
    graph1 = f.add_subplot(211)
    graph2 = f.add_subplot(212,sharex=graph1)

    for item in result_list:
        tL = []
        vgsL = []
        vdsL = []
        isubL = []
        for dict in item:
            tL.append(dict['time'])
            vgsL.append(dict['vgs'])
            vdsL.append(dict['vds'])
            isubL.append(dict['isub'])
        graph1.plot(tL,vdsL,'bo',label='a')
        graph1.plot(tL,vgsL,'rp',label='b')
        graph2.plot(tL,isubL,'b-',label='c')

    plotCanvas = FigureCanvasTkAgg(f, pltFrame)
    toolbar = NavigationToolbar2TkAgg(plotCanvas, pltFrame)
    toolbar.pack(side=BOTTOM)
    plotCanvas.get_tk_widget().pack(side=TOP)
 

213voto

Joe Kington Points 68089

Vous avez deux options:

  1. Faire exactement ce que vous êtes en train de faire, mais appelez - graph1.clear() et graph2.clear() avant replotting les données. C'est le plus lent, mais plus simple et la plus robuste de l'option.

  2. Au lieu de replotting, vous pouvez simplement mettre à jour les données de la parcelle objets. Vous aurez besoin de faire quelques changements dans votre code, mais ce devrait être beaucoup, beaucoup plus vite que replotting choses à chaque fois. Cependant, la forme des données que vous avez tracé ne peux pas changer, et si la gamme de vos données est en train de changer, vous aurez besoin de réinitialiser manuellement les axes x et y des limites.

Pour donner un exemple de la deuxième option:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma

for phase in np.linspace(0, 10*np.pi, 500):
    line1.set_ydata(np.sin(x + phase))
    fig.canvas.draw()

8voto

CavemanPhD Points 61

Dans le cas où quelqu'un vient sur cet article en cherchant ce que je cherchais, j'ai trouvé des exemples à

Comment visualiser scalaire des données 2D avec Matplotlib?

et

http://mri.brechmos.org/2009/07/automatically-update-a-figure-in-a-loop/

ensuite modifiés pour utiliser imshow avec une pile d'images, au lieu de générer et d'utiliser des contours à la volée.


En commençant par un tableau 3D d'images de forme (nBins, nBins, nBins), appelés frames.

def animate_frames(frames):
    nBins   = frames.shape[0]
    frame   = frames[0]
    tempCS1 = plt.imshow(frame, cmap=plt.cm.gray)
    for k in range(nBins):
        frame   = frames[k]
        tempCS1 = plt.imshow(frame, cmap=plt.cm.gray)
        del tempCS1
        fig.canvas.draw()
        #time.sleep(1e-2) #unnecessary, but useful
        fig.clf()

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

win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate_frames, frames)

J'ai aussi trouvé un moyen beaucoup plus simple pour aller sur l'ensemble de ce processus, quoique moins robuste:

fig = plt.figure()

for k in range(nBins):
    plt.clf()
    plt.imshow(frames[k],cmap=plt.cm.gray)
    fig.canvas.draw()
    time.sleep(1e-6) #unnecessary, but useful

Notez que ces deux ne semblent travailler avec ipython --pylab=tk, une.k.une.backend = TkAgg

Merci pour l'aide en tout.

8voto

Scott Points 393

J'ai sorti un paquet python-drawnow qui fournit des fonctionnalités laisser une figure de mise à jour, généralement appelée dans une boucle for, similaire à Matlab drawnow.

Un exemple d'utilisation:

from pylab import figure, plot, ion, linspace, arange, sin, pi
def draw_fig():
    # can be arbitrarily complex; just to draw a figure
    #figure() # don't call!
    plot(t, x)
    #show() # don't call!

N = 1e3
figure() # call here instead!
ion()    # enable interactivity
t = linspace(0, 2*pi, num=N)
for i in arange(100):
    x = sin(2 * pi * i**2 * t / 100.0)
    drawnow(draw_fig)

Ce package est robuste. Cependant, il est principalement destiné pour le développement et, par conséquent, lent et légèrement instable. Cependant, ce paquet fournit des options d'attente après chaque mise à jour ou de le déposer dans le débogueur.

4voto

jkeyser Points 29

Tout ce qui précède est peut-être vrai. Toutefois, pour moi, la mise à jour en ligne des chiffres ne fonctionne qu'avec certains moteurs, en particulier wx . Vous pouvez simplement essayer de changer cela, par exemple en démarrant ipython / pylab de ipython --pylab=wx ! Bonne chance!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X