基於PyQt 繪製多個變量的動圖

Pyqt 多參數控制繪圖 採用spinbox 和horizionslider 控制sin曲線的幅值和相位的變換。

主程序如下:

# -*- coding: utf-8 -*-
import sys
import os
import random
import time
import numpy as np
import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from numpy import arange
import pandas as pd
import ControlCanvas


class Ui_MainWindow(object):	
	def setupUi(self, MainWindow):
		MainWindow.setObjectName("MainWindow")
		self.screen = QtWidgets.QDesktopWidget().screenGeometry()
		MainWindow.setGeometry(10, 50, self.screen.width()/4,self.screen.height()/4)
		# MainWindow.resize(self.screen.width()/4,self.screen.height()/4)
		# MainWindow.showMaximized()
		self.centralWidget = QtWidgets.QWidget(MainWindow)
		self.centralWidget.setObjectName("centralWidget")
		MainWindow.setCentralWidget(self.centralWidget)
		self.testing = [0,0]
####################################################################################
		#QGridLayout
		self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
		self.gridLayout.setSpacing(2)
		self.gridLayout.setObjectName("gridLayout")
		#splitter
		self.splitter = QtWidgets.QSplitter(orientation=QtCore.Qt.Horizontal)
		self.gridLayout.addWidget(self.splitter,1,0,8,0)
		self.splitter.setSizes([self.splitter.size().height() * 0.8, self.splitter.size().height() * 0.2])
		# Canvas
		self.main_widget = QWidget()
		self.dc = ControlCanvas.MyControlMplCanvas(self.main_widget, width=5, height=4, dpi=100)
		self.splitter.addWidget(self.dc)
		# self.gridLayout.addWidget(self.dc,rowspan=-1)
		#
		#QVBoxLayout
		self.verticallayout = QtWidgets.QVBoxLayout()
		# self.verticallayout.setContentsMargins(11, 11, 11, 11)
		self.verticallayout.setSpacing(6)
		self.verticallayout.setObjectName("verticallayout")
		self.gridLayout.addLayout(self.verticallayout, 0, 1)
		#
		self.lb = []
		self.hs = []
		self.sp = []
		self.echoGroup =  QtWidgets.QGroupBox('Echo')
		self.echoLayout = QtWidgets.QGridLayout()
		self.echoGroup.setLayout(self.echoLayout)
		sp_inital_value = [0.,0.]
		sp_range = [[0,9999.],[0.,500.]]
		lb_name = ['a','b']
	
		for i in range(2):
			self.lb.append(i);self.hs.append(i);self.sp.append(i)
			self.lb[i] = QtWidgets.QLabel(lb_name[i])
			self.echoLayout.addWidget(self.lb[i],i+1,0)
			self.hs[i] = QtWidgets.QSlider(self.centralWidget)
			self.hs[i].setOrientation(QtCore.Qt.Horizontal)
			self.hs[i].setRange(sp_range[i][0],sp_range[i][1])
			self.echoLayout.addWidget(self.hs[i],i+1,2)

			self.sp[i] = QtWidgets.QDoubleSpinBox()
			self.sp[i].setDecimals(5)

			self.sp[i].setValue(sp_inital_value[i])
			self.sp[i].setSingleStep(1) 
			self.sp[i].setRange(sp_range[i][0],sp_range[i][1])
			self.echoLayout.addWidget(self.sp[i],i+1,1)
			self.hs[i].valueChanged.connect(self.sp[i].setValue)
			self.sp[i].valueChanged.connect(self.hs[i].setValue)
			self.hs[i].sliderReleased.connect(lambda: self.dc.update_figure(self.figure_args()))
			self.sp[i].valueChanged.connect(lambda: self.dc.update_figure(self.figure_args()))
		self.splitter.addWidget(self.echoGroup)
		#
		
	def figure_args(self):		
		return [self.sp[i].value() for i in range(2)]

####################################################################################
if __name__ == "__main__":
	app = QtWidgets.QApplication(sys.argv)
	ex = Ui_MainWindow()
	w = QtWidgets.QMainWindow()
	ex.setupUi(w)
	w.show()
	sys.exit(app.exec_())
####################################################################################

Canvas相關的控制變量 

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np

class MyMplCanvas(FigureCanvas):
	def __init__(self, parent=None, width=50, height=50, dpi=100):
		fig = Figure(figsize=(width, height), dpi=dpi)
		self.axes = fig.add_subplot(111)
		# 每次plot()調用的時候,我們希望原來的座標軸被清除(所以False)
		self.compute_initial_figure()
 
		#
		FigureCanvas.__init__(self, fig)
		self.setParent(parent)
 
		FigureCanvas.setSizePolicy(self,
									QSizePolicy.Expanding,
									QSizePolicy.Expanding)
		self.axes.set_xlabel('Strain[-]')
		self.axes.set_ylabel('Stress[GPa]')
		FigureCanvas.updateGeometry(self)
 
	def compute_initial_figure(self):
		pass
 
class MyControlMplCanvas(MyMplCanvas):#
	def __init__(self, *args, **kwargs):
		MyMplCanvas.__init__(self, *args, **kwargs)
 
	def compute_initial_figure(self):
		self.axes.plot([0, 0, 0, 0], [1, 2, 3, 4], 'r')
 
	def update_figure(self,*args):
		print (args)
		args= args[0]
		a = args[0];b = args[1];
		x = np.arange(0.0, 3., 0.01)
		self.axes.cla()
		y = self.func1(a,b,x)
		self.axes.plot(x, y)
		self.axes.grid('on')
		self.draw()
		
	def func1(self,a,b,x):
		value = a*np.sin(x*np.pi+b)
		return value

 

 

發佈了14 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章