【问题标题】:matplotlib draw() freezes windowmatplotlib draw() 冻结窗口
【发布时间】:2012-04-03 19:13:04
【问题描述】:

我正在尝试使用 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)

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

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

    这允许我在显示后保留对图表的控制,并且在我尝试移动窗口时它不会冻结。

    【讨论】:

      【解决方案2】:

      这可能与this question 重复。

      无论如何,我怀疑你制作动画的方式。这看起来不像 matplotlib animation examples 中的任何一个,也不遵循(我认为是旧的)advice here

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

      【讨论】:

      • 我不同意对此的普遍怀疑。以我的经验,大多数建议的在 matplotlib 中制作动画的方法都非常糟糕,将事情转移到对matplotlib.pylab.ion() 更友好的方法是一个好主意。有关交互式绘图的示例解决方案,请考虑answer that I gave here。它应该可以修改以允许基本动画。
      • basic_example 动画也会出现问题。我不确定如何在 plt.show() 之后允许新数据进入,它不会挂起但不会更新!
      • EMS 我尝试了您的示例解决方案,但当我移动窗口时它也挂起。
      【解决方案3】:

      我在尝试实时绘制一些曲线时遇到了同样的问题。快速解决方法是在绘图函数中添加绘图暂停。

      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)
      

      【讨论】:

        【解决方案4】:

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

        from matplotlib import pyplot as plt
        #.
        #. My code here 
        #.
        
        # Last line of code:
        plt.show()
        

        【讨论】:

          猜你喜欢
          • 2021-12-31
          • 2020-05-25
          • 2013-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多