用Jupyter Noteb中的matplotlib绘制动态变化图形

2024-05-13 23:17:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个mxn2d数组:第I行表示时间I上N个点的值

我想以图形的形式显示点[1行数组],其中值在一小段时间后更新。因此,图一次显示一行,然后将值更新到下一行,依此类推。

我想在笔记本上做这个。正在查找参考代码。

我试过以下几件事,但没有成功:


Tags: 代码communityhttp图形plotmatplotlibwith时间
3条回答

我一直在寻找一个很好的解决方案,其中一个线程正在泵送数据,我们希望Jupyter笔记本不断更新图形,而不阻止任何事情。在查阅了十几个相关答案后,以下是一些发现:

小心

如果你想要一个实时的图表,不要使用下面的魔术。如果笔记本使用以下内容,则图形更新不起作用:

%load_ext autoreload
%autoreload 2

在导入matplotlib之前,您需要在笔记本中使用以下魔法:

%matplotlib notebook

方法1:使用FuncAnimation

这有一个缺点,即即使数据尚未更新,也会发生图形更新。下面的示例显示了另一个线程在Jupyter笔记本通过FuncAnimation更新图形时更新数据。

%matplotlib notebook

from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from random import randrange
from threading import Thread
import time

class LiveGraph:
    def __init__(self):
        self.x_data, self.y_data = [], []
        self.figure = plt.figure()
        self.line, = plt.plot(self.x_data, self.y_data)
        self.animation = FuncAnimation(self.figure, self.update, interval=1000)
        self.th = Thread(target=self.thread_f, daemon=True)
        self.th.start()

    def update(self, frame):
        self.line.set_data(self.x_data, self.y_data)
        self.figure.gca().relim()
        self.figure.gca().autoscale_view()
        return self.line,

    def show(self):
        plt.show()

    def thread_f(self):
        x = 0
        while True:
            self.x_data.append(x)
            x += 1
            self.y_data.append(randrange(0, 100))   
            time.sleep(1)  

g = LiveGraph()
g.show()

方法2:直接更新

第二种方法是在数据从另一个线程到达时更新图形。这是有风险的,因为matplotlib不是线程安全的,但只要只有一个线程在进行更新,它似乎就可以工作。

%matplotlib notebook

from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from random import randrange
from threading import Thread
import time

class LiveGraph:
    def __init__(self):
        self.x_data, self.y_data = [], []
        self.figure = plt.figure()
        self.line, = plt.plot(self.x_data, self.y_data)

        self.th = Thread(target=self.thread_f, daemon=True)
        self.th.start()

    def update_graph(self):
        self.line.set_data(self.x_data, self.y_data)
        self.figure.gca().relim()
        self.figure.gca().autoscale_view()

    def show(self):
        plt.show()

    def thread_f(self):
        x = 0
        while True:
            self.x_data.append(x)
            x += 1
            self.y_data.append(randrange(0, 100))  

            self.update_graph()

            time.sleep(1)  


from live_graph import LiveGraph

g = LiveGraph()
g.show()

下面是另一种可能更简单的解决方案:

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt

m = 100
n = 100
matrix = np.random.normal(0,1,m*n).reshape(m,n)

fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()

fig.show()
fig.canvas.draw()

for i in range(0,100):
    ax.clear()
    ax.plot(matrix[i,:])
    fig.canvas.draw()

相关问题 更多 >