实现方式:调用pyqtgraph.opengl模块里面的GLViewWidget初始化三维绘图空间,调用GLScatterPlotItem绘制三维空间中的散点,调用GLLinePlotItem绘制三维空间中的散点连线;调用pyqtgraph模块里面的PlotWidget初始化二维绘图空间,调用ScatterPlotItem 绘制二维空间中的散点,调用PlotDataItem绘制二维空间中的连线。最后通过QTimer定时刷新散点图。
代码:
# coding=utf-8
# python3
"""
@FileName:基于pyqtgraph 绘制二维 三维散点动图.py
@Author: XiaoFang
@CreateFileTime: 2024/6/26 18:53
@Description: pyqtgraph==0.12.4 python==3.8.12 numpy==1.22.4 pyqt5==5.12.4
"""
import sys
import numpy as np
import pyqtgraph.opengl as gl
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout
from PyQt5.QtCore import QTimer
from pyqtgraph import PlotWidget, PlotDataItem, ScatterPlotItem, mkPen, mkBrush
class MyWidget(QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.connect_rules = [0, 2, 1, 2, 3, 4, 5, 6, 5, 4, 7, 8, 9, 8, 7, 3, 7, 13, 14, 15, 14,
13, 16, 17, 16, 10, 4, 10, 11, 12] # 散点连线规则
self.pos = np.empty((18, 3))
self.pos[:] = [(0, 2, 5), (0, -2, 5), (2, 0, 7), (5, 0, 6), (8, 3, 4), (7, 5, 2), (6, 7, 0), (8, -3, 4),
(7, -5, 2), (6, -7, 0), (12, 3, 4), (11, 5, 2), (10, 7, 0), (12, -3, 4),
(11, -5, 2), (10, -7, 0), (12, 0, 4), (13, 0, 1)] # 初始化散点坐标
self.color = [(10, 36, 45, 255), (32, 120, 186, 255), (50, 25, 28, 255), (79, 182, 62, 255), (90, 27, 32, 255),
(48, 129, 196, 255), (255, 127, 0, 255), (255, 119, 129, 255), (58, 157, 47, 255),
(124, 85, 147, 255), (38, 123, 191, 255), (235, 154, 100, 255), (207, 179, 205, 255),
(127, 185, 158, 255), (235, 40, 50, 255), (250, 180, 108, 255), (250, 200, 120, 255),
(250, 220, 140, 255)] # 散点颜色
self.init_ui()
self.timer = QTimer(self)
self.timer.timeout.connect(self._init_view) # 绑定定时器与更新函数
self.timer.start(100) # 设置定时器周期为100ms
def init_ui(self):
layout = QHBoxLayout(self)
view_widget = gl.GLViewWidget() # 三维视图
layout.addWidget(view_widget, 10)
grid = gl.GLGridItem() # 设置网格
grid.setSpacing(50, 50, 50)
grid.setSize(x=200, y=200, z=100)
view_widget.setCameraPosition(distance=100, elevation=45, azimuth=45)
view_widget.addItem(grid)
plot_widget = PlotWidget() # 二维绘图
layout.addWidget(plot_widget, 10)
plot_widget.setXRange(-100, 100)
plot_widget.setYRange(-100, 100)
self.gl_scatter_item = gl.GLScatterPlotItem(pos=np.array([[0, 0, 0]] * len(self.color)), size=10,
color=np.array(self.color) / 255) # 初始化三维散点Item
self.gl_line_item = gl.GLLinePlotItem(pos=np.array([0, 0, 0]), color=(1.0, 1.0, 0.0, 1)) # 初始化三维散点连线Item
view_widget.addItem(self.gl_scatter_item)
view_widget.addItem(self.gl_line_item)
self.scatter_item = ScatterPlotItem(pos=np.array([[0, 0]] * len(self.color)), size=10,
pen=[mkPen(color) for color in self.color],
brush=[mkBrush(color) for color in self.color]) # 初始化二维散点连线Item
plot_widget.addItem(self.scatter_item)
self.lint_item = PlotDataItem(np.array([0, 0]), pen=mkPen((255, 0, 0, 255)),
width=1.5, antialias=False) # 初始化二维散点连线Item
plot_widget.addItem(self.lint_item)
# 更新散点坐标
def _init_view(self):
self.pos = self.pos + np.array([1, 0, 0]) # 每次更新后散点 X坐标都加1
self.gl_scatter_item.setData(pos=self.pos)
line = [self.pos[i] for i in self.connect_rules] # 三维散点连线
self.gl_line_item.setData(pos=np.array(line))
pos_2d = self.pos[:, :2] # 只保留二维坐标
self.scatter_item.setData(pos=pos_2d, brush=[mkBrush(color) for color in self.color])
line_2d = [pos_2d[i] for i in self.connect_rules] # 二维散点连线
self.lint_item.setData(np.array(line_2d))
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())
运行效果:
基于pyqtgraph及opengl绘制二维 三维散点动图