2012-04-03 71 views
4

我试图使用matplotlib创建一个图表,以反映实时的效果。我可能没有正确执行此操作,因为移动窗口,更改窗口或单击事件会导致图形冻结。下面是我的意思的一个例子。matplotlib平局()冻结窗口

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) 

回答

2

我解决的方法是使用传统知识作为GUI:

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() 

这让我保留图形控制我表演结束后,并没有冻结每当我试图移动窗口。

+0

是否清楚为什么这需要? – Yann 2013-02-06 18:22:30

1

这可能是this question的副本。

在任何情况下,我怀疑你在做动画的方式。这看起来不像matplotlib animation examples中的任何一个,也不遵循(更老,我认为)advice here

大多数的这些例子缔结用plt.show();就像任何其他的事件驱动GUI编程系统(因为这是matplotlib就是在心脏),你需要控制移交给其事件循环和学习,如果你想要的东西才能正常工作这一框架的规定范围内的工作动画。

+2

我不同意它的总体疑虑。根据我的经验,大多数建议的在matplotlib中执行动画的方法都非常糟糕,而将事物移动到更多'matplotlib.pylab.ion()'友好的方法是一个好主意。有关交互式绘图的示例解决方案,请考虑[我在此给出的答案](http://stackoverflow.com/a/9814936/567620)。它应该是可修改的,以允许基本的动画。 – ely 2012-04-03 20:39:51

+0

basic_example动画也会出现问题。我不确定如何在plt.show()后允许新数据,它不会挂起,但它不会更新! – user1170056 2012-04-03 21:03:53

+0

EMS我尝试了您的示例解决方案,但它在移动窗口时也会挂起。 – user1170056 2012-04-03 21:12:05

1

我想要绘制实时曲线的一些同样的问题。快速解决方法是在绘图功能中添加绘图暂停。

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

我从一个非常简单的方法解决了它。在我的Python主文件的末尾,我在代码的最后添加了plt.show()。

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

# Last line of code: 
plt.show()