在 GUI 中创建多个曲面图
Posted
技术标签:
【中文标题】在 GUI 中创建多个曲面图【英文标题】:Create multiple surface plots in GUI 【发布时间】:2021-10-25 14:59:41 【问题描述】:所以我刚刚开始了一个新项目,我需要在其中展示我在 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 元素来显示四个需要的图,但我只是找不到如何链接这些数字,我在第一个测试程序(没有 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
【问题讨论】:
请分享一些.mat @eyllanesc 我将链接添加到 .mat 文件中,我将用于曲面图 如何读取此文件以获取 X、Y 和 Z? 我可以读取数据:TempRef、Nr 和 TempAct,但它们是 1162334x1 数组,但它们不会形成表面,因为为此它们需要是二维数组 【参考方案1】:我必须注意:
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_())
【讨论】:
感谢您的代码。当我删除一些不允许共享的数据点时,Matlab 似乎更改了 .mat 文件。这一定是 mat73 不起作用的原因。我从录音软件收到的 .mat 文件只需使用 mat73 即可读取。我和你分享的数据,其实就是我用来计算的数据,我只是用三个数组创建了需要的数组。 我只是尝试使用您提供的代码更新我的代码,但我没有得到绘图。我没有得到以下几点:我使用的是'class Ui_MainWindow(object)',但你使用的是'MainWindow(QMainWindow)',有什么区别?我正在使用 QT Desinger 创建代码。另外我该如何设置情节的位置。在我的 GUI 中,我需要同时显示四个曲面图。这就是为什么我创建了这么大的主窗口 @user3794592 阅读***.com/questions/46544780/… 感谢您的链接。我将更新我的代码,以使用 logic.py 和 Design.py 现在更新了我的代码,使图形显示在主窗口中。所以效果很好。但是如何设置绘图的几何形状(图形的大小和位置)?我还想在一个屏幕上显示四个图。为此,我可以创建子图的多个实例并多次调用 update_plot() 方法吗?以上是关于在 GUI 中创建多个曲面图的主要内容,如果未能解决你的问题,请参考以下文章