2012-04-03 7 views
4

Ich versuche mit Matplotlib ein Diagramm zu erstellen, das die Echtzeitergebnisse widerspiegelt. Ich mache das wahrscheinlich nicht richtig, weil das Bewegen des Fensters, das Ändern von Fenstern oder das Klicken auf Dinge dazu führt, dass das Diagramm einfriert. Unten ist ein Beispiel dafür, was ich meine.matplotlib draw() friert das Fenster ein

import matplotlib 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
import numpy as np 

def function1(fig, varse): 
    ax = fig.add_subplot(111, projection='3d') 
    color_grade_classes = ['#80FF00','#FFFF00','#FF8000', '#FF0000'] 
    varse = varse +1 
    ax.set_xlabel('X') 
    ax.set_ylabel('Y') 
    for colors, rows in zip(color_grade_classes, [3,2,1,0]): 
    indexs = np.arange(5) 
    heights = [varse,varse/2,varse/3,0,0] 
    ax.bar(indexs, heights, zs = rows, zdir='y', color=colors, alpha=0.8) 
    plt.ion() 
    plt.draw() 
    plt.show() 
    plt.ioff() 
    return varse 

varse = 0 
plt.ion() 
fig = plt.figure() 
plt.ioff() 
while(1): 
    varse = function1(fig, varse) 

Antwort

2

So wie ich war gelöst tk als gui zu verwenden:

import matplotlib 
matplotlib.use('TkAgg') 

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg 
from matplotlib.figure import Figure 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import random 
import numpy as np 
import sys 
import Tkinter as tk 
import time 

def function1(fig, ax): 
    ax.cla() 
    color_grade_classes = ['#80FF00','#FFFF00','#FF8000', '#FF0000'] 
    varsi = random.randint(1, 100) 

    for colors, rows in zip(color_grade_classes, [3,2,1,0]): 
     indexs = np.arange(5) 
     heights = [varsi,varsi/2,varsi/3,0,0] 
     ax.bar(indexs, heights, zs = rows, zdir='y', color=colors, alpha=0.8) 
    return fig 

class App(): 
    def __init__(self): 
     self.root = tk.Tk() 
     self.root.wm_title("Embedding in TK") 

     self.fig = plt.figure() 
     self.ax = self.fig.add_subplot(111, projection='3d') 
     self.ax.set_xlabel('X') 
     self.ax.set_ylabel('Y') 
     self.fig = function1(self.fig, self.ax) 

     self.canvas = FigureCanvasTkAgg(self.fig, master=self.root) 
     self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.root) 
     self.toolbar.update() 
     self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) 

     self.label = tk.Label(text="") 
     self.label.pack() 
     self.update_clock() 
     self.root.mainloop() 

    def update_clock(self): 
     self.fig = function1(self.fig,self.ax) 
     self.canvas.show() 
     self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) 
     now = time.strftime("%H:%M:%S") 
     self.label.configure(text=now) 
     self.root.after(1000, self.update_clock) 

app=App() 

Diese mir die Kontrolle des Graphen beibehalten kann, nachdem ich zeige und es nach oben nicht einfrieren, wenn ich versuche, das Fenster zu bewegen.

+0

Ist klar, warum das nötig war? – Yann

1

Dies kann ein Duplikat von this question sein.

In jedem Fall bin ich zweifelhaft, wie Sie Animation machen. Dies sieht nicht so aus wie der matplotlib animation examples und folgt auch nicht dem (älteren, glaube ich) advice here.

Die meisten dieser Beispiele schließen mit einer plt.show(); Genau wie jedes andere sogar angetriebene GUI-Programmiersystem (weil das Matplotlib im Herzen ist) müssen Sie die Kontrolle an seine Ereignisschleife übergeben und lernen, innerhalb der Animation dieses Rahmens zu arbeiten, wenn Sie wollen, dass Dinge richtig funktionieren.

+2

Ich stimme den allgemeinen Zweifel daran nicht zu. Nach meiner Erfahrung sind die meisten vorgeschlagenen Wege, Matplotlib-Animationen zu machen, ziemlich schlecht, und es ist eine gute Idee, Dinge auf einen 'matplotlib.pylab.ion()' freundlichen Ansatz zu verschieben. Eine Beispiellösung für das interaktive Plotten finden Sie in der [Antwort, die ich hier gegeben habe] (http://stackoverflow.com/a/9814936/567620). Es sollte modifizierbar sein, um auch grundlegende Animationen zu ermöglichen. – ely

+0

Das Problem tritt auch bei der Animation basic_example auf. Ich bin nicht sicher, wie man neue Daten nach plt.show() erlaubt, es hängt nicht, aber es aktualisiert nicht! – user1170056

+0

EMS Ich habe versucht, Ihre Beispiellösung, aber es hängt auch, wenn ich das Fenster verschiebe. – user1170056

1

Ich hatte das gleiche Problem versucht, einige Kurven in Echtzeit zu plotten. Eine schnelle Lösung ist das Hinzufügen einer Plot-Pause in Ihrer Plotfunktion.

import matplotlib 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
import numpy as np 

def function1(fig, varse): 
    ax = fig.add_subplot(111, projection='3d') 
    color_grade_classes = ['#80FF00','#FFFF00','#FF8000', '#FF0000'] 
    varse = varse +1 
    ax.set_xlabel('X') 
    ax.set_ylabel('Y') 
    for colors, rows in zip(color_grade_classes, [3,2,1,0]): 
    indexs = np.arange(5) 
    heights = [varse,varse/2,varse/3,0,0] 
    ax.bar(indexs, heights, zs = rows, zdir='y', color=colors, alpha=0.8) 
    plt.draw() 
    plt.pause(0.001) 
    return varse 

varse = 0 
plt.ion() 
fig = plt.figure() 
plt.show() 

while(1): 
    varse = function1(fig, varse) 
0

Ich löste es von einer wirklich einfachen Art und Weise. Am Ende meiner Hauptdatei in Python habe ich plt.show() am Ende meines Codes hinzugefügt.

from matplotlib import pyplot as plt 
#. 
#. My code here 
#. 

# Last line of code: 
plt.show()