如何在实时python中自动缩放图形的y轴和x轴
我修改了本教程的代码以创建自己的实时绘图: 我需要实时绘制来自接近传感器的数据,数据通过USB电缆发送到计算机,我使用串行端口读取数据,因此代码已经按我所希望的方式工作,但我还想修改y轴和x轴,而不是让它静止,因为有时峰值为3000,有时为2000,当传感器未被触摸时,峰值约为200,因为它还检测环境光。有什么线索可以帮我吗如何在实时python中自动缩放图形的y轴和x轴,python,matplotlib,animation,graph,real-time,Python,Matplotlib,Animation,Graph,Real Time,我修改了本教程的代码以创建自己的实时绘图: 我需要实时绘制来自接近传感器的数据,数据通过USB电缆发送到计算机,我使用串行端口读取数据,因此代码已经按我所希望的方式工作,但我还想修改y轴和x轴,而不是让它静止,因为有时峰值为3000,有时为2000,当传感器未被触摸时,峰值约为200,因为它还检测环境光。有什么线索可以帮我吗 import matplotlib.pyplot as plt import matplotlib.animation as animation import seria
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
# Data from serial port
port = 'COM8'
baudrate = 9600
tout = 0.01 # Miliseconds
# Time to update the data of the sensor signal real time Rs=9600baud T=1/Rs
tiempo = (1 / baudrate) * 1000
# Parameters
x_len = 200 # Number of points to display
y_range = [20000, 40000] # Range of Y values to display
# Create figure for plotting
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
xs = list(range(0, x_len))
ys = [0] * x_len
ax.set_ylim(y_range)
# Create a blank line. We will update the line in animate
line, = ax.plot(xs, ys)
# Markers
startMarker = 60 # Start marker "<"
endMarker = 62 # End marker ">"
# Begin Arduino communication, Port COM8, speed 9600
serialPort = serial.Serial(port, baudrate, timeout=tout)
# Begin to save the arduino data
def arduinodata():
global startMarker, endMarker
ck = ""
x = "z" # any value that is not an end- or startMarker
bytecount = -1 # to allow for the fact that the last increment will be one too many
# wait for the start character
while ord(x) != startMarker:
x = serialPort.read()
# save data until the end marker is found
while ord(x) != endMarker:
if ord(x) != startMarker:
ck = ck + x.decode()
bytecount += 1
x = serialPort.read()
return ck
def readarduino():
# Wait until the Arduino sends '<Arduino Ready>' - allows time for Arduino reset
# It also ensures that any bytes left over from a previous message are discarded
msg = ""
while msg.find("<Arduino is ready>") == -1:
while serialPort.inWaiting() == 0:
pass
# delete for example the "\r\n" that may contain the message
msg = arduinodata()
msg = msg.split("\r\n")
msg = ''.join(msg)
# If the sensor send very big numbers over 90000 they will be deleted
if msg and len(msg) <= 5:
msg = int(msg)
return msg
elif msg and len(msg) >= 4:
msg = int(msg)
return msg
# This function is called periodically from FuncAnimation
def animate(i, ys):
# Read pulse from PALS2
pulse = readarduino()
# Add y to list
ys.append(pulse)
# Limit x and y lists to set number of items
ys = ys[-x_len:]
# Update line with new Y values
line.set_ydata(ys)
return line,
# Plot labels
plt.title('Heart frequency vs Time')
plt.ylabel('frequency ')
plt.xlabel('Samples')
# Set up plot to call animate() function periodically
ani = animation.FuncAnimation(fig, animate, fargs=(ys,), interval=tiempo, blit=True)
plt.show()
plt.close()
serialPort.close()
导入matplotlib.pyplot作为plt
将matplotlib.animation导入为动画
导入序列号
#来自串行端口的数据
端口='COM8'
波特率=9600
tout=0.01毫秒
#实时更新传感器信号数据的时间Rs=9600波特T=1/Rs
tiempo=(1/波特率)*1000
#参数
x_len=200#要显示的点数
y_范围=[20000,40000]#要显示的y值范围
#创建用于打印的图形
图=plt.图()
ax=图添加子批次(1,1,1)
xs=列表(范围(0,x_len))
ys=[0]*x_len
ax.set_ylim(y_范围)
#创建一个空行。我们将在动画中更新该行
直线,=ax.绘图(xs,ys)
#标记
startMarker=60#开始标记“”
#开始Arduino通信,端口COM8,速度9600
串行端口=串行。串行(端口,波特率,超时=tout)
#开始保存arduino数据
def arduinodata():
全球startMarker、endMarker
ck=“”
x=“z”#任何不是结束或开始标记的值
bytecount=-1#考虑到最后一个增量太多的事实
#等待开始字符
而ord(x)!=startMarker:
x=serialPort.read()
#保存数据,直到找到结束标记
而ord(x)!=结束标记:
如果作战需求文件(x)!=startMarker:
ck=ck+x.解码()
字节数+=1
x=serialPort.read()
返回ck
def readarduino():
#如果要自动缩放y轴,请等待Arduino发送“,然后只需在animate()
函数中调整y轴限制:
def animate(i, ys):
# Read pulse from PALS2
pulse = readarduino()
# Add y to list
ys.append(pulse)
# Limit x and y lists to set number of items
ys = ys[-x_len:]
ymin = np.min(ys)
ymax = np.max(ys)
ax.set_ylim(ymin, ymax)
# Update line with new Y values
line.set_ydata(ys)
return line,
但是,如果使用blit=True
,结果将不是您期望的结果。这是因为blitting试图只绘制已更改的图形部分,而轴上的记号不包括在内。如果需要更改限制并因此更改刻度,则应在调用FuncAnimation
时使用blit=False
。请注意,由于matplotlib必须在每一帧重新绘制整个绘图,因此会遇到性能问题,但如果要更改限制,则没有办法解决。如果要自动缩放y轴,则只需在animate()
函数中调整y轴限制:
def animate(i, ys):
# Read pulse from PALS2
pulse = readarduino()
# Add y to list
ys.append(pulse)
# Limit x and y lists to set number of items
ys = ys[-x_len:]
ymin = np.min(ys)
ymax = np.max(ys)
ax.set_ylim(ymin, ymax)
# Update line with new Y values
line.set_ydata(ys)
return line,
但是,如果使用blit=True
,结果将不是您期望的结果。这是因为blitting试图只绘制已更改的图形部分,而轴上的记号不包括在内。如果需要更改限制并因此更改刻度,则应在调用FuncAnimation
时使用blit=False
。请注意,由于matplotlib必须在每一帧重新绘制整个绘图,因此您将遇到性能问题,但如果您想更改限制,则没有办法解决。因此,我对此链接的最后一段代码进行了一些更改
我可以解决这个问题。x轴和Y轴现在正在自动缩放
import PyQt5
from PyQt5 import QtWidgets, QtCore
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys # We need sys so that we can pass argv to QApplication
import os
from random import randint
import serial
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.graphWidget = pg.PlotWidget()
self.setCentralWidget(self.graphWidget)
# Data from serial port
self.port = 'COM8'
self.baudrate = 9600
self.tout = 0.01 # Miliseconds
# Time to update the data of the sensor signal Rs=9600baud T=1/Rs
self.tiempo = (1 / self.baudrate) * 1000
self.x_len = 200
self.x = list(range(0, self.x_len)) # 100 time points
self.y = [0] * self.x_len # 100 data points
self.graphWidget.setBackground('w')
# Markers
self.startMarker = 60 # Start marker "<"
self.endMarker = 62 # End marker ">"
# Begin Arduino communication, Port COM8, speed 9600
self.serialPort = serial.Serial(self.port, self.baudrate, timeout=self.tout)
pen = pg.mkPen(color=(255, 0, 0))
self.data_line = self.graphWidget.plot(self.x, self.y, pen=pen)
self.timer = QtCore.QTimer()
self.timer.setInterval(self.tiempo)
self.timer.timeout.connect(self.update_plot_data)
self.timer.start()
# Begin to save the arduino data
def arduinodata(self):
ck = ""
x = "z" # any value that is not an end- or startMarker
bytecount = -1 # to allow for the fact that the last increment will be one too many
# wait for the start character
while ord(x) != self.startMarker:
x = self.serialPort.read()
# save data until the end marker is found
while ord(x) != self.endMarker:
if ord(x) != self.startMarker:
ck = ck + x.decode()
bytecount += 1
x = self.serialPort.read()
return ck
def readarduino(self):
# Wait until the Arduino sends '<Arduino Ready>' - allows time for Arduino reset
# It also ensures that any bytes left over from a previous message are discarded
msg = ""
while msg.find("<Arduino is ready>") == -1:
while self.serialPort.inWaiting() == 0:
pass
# delete for example the "\r\n" that may contain the message
msg = self.arduinodata()
msg = msg.split("\r\n")
msg = ''.join(msg)
# If the sensor send very big numbers over 90000 they will be deleted
if msg and len(msg) <= 5:
msg = int(msg)
return msg
elif msg and len(msg) >= 4:
msg = int(msg)
return msg
def update_plot_data(self):
pulse = self.readarduino()
self.x = self.x[1:] # Remove the first y element.
self.x.append(self.x[-1] + 1) # Add a new value 1 higher than the last.
self.y = self.y[1:] # Remove the first
self.y.append(pulse) # Add a new random value.
self.data_line.setData(self.x, self.y) # Update the data.
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
导入PyQt5
从PyQt5导入QtWidgets、QtCore
从pyqtgraph导入PlotWidget,打印
将pyqtgraph作为pg导入
导入sys#我们需要sys以便将argv传递给QApplication
导入操作系统
从随机导入randint
导入序列号
类MainWindow(QtWidgets.QMainWindow):
定义初始化(self,*args,**kwargs):
超级(主窗口,自我)。\uuuuu初始化(*args,**kwargs)
self.graphWidget=pg.PlotWidget()
self.setCentralWidget(self.graphWidget)
#来自串行端口的数据
self.port='COM8'
self.baudrate=9600
self.tout=0.01毫秒
#更新传感器信号数据的时间Rs=9600波特T=1/Rs
self.tiempo=(1/自波特率)*1000
self.x_len=200
self.x=列表(范围(0,self.x_len))#100个时间点
self.y=[0]*self.x#len#100个数据点
self.graphWidget.setBackground('w')
#标记
self.startMarker=60#开始标记“”
#开始Arduino通信,端口COM8,速度9600
self.serialPort=serial.serial(self.port,self.baudrate,timeout=self.tout)
pen=pg.mkPen(颜色=(255,0,0))
self.data\u line=self.graphWidget.plot(self.x,self.y,pen=pen)
self.timer=QtCore.QTimer()
self.timer.setInterval(self.tiempo)
self.timer.timeout.connect(self.update\u plot\u数据)
self.timer.start()
#开始保存arduino数据
def arduinodata(自):
ck=“”
x=“z”#任何不是结束或开始标记的值
bytecount=-1#考虑到最后一个增量太多的事实
#等待开始字符
而ord(x)!=self.startMarker:
x=self.serialPort.read()
#保存数据,直到找到结束标记
而ord(x)!=self.endMarker:
如果作战需求文件(x)!=self.startMarker:
ck=ck+x.解码()
字节数+=1
x=self.serialPort.read()
返回ck
def readarduino(自身):
#等待Arduino发送“”-为Arduino重置留出时间
#它还确保丢弃前一条消息留下的任何字节
msg=“”
而msg.find(“”==-1:
当self.serialPort.inWaiting()=0时:
通过
#例如,删除可能包含消息的“\r\n”
msg=self.arduinodata()
味精