matplotlib draw()冻结窗口

时间:2012-04-03 19:13:05

标签: python 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)

4 个答案:

答案 0 :(得分:2)

我解决的方法是使用tk作为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()

这使我可以在显示后保留对图形的控制,并且每当我尝试移动窗口时它都不会冻结。

答案 1 :(得分:1)

这可能与this question重复。

无论如何,我对你做动画的方式表示怀疑。这看起来不像matplotlib animation examples中的任何一个,也不符合(我认为)较早的advice here

这些例子中的大多数以plt.show()结尾;就像任何其他甚至驱动的GUI编程系统一样(因为这就是matplotlib的核心)你需要将控制移交给它的事件循环,并且如果你想让东西正常工作,学会在该框架的动画规定中工作。

答案 2 :(得分: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)

答案 3 :(得分:0)

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

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

# Last line of code:
plt.show()