Search code examples
pythonreal-timepointpyqtgraph

Fast, Real-time plotting of points using pyqtgraph and a LiDAR


I want to create a real-time, point plotting GUI. I am using the Scanse Sweep LiDAR, and at each sweep of this LiDAR (working between 1 - 10Hz) I receive approximately 1000 points (x, y) describing the LiDARs surrounding. This is a 2D LiDAR.

I have looked everywhere and tried countless of code snippets for pyqtgraph, but either it crashes, is super slow or doesn't work at all.

Is there a straight-forward way of creating a plotter window and upon each new scan/data delivery, push those points to the plotter window?

Thankful for any kind of help


Solution

  • It is unclear to me what exactly you want to do, so I assume that you want to make a scatter plot with a 1000 points that are refreshed 10 times a second. Next time please include your code so that we can reproduce your issues and see what you want to achieve.

    In my experience PyQtGraph is the fastest option in Python. It can easily plot a 1000 points at 10 Hz. See the example below.

    #!/usr/bin/env python
    
    from PyQt5 import QtCore, QtWidgets
    import pyqtgraph as pg
    import numpy as np
    
    
    class MyWidget(pg.GraphicsWindow):
    
        def __init__(self, parent=None):
            super().__init__(parent=parent)
    
            self.mainLayout = QtWidgets.QVBoxLayout()
            self.setLayout(self.mainLayout)
    
            self.timer = QtCore.QTimer(self)
            self.timer.setInterval(100) # in milliseconds
            self.timer.start()
            self.timer.timeout.connect(self.onNewData)
    
            self.plotItem = self.addPlot(title="Lidar points")
    
            self.plotDataItem = self.plotItem.plot([], pen=None, 
                symbolBrush=(255,0,0), symbolSize=5, symbolPen=None)
    
    
        def setData(self, x, y):
            self.plotDataItem.setData(x, y)
    
    
        def onNewData(self):
            numPoints = 1000  
            x = np.random.normal(size=numPoints)
            y = np.random.normal(size=numPoints)
            self.setData(x, y)
    
    
    def main():
        app = QtWidgets.QApplication([])
    
        pg.setConfigOptions(antialias=False) # True seems to work as well
    
        win = MyWidget()
        win.show()
        win.resize(800,600) 
        win.raise_()
        app.exec_()
    
    if __name__ == "__main__":
        main()
    

    The way it works is as follows. By plotting an empty list a PlotDataItem is created. This represents a collection of points. When new data points arrive, the setData method is used to set them as the data of the PlotDataItem, which removes the old points.