【问题标题】:Real time dynamic plotting实时动态绘图
【发布时间】:2013-05-23 04:19:04
【问题描述】:

我有一个关于从 matplotlib 动态更新散点图的问题。 我在 Python 中有以下课程

''' PolygonHandler.py - Python source for polygon handling '''
import numpy as np
import matplotlib.pyplot as plt


class PolygonHandler:
    # Constructor
    def __init__(self):
        self.X = []
        self.Y = []
        self.numberPoints = 0

    # Print the polygon
    def draw(self):
        plt.scatter(self.X,self.Y)
        plt.draw()

    def update(self):
        for i in range(1,self.numberPoints):
            self.X[i] += np.random.normal()*0.01
            self.Y[i] += np.random.normal()*0.01


    # append a point
    def add(self,x,y):
        self.numberPoints += 1
        self.X.append(x)
        self.Y.append(y)

该类用于接收信息并将点添加到 PolygonHandler 类的实时循环中。现在出于示例的目的,我想设计以下循环

P = PolygonHandler()
P.add(1,1)
P.add(2,2)
P.add(1,2)
plt.ion()
plt.show()
while (True):
    P.draw()
    P.update()

如何告诉解释器绘制散点图,并在更新后删除以前的点?现在,我的情节绘制了点和它们之前的所有位置。

文森特

非常感谢您的帮助

PS:我遇到的另一个问题是 matplotlib 打开的窗口在我单击它后立即冻结并停止响应(例如将其移动到屏幕上的另一个位置),有没有办法防止那个?

【问题讨论】:

  • 当您不想要旧点时,为什么需要更新您的情节?你不能关闭旧图并绘制新数据吗?
  • 感谢您的回答!实际上我正在将这段代码用于实时运行的 c++ 应用程序中:不幸的是,关闭和重新打开太慢了

标签: python matplotlib


【解决方案1】:

这里有一种方法可以使用,使用 matplotlib 中的动画。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class PolygonHandler:
    # Constructor
    def __init__(self):
        self.X = []
        self.Y = []
        self.numberPoints = 0
        self.fig , ax = plt.subplots()
        self.sc = ax.scatter(self.X,self.Y)
        ax.set_xlim(0,3)
        ax.set_ylim(0,3)

    # Print the polygon
    def update(self,_):
        for i in range(self.numberPoints):
            self.X[i] += np.random.normal()*0.01
            self.Y[i] += np.random.normal()*0.01
        self.sc.set_offsets(np.column_stack((self.X,self.Y)))
        return self.sc,

    # append a point
    def add(self,x,y):
        self.numberPoints += 1
        self.X.append(x)
        self.Y.append(y)

这样你就可以绘制出你的 3 次随机游走:

P = PolygonHandler()
P.add(1,1)
P.add(2,2)
P.add(1,2)
ani = animation.FuncAnimation(P.fig, P.update, interval=10,blit=False)

关键元素是方法set_offsets(),它替代了散点图的数据。然后update()返回这样的scatter对象,这样matplotlib就知道必须更新了。有关由类处理 matplotlib 动画的另一个源,请参阅this matplotlib 示例。

在最后一行使用 blit=True 动画会更快,但根据您的操作系统,它可能无法正常工作。

【讨论】:

    【解决方案2】:

    你可以这样做。它接受 x,y 作为列表并在同一图上输出散点图和线性趋势。

    from IPython.display import clear_output
    from matplotlib import pyplot as plt
    %matplotlib inline
        
    def live_plot(x, y, figsize=(7,5), title=''):
        clear_output(wait=True)
        plt.figure(figsize=figsize)
        plt.xlim(0, training_steps)
        plt.ylim(0, 100)
        x= [float(i) for i in x]
        y= [float(i) for i in y]
        
        if len(x) > 1:
            plt.scatter(x,y, label='axis y', color='k') 
            m, b = np.polyfit(x, y, 1)
            plt.plot(x, [x * m for x in x] + b)
    
        plt.title(title)
        plt.grid(True)
        plt.xlabel('axis x')
        plt.ylabel('axis y')
        plt.show();
    

    您只需要在循环中调用live_plot(x, y)。这是它的外观:

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 1970-01-01
      • 2015-11-04
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-02
      相关资源
      最近更新 更多