问题描述
我的python项目有问题。现在,我正在使用pyserial for Arduino和matplotlib进行实时图形绘制。我想将来自Arduino的温度传感器数据实时绘制到图形中。收到数据后,我想在关闭显示的图形后继续执行其他行代码。在这种情况下,我想在关闭图形显示后打印“确定”。这是我使用的代码:
import serial
import matplotlib.pyplot as plt
import time
plt.ion()
fig=plt.figure()
i=0
x1=list()
y1=list()
isrun = True
ser = serial.Serial('COM3',9600)
i=0
ser.close()
ser.open()
run = True
while True:
data1 = ser.readline()
print(data1.decode())
x1.append(i)
y1.append(data1.decode())
plt.plot(x1,y1)
plt.title('Temperature')
i += 1
plt.pause(0.005)
plt.show(block=False)
# if plt.close() :
# run= False
# ser.close()
# break
print('ok')
在这种情况下,关闭实时图形后无法打印“确定”。即使我关闭它,它仍继续显示该图。好像他们一直在做循环。我找不到打破循环并继续下一行代码的方法。如何在这种情况下中断循环并继续打印“确定”。希望任何人都可以提供帮助。
解决方法
您必须使用fig.canvas.mpl_connect()捕获按键事件
fig = plt.figure()
keep_ploting = True
def on_key(event):
global keep_ploting
keep_ploting = False
while keep_ploting:
data1 = ser.readline()
print(data1.decode())
x1.append(i)
y1.append(data1.decode())
plt.plot(x1,y1)
plt.title('Temperature')
i += 1
plt.pause(0.005)
plt.show(block=False)
fig.canvas.mpl_connect('key_press_event',on_key)
在这种情况下,它会在任何键事件之后中断循环,您可以定义一个特殊的键来中断循环或采取某些措施。
this question与鼠标单击事件有关,但是您会找到更多有用的信息。
, close event
更适合您的任务。由于plt.pasue()
也会触发此事件,因此您可以使用其他命令来更新图形。
逻辑是:首先绘制一个图,然后不关闭它。在每次迭代中,您只需要更新数据并重新绘制即可。这比每次迭代中显示/关闭图形都要快。
但是,要使绘图与COM3事件保持同步仍然很困难,因为仍然会有延迟。
您可以参考Fast Live Plotting in Matplotlib / PyPlot使更新更快。
这是我的演示:
import matplotlib.pyplot as plt
import numpy as np
import time
close_flag = 0
x = np.arange(0,10)
y = np.arange(0,10)
# to handle close event.
def handle_close(evt):
global close_flag # should be global variable to change the outside close_flag.
close_flag = 1
print('Closed Figure!')
plt.ion()
fig,ax = plt.subplots()
fig.canvas.mpl_connect('close_event',handle_close) # listen to close event
line,= plt.plot(x,y)
t = 0
delta_t = 0.1
while close_flag == 0:
if abs(t - round(t)) < 1e-5:
print(round(t))
x = x + delta_t
y = y - delta_t
line.set_data(x,y) # change the data in the line.
ax.relim() # recompute the axes limits.
ax.autoscale_view() # update the axes limits.
fig.canvas.draw() # draw the figure
fig.canvas.flush_events() # flush the GUI events for the figure.
# plt.show(block=False)
time.sleep(delta_t) # wait a little bit of time
t += delta_t
if close_flag == 1:
break
print('ok')