Jupyter Notebook中的实时实时图形



我刚刚开始学习python来绘制实时gragh。我已经尝试了堆栈溢出上提供的解决方案,但没有一个有效。下面是我的代码,它没有嘟嘟囔囔。请帮忙

import numpy as np
import matplotlib.pyplot as plt
import pyautogui as pg
from matplotlib.animation import FuncAnimation
%matplotlib notebook
binSize = 512
# fig(ax1,ax2) = plt.subplots(2,figsize=(12,6))
f = []
def animate(i):
try:
while True:
x, y = pg.position()
f.append(x)
except KeyboardInterrupt:
print('') 
#     f.append(15) 
if len(f)<binSize :
plt.cla()
plt.plot(f, color='c',LineWidth=1.5,label="Noisy") 
else:
plt.cla()
plt.plot(f[-binSize:],color='c',LineWidth=1.5,label="Noisy")
ani = FuncAnimation(plt.gcf(),animate,interval=1);

所以我更新了代码并尝试绘制两个子图,但过了一段时间

  1. 上图停止清除画布(鼠标 X 坐标(
  2. 下图停止更新图(FFT(
  3. 当数据增长到超出 binSize 时,笔记本冻结并且绘图更新非常缓慢

%matplotlib notebook

binSize = 256
# fig(ax1,ax2) = plt.subplots(2,figsize=(12,6))
f = []
t = 0
dt = 1
fig,axs = plt.subplots(2,1) 

def animate(i):
x, y = pg.position() 
f.append(x) 
n = len(f)
if n<binSize : 
plt.sca(axs[0])
plt.cla()
plt.plot(f, color='c',LineWidth=1.5,label="MOUSE") 
else:
fhat = np.fft.fft(f,binSize)
PSD = fhat*np.conj(fhat)/binSize
freq  = (1/(dt*binSize))*np.arange(binSize)
L = np.arange(1,np.floor(binSize/2),dtype='int')

# update the code third time


axs[0].clear() 
axs[0].plot(f[-binSize:], color='c',LineWidth=1.5,label="MOUSE") 
#           axs[0].xlim(0,binSize) # this stopped the FFT graph to be plotted

#           plt.cla()
axs[1].clear()  
axs[1].plot(freq[L],PSD[L],color='r',LineWidth=2,label="FFT")  
#         plt.xlim(t[0],t[-1])
#         plt.legend()

#         plt.sca(axs[1])
#         plt.plot(freq[L],PSD[L],color='c',LineWidth=2,label="Mouse FFT") 
#         plt.xlim(0,300)
#         plt.legend()
#         plt.cla()
#         plt.plot(f[-binSize:],color='c',LineWidth=1.5,label="Mouse")

ani = FuncAnimation(plt.gcf(),animate,interval=dt)  

为了使其更快,您可以像其他答案一样减少数据

f.pop(0)

我也使用不同的方法来更新绘图,这在我的计算机上工作得更快。

我在开始时创建空图

# needs `,` to get first element from list
p1, = axs[0].plot([], [], color='c', LineWidth=1.5, label="MOUSE")
p2, = axs[1].plot([], [], color='r', LineWidth=2,   label="FFT")

以后只更新图中的数据,没有clear(),再次plot()

xdata = range(len(f))
ydata = f
p1.set_data(xdata, ydata)

# replace data in plot
xdata = range(binSize)
ydata = f[-binSize:]
p1.set_data(xdata, ydata)
#p1.set_xdata(xdata)
#p1.set_ydata(ydata)
# replace data in plot
xdata = freq[:(binSize//2)]
ydata = PSD[:(binSize//2)]
p2.set_data(xdata, ydata)

它只需要运行重新缩放绘图的代码

# rescale view
axs[0].relim()
axs[0].autoscale_view(True,True,True)
axs[1].relim()
axs[1].autoscale_view(True,True,True)

animate()还必须返回新的情节

# return plots
return p1, p2

FuncAnimation()必须闪电战他们

ani = FuncAnimation(..., blit=True)
<小时 />

编辑:

动画的工作速度要快得多,因为我python script.py正常运行,而不是在Jupuyter笔记本中

编辑:

当我正常运行时,我发现了一个可以找到解决方案的问题:它不会更新轴上的值/刻度。Jupyter Notebook没有这个问题。

<小时 />
import numpy as np
import matplotlib.pyplot as plt
import pyautogui as pg
from matplotlib.animation import FuncAnimation
%matplotlib notebook
binSize = 256
f = []
t = 0
dt = 1
fig, axs = plt.subplots(2, 1) 
# needs `,` to get first element from list
p1, = axs[0].plot([], [], color='c', LineWidth=1.5, label="MOUSE")
p2, = axs[1].plot([], [], color='r', LineWidth=2,   label="FFT")
freq = np.arange(binSize)/(dt*binSize)
def animate(i):
x, y = pg.position() 
n = len(f)
if n < binSize :  
f.append(x)
# replace data in plot        
xdata = range(len(f))
ydata = f
p1.set_data(xdata, ydata)
#p1.set_xdata(xdata)
#p1.set_ydata(ydata)
else:
f.pop(0)
f.append(x)

fhat = np.fft.fft(f, binSize)
PSD  = fhat * np.conj(fhat) / binSize

# replace data in plot
#xdata = range(binSize)
ydata = f[-binSize:]
#p1.set_data(xdata, ydata)
#p1.set_xdata(xdata)
p1.set_ydata(ydata)
# replace data in plot
xdata = freq[:(binSize//2)]
ydata = PSD[:(binSize//2)]
p2.set_data(xdata, ydata)
# rescale view
axs[0].relim()
axs[0].autoscale_view(True,True,True)
axs[1].relim()
axs[1].autoscale_view(True,True,True)

# return plots
return p1, p2
ani = FuncAnimation(plt.gcf(), animate, interval=dt, blit=True)
plt.show()

你应该试试这个。而不是清除 plt 清除 axs[0] 等。另外,不是在 plt.plot 上绘制,而是在 axs[0].plot 上绘制

%matplotlib notebook
binSize = 256
# fig(ax1,ax2) = plt.subplots(2,figsize=(12,6))
f = []
t = 0
dt = 1
fig,axs = plt.subplots(2,1) 
plt.sca(axs[0]) 
plt.sca(axs[1])
def animate(i):
x, y = pg.position() 
n = len(f)
if n<binSize :  
f.append(x*100) 
axs[0].clear() 
axs[0].plot(f, color='c',LineWidth=1.5,label="MOUSE") 
else:
f.pop(0)
f.append(x) 
fhat = np.fft.fft(f,binSize)
PSD = fhat*np.conj(fhat)/binSize
freq  = (1/(dt*binSize))*np.arange(binSize)
L = np.arange(1,np.floor(binSize/2),dtype='int') # index array of  [1,2,3..... binsize/2] type int

axs[0].clear() 
axs[0].plot(f[-binSize:], color='c',LineWidth=1.5,label="MOUSE")  

axs[1].clear()  
axs[1].plot(freq[L],PSD[L],color='r',LineWidth=2,label="FFT")   

ani = FuncAnimation(plt.gcf(),animate,interval=dt) 
plt.show()

最新更新