问题描述
我修改了本教程的代码以创建自己的实时绘图:
因此,我对该链接的最后一个代码进行了一些更改"> https://www.learnpyqt.com/courses/graphics-plotting/plotting-pyqtgraph/我可以解决问题.x和Y轴现在正在自动缩放
导入PyQt5从PyQt5导入QtWidgets,QtCore从pyqtgraph导入PlotWidget,绘制将pyqtgraph导入为pgimport sys#我们需要sys以便可以将argv传递给QApplication导入操作系统来自随机进口randint导入序列类MainWindow(QtWidgets.QMainWindow):def __init __(self,* args,** kwargs):超级(MainWindow,self).__ init __(* args,** kwargs)self.graphWidget = pg.PlotWidget()self.setCentralWidget(self.graphWidget)#串口数据self.port ='COM8'波特率= 9600self.tout = 0.01#毫秒#更新传感器信号数据的时间Rs = 9600baud T = 1/Rsself.tiempo =(1/self.baudrate)* 1000self.x_len = 200self.x = list(range(0,self.x_len))#100个时间点self.y = [0] * self.x_len#100个数据点self.graphWidget.setBackground('w')#标记self.startMarker = 60#开始标记<".self.endMarker = 62##开始Arduino通信,端口COM8,速度9600self.serialPort = serial.Serial(self.port,self.baudrate,timeout = self.tout)笔= pg.mkPen(颜色=(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()#开始保存arduino数据def arduinodata():ck ="x ="z";#任何不是end-或startMarker的值bytecount = -1#允许最后一个增量太多#等待开始字符而ord(x)!= self.startMarker:x = self.serialPort.read()#保存数据,直到找到结束标记而ord(x)!= self.endMarker:如果ord(x)!= self.startMarker:ck = ck + x.decode()字节数+ = 1x = self.serialPort.read()返回ckdef readarduino(个体):#等待Arduino发送'< Arduino Ready>'-留出时间进行Arduino重置#它还确保丢弃前一条消息剩余的任何字节msg ="而msg.find(< Arduino就绪">)== -1:而self.serialPort.inWaiting()== 0时:经过#删除例如"\ r \ n"可能包含消息msg = self.arduinodata()msg = msg.split("\ r \ n")msg =''.join(msg)#如果传感器发送的数字超过90000,则将其删除如果msg和len(msg)< = 5:味精= int(味精)返回味精elif msg和len(msg)> = 4:味精= int(味精)返回味精def update_plot_data(self):脉冲= self.readarduino()self.x = self.x [1:]#删除第一个y元素.self.x.append(self.x [-1] + 1)#添加一个比上一个值高1的新值.self.y = self.y [1:]#删除第一个self.y.append(pulse)#添加一个新的随机值.self.data_line.setData(self.x,self.y)#更新数据.应用= QtWidgets.QApplication(sys.argv)w = MainWindow()w.show()sys.exit(app.exec_())
I modified the code of this tutorial to create my own real time plot:
I needed to plot the data from a proximity sensor in real time, the data is sent through USB cable to the computer and I read it with the serial port, so the code is already working how I wanted to, but I also want to modify the y-axis and x-axis, not let it static, because sometimes the peaks are 3000 and sometimes 2000 and when the sensor is not being touched, the peaks are at around 200 because it also detects the ambient light. any clue how can I make it?
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()
This is how the graph looks like, the x and y axis are always the same:
So I made some changes to the last code of this link https://www.learnpyqt.com/courses/graphics-plotting/plotting-pyqtgraph/and I could solve the problem. x and Y axis are now autoscaling
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_())
这篇关于如何在实时python中自动缩放图形的y和x轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!