在 GUI 中创建多个曲面图
Create multiple surface plots in GUI
所以我刚开始一个新项目,我需要在 GUI 上展示我收集的数据。为此,我创建了一个测试脚本,它从 .mat 文件中读取数据,然后计算曲面图。到目前为止一切正常。现在我需要从 GUI 开始。我已经设法创建了另一个可以打开 OpenFileName-Dialog 并从文件中读取数据的测试程序。
from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('Qt5Agg')
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as Navi
from matplotlib.figure import Figure
import seaborn as sns
import pandas as pd
import sip
import h5py
import mat73
import numpy as np
class MatplotlibCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width = 5, height = 4, dpi = 120):
fig = Figure(figsize = (width,height))
self.axes = fig.add_subplot(111)
super(MatplotlibCanvas,self).__init__(fig)
fig.tight_layout()
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1466, 910)
font = QtGui.QFont()
font.setFamily("Tahoma")
MainWindow.setFont(font)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView.setGeometry(QtCore.QRect(280, 0, 561, 441))
self.graphicsView.setObjectName("graphicsView")
self.graphicsView_2 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_2.setGeometry(QtCore.QRect(860, 0, 561, 441))
self.graphicsView_2.setObjectName("graphicsView_2")
self.graphicsView_3 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_3.setGeometry(QtCore.QRect(280, 440, 561, 441))
self.graphicsView_3.setObjectName("graphicsView_3")
self.graphicsView_4 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_4.setGeometry(QtCore.QRect(860, 440, 561, 441))
self.graphicsView_4.setObjectName("graphicsView_4")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(40, 90, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.action_Open = QtWidgets.QAction(MainWindow)
self.action_Open.setObjectName("action_Open")
self.action_Save = QtWidgets.QAction(MainWindow)
self.action_Save.setObjectName("action_Save")
self.action_Export = QtWidgets.QAction(MainWindow)
self.action_Export.setObjectName("action_Export")
self.action_Exit = QtWidgets.QAction(MainWindow)
self.action_Exit.setObjectName("action_Exit")
self.filename = ''
self.canv = MatplotlibCanvas(self)
self.df = []
self.toolbar = Navi(self.canv, self.centralwidget)
self.pushButton.clicked.connect(self.getFile)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def getFile(self):
""" this function will get the adress of the mat file location
also calls a readData function
"""
self.filename = QFileDialog.getOpenFileName(filter="mat (*.mat)")[0]
print("File: ", self.filename)
self.readData()
def readData(self):
self.df = mat73.loadmat(self.filename, use_attrdict=True)
struct = self.df['DemoData']
print(struct.Nr.data)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Open "))
self.action_Open.setText(_translate("MainWindow", "&Open"))
self.action_Save.setText(_translate("MainWindow", "&Save"))
self.action_Export.setText(_translate("MainWindow", "&Export"))
self.action_Exit.setText(_translate("MainWindow", "&Quit"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
既然我可以读取数据,下一步就是创建曲面图并显示数据。我的想法是使用 graphicsView 元素来显示四个需要的图,但我找不到如何 link 数字,我在第一个测试程序(没有 GUI)中使用了 graphicsView 元素。对于该图,我使用了以下代码行:
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
surf = ax.plot_surface(pArray, rArray, trArray, alpha = 0.5)
surf = ax.plot_surface(pArray, rArray, tArray, cmap=cm.jet, alpha = 1)
谁能给我一个提示,我是怎么做到的?
编辑:我上传了一个 .mat 文件 .mat File
我要注意的是:
- mat73 无法读取提供的 .mat 所以我使用 scipy.
- .mat 中包含的数据是一维数组,因此它们无法形成曲面,因为需要二维数组,所以我将只展示如何绘制点。
- 由于点数较多,绘画需要时间,可能会卡顿
逻辑是使用 FigureCanvas 并创建 3d 图:
from functools import cached_property
from PyQt5.QtWidgets import QApplication, QFileDialog, QMainWindow
from matplotlib.backends.backend_qt5agg import (
FigureCanvas,
NavigationToolbar2QT as NavigationToolbar,
)
from matplotlib.figure import Figure
from matplotlib import cm
import scipy.io as sio
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ax = self.canvas.figure.add_subplot(projection="3d")
self.setCentralWidget(self.canvas)
self.addToolBar(self.toolbar)
file_menu = self.menuBar().addMenu("&File")
open_action = file_menu.addAction("&Open")
open_action.triggered.connect(self.handle_open_action_triggered)
@cached_property
def canvas(self):
return FigureCanvas()
@cached_property
def toolbar(self):
return NavigationToolbar(self.canvas, self)
def handle_open_action_triggered(self):
filename, _ = QFileDialog.getOpenFileName(self, filter="mat (*.mat)")
if filename:
self.load_mat(filename)
def load_mat(self, filename):
res = sio.loadmat(filename)
record = res["record"]
data = record["Data"]
temp_ref = data[0, 0]["TempRef"][0, 0][0, 0]["data"]
nr = data[0][0]["Nr"][0, 0][0, 0]["data"]
temp_act = data[0, 0]["TempAct"][0, 0][0, 0]["data"]
self.update_plot(temp_ref, nr, temp_act)
def update_plot(self, x, y, z):
print(x.shape, y.shape, z.shape)
self.ax.scatter(x, y, z)
self.canvas.draw()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
所以我刚开始一个新项目,我需要在 GUI 上展示我收集的数据。为此,我创建了一个测试脚本,它从 .mat 文件中读取数据,然后计算曲面图。到目前为止一切正常。现在我需要从 GUI 开始。我已经设法创建了另一个可以打开 OpenFileName-Dialog 并从文件中读取数据的测试程序。
from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('Qt5Agg')
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as Navi
from matplotlib.figure import Figure
import seaborn as sns
import pandas as pd
import sip
import h5py
import mat73
import numpy as np
class MatplotlibCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width = 5, height = 4, dpi = 120):
fig = Figure(figsize = (width,height))
self.axes = fig.add_subplot(111)
super(MatplotlibCanvas,self).__init__(fig)
fig.tight_layout()
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1466, 910)
font = QtGui.QFont()
font.setFamily("Tahoma")
MainWindow.setFont(font)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView.setGeometry(QtCore.QRect(280, 0, 561, 441))
self.graphicsView.setObjectName("graphicsView")
self.graphicsView_2 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_2.setGeometry(QtCore.QRect(860, 0, 561, 441))
self.graphicsView_2.setObjectName("graphicsView_2")
self.graphicsView_3 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_3.setGeometry(QtCore.QRect(280, 440, 561, 441))
self.graphicsView_3.setObjectName("graphicsView_3")
self.graphicsView_4 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_4.setGeometry(QtCore.QRect(860, 440, 561, 441))
self.graphicsView_4.setObjectName("graphicsView_4")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(40, 90, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.action_Open = QtWidgets.QAction(MainWindow)
self.action_Open.setObjectName("action_Open")
self.action_Save = QtWidgets.QAction(MainWindow)
self.action_Save.setObjectName("action_Save")
self.action_Export = QtWidgets.QAction(MainWindow)
self.action_Export.setObjectName("action_Export")
self.action_Exit = QtWidgets.QAction(MainWindow)
self.action_Exit.setObjectName("action_Exit")
self.filename = ''
self.canv = MatplotlibCanvas(self)
self.df = []
self.toolbar = Navi(self.canv, self.centralwidget)
self.pushButton.clicked.connect(self.getFile)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def getFile(self):
""" this function will get the adress of the mat file location
also calls a readData function
"""
self.filename = QFileDialog.getOpenFileName(filter="mat (*.mat)")[0]
print("File: ", self.filename)
self.readData()
def readData(self):
self.df = mat73.loadmat(self.filename, use_attrdict=True)
struct = self.df['DemoData']
print(struct.Nr.data)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Open "))
self.action_Open.setText(_translate("MainWindow", "&Open"))
self.action_Save.setText(_translate("MainWindow", "&Save"))
self.action_Export.setText(_translate("MainWindow", "&Export"))
self.action_Exit.setText(_translate("MainWindow", "&Quit"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
既然我可以读取数据,下一步就是创建曲面图并显示数据。我的想法是使用 graphicsView 元素来显示四个需要的图,但我找不到如何 link 数字,我在第一个测试程序(没有 GUI)中使用了 graphicsView 元素。对于该图,我使用了以下代码行:
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
surf = ax.plot_surface(pArray, rArray, trArray, alpha = 0.5)
surf = ax.plot_surface(pArray, rArray, tArray, cmap=cm.jet, alpha = 1)
谁能给我一个提示,我是怎么做到的?
编辑:我上传了一个 .mat 文件 .mat File
我要注意的是:
- mat73 无法读取提供的 .mat 所以我使用 scipy.
- .mat 中包含的数据是一维数组,因此它们无法形成曲面,因为需要二维数组,所以我将只展示如何绘制点。
- 由于点数较多,绘画需要时间,可能会卡顿
逻辑是使用 FigureCanvas 并创建 3d 图:
from functools import cached_property
from PyQt5.QtWidgets import QApplication, QFileDialog, QMainWindow
from matplotlib.backends.backend_qt5agg import (
FigureCanvas,
NavigationToolbar2QT as NavigationToolbar,
)
from matplotlib.figure import Figure
from matplotlib import cm
import scipy.io as sio
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ax = self.canvas.figure.add_subplot(projection="3d")
self.setCentralWidget(self.canvas)
self.addToolBar(self.toolbar)
file_menu = self.menuBar().addMenu("&File")
open_action = file_menu.addAction("&Open")
open_action.triggered.connect(self.handle_open_action_triggered)
@cached_property
def canvas(self):
return FigureCanvas()
@cached_property
def toolbar(self):
return NavigationToolbar(self.canvas, self)
def handle_open_action_triggered(self):
filename, _ = QFileDialog.getOpenFileName(self, filter="mat (*.mat)")
if filename:
self.load_mat(filename)
def load_mat(self, filename):
res = sio.loadmat(filename)
record = res["record"]
data = record["Data"]
temp_ref = data[0, 0]["TempRef"][0, 0][0, 0]["data"]
nr = data[0][0]["Nr"][0, 0][0, 0]["data"]
temp_act = data[0, 0]["TempAct"][0, 0][0, 0]["data"]
self.update_plot(temp_ref, nr, temp_act)
def update_plot(self, x, y, z):
print(x.shape, y.shape, z.shape)
self.ax.scatter(x, y, z)
self.canvas.draw()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())