Skip to content

Instantly share code, notes, and snippets.

@eyllanesc
Last active December 19, 2023 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eyllanesc/47a3e2e650e299958979890eb006fd0a to your computer and use it in GitHub Desktop.
Save eyllanesc/47a3e2e650e299958979890eb006fd0a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
#Importing PyQt5 library to construct widgets for Graphic User Interface (GUI) application
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import (QLineEdit, QPushButton, QSlider, QApplication, QVBoxLayout, QHBoxLayout,
QApplication, QWidget, QLabel, QCheckBox, QRadioButton, QPlainTextEdit, QSizePolicy,
QMainWindow,QFrame, QFileDialog, QTableWidgetItem, QTableWidget, QMenu, QMessageBox,
QAction, QToolBar)
from PyQt5.QtCore import Qt, QAbstractTableModel, pyqtSignal
import matplotlib
matplotlib.use("Qt5Agg")
from numpy import arange, sin, pi
from matplotlib import pyplot as plt
#Backend door for matplotlib importation required to use Pyqt with matpltlib libray
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationBar
from matplotlib.figure import Figure
import csv
import pandas as pd
import numpy as np
"""
### PYQT LEGEND ###
Qlabel = block of text non-interactable
QPushButton = ordinary button that can be pushed/interacted with
QLineEdit = text input box and can be interacted with
QSlider = slider widget moved back/forth up/down to change the value of something
QCheckbox = interactable checkbox
"""
#Create Canvas to plot data on
# class CanvasCreation(FigureCanvas):
#
# def __init__(self, parent):
# self.figure = Figure()
# self.axes = self.figure.add_subplot(111)
# self.axes.hold(False)
#
# #draws the figure
# FigureCanvas.__init__(self, self.figure)
#
# self.axes.legend()
#
# FigureCanvas.setSizePolicy(self,
# QSizePolicy.Expanding,
# QSizePolicy.Expanding)
# FigureCanvas.updateGeometry(self)
#
# class MatpltWidget(QWidget): #MatpltlibWidget
# def __init__(self, parent=None):
# QWidget.__init__(self, parent)
# self.canvas = CanvasCreation()
# self.vboxRight.addWidget(self.canvas)
# def Plotter(self, ydata, xdata):
# x = range(0, 10)
# y = range(0, 20, 2)
# self.canvas.axes.plot(x,y)
# self.canvas.draw()
"""
Purpose of CanvasCreation is to initialize the creation of a canvas where graphs and plots can be displayed on and inherit aspects of the class
"""
class CanvasCreation(FigureCanvas):
def __init__(self, parent):
#Create an object figure where a graph(s) can be displayed
self.figure = Figure()
#defines a variable axes to besubplot where we will plot our data. The numbers 111 represent plot sub-number
self.axes = self.figure.add_subplot(111)
#this resets the canvas each time the class is called (clears)
self.axes.hold(False)
#NOTESELF:need to grab a class to get the data
#self.x = np.arange(0.0, 5, 0.01)
#self.y = np.cos(1 * np.pi * self.x)
#self.axes.plot(self.x, self.y)
#draws the figure
FigureCanvas.__init__(self, self.figure)
self.axes.legend()
FigureCanvas.setSizePolicy(self,
QSizePolicy.Expanding,
QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
class Plotter(CanvasCreation):
print("in plotter")
def __init__(self, y_data, x_data): #mutltiple graphs???, overlay, side by side??, GraphHeader, x_title, y_title
print("in initialization")
#super(MainWindow, self).__init__()
self.figure = Figure()
self.axes = self.figure.add_subplot(111)
print("data is about to be defined")
print(y_data)
print(x_data)
self.x = np.arange(0.0, 5.0, 0.01)
self.y = np.cos(5 * np.pi * self.x)
#self.x = [0,1,2,3,4,5,6,7,8,9]
#self.y = y_data
print("data has been defined about to plot")
self.axes.plot(self.x, self.y)
print("after plot next step is draw")
FigureCanvas.__init__(self, self.figure)
self.show()
#self.figure.canvas.draw()
#self.vboxRight.addWidget(self.axes)
print("data has been assigned right before plot is called")
class MainWindow(QMainWindow):
"""
MainWindow class will be the centeral widget and main screen for application
Inherits behavior from the class QMainWindow from PyQt5 library.
*see index for difference between QMainWindow and QWidget
Purpose: Creation of widgets and controls their layout
"""
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("Perspective")
self.initializeUI()
def initializeUI(self):
#Main Widget
self.main_widget = QWidget(self)
self.setCentralWidget(self.main_widget)
#CREATION OF WIDGETS
# <editor-fold desc="Widgets Creation Site">
###Graph Title Entry###
#button and line entry made to change the name of the graph before or after data has been plotted
self.TitlEdit = QLineEdit('Graph Title')
self.TitleBtn = QPushButton('Enter')
###first file###
#buttons associated with the first browse button
"""
Buttons related to the first file being uploaded
"""
self.FileNmLabel = QLabel('FileName')
self.FileNameEdit = QLineEdit('"Filename"')
self.BrowseBtn = QPushButton('Browse')
self.OpacityLabel = QLabel('Opacity')
self.OpacitySlider = QSlider(Qt.Horizontal)
self.OpacitySlider.setMinimum(0)
self.OpacitySlider.setMaximum(100)
self.OpacitySlider.setValue(100)
self.OpacitySlider.setTickInterval(10)
self.OpacitySlider.setTickPosition(QSlider.TicksBelow)
self.ShowChkbx = QCheckBox('show')
###Plot Selection###
#Radiobuttons are choosen because the difference between radio and check buttons are that only one radio button can be selected at any given time
#give user ability to choose between Boxplot, whisker, or scatter
self.BoxPlt = QRadioButton('Box Plot')
self.WhiskerPlt = QRadioButton('Whisker Plot')
self.ScatterPlt = QRadioButton('Scatter Plot')
#NOTE SELF:for functionality .toggled() might be more appropriate than .clicked()
###Overlay Plot###
#checkbox to give user ability to overlay data
self.Overlay = QCheckBox('Overlay Plots')
#self.canvas....
# <editor-fold desc="Trend Report Button Repetition">
###2nd trend report###
self.FileNmLabel2 = QLabel('FileNames')
self.FileNameEdit2 = QLineEdit('')
self.BrowseBtn2 = QPushButton('Browse')
self.OpacityLabel2 = QLabel('Opacity')
self.OpacitySlider2 = QSlider(Qt.Horizontal)
self.OpacitySlider2.setMinimum(0)
self.OpacitySlider2.setMaximum(100)
self.OpacitySlider2.setValue(100)
self.OpacitySlider2.setTickInterval(10)
self.OpacitySlider2.setTickPosition(QSlider.TicksBelow)
self.ShowChkbx2 = QCheckBox('show')
###3rd report###
self.FileNmLabel3 = QLabel('FileNames')
self.FileNameEdit3 = QLineEdit('')
self.BrowseBtn3 = QPushButton('Browse')
self.OpacityLabel3 = QLabel('Opacity')
self.OpacitySlider3 = QSlider(Qt.Horizontal)
self.OpacitySlider3.setMinimum(0)
self.OpacitySlider3.setMaximum(100)
self.OpacitySlider3.setValue(100)
self.OpacitySlider3.setTickInterval(10)
self.OpacitySlider3.setTickPosition(QSlider.TicksBelow)
self.ShowChkbx3 = QCheckBox('show')
###TEXT EDIT TEST WIDGET
self.TextEdit = QPlainTextEdit()
# </editor-fold>________________________________________END OF TREND REPORTS
###PLOT###________________________________________________________EXPIREMENTAL AF
#self.figure = Figure() # don't use matplotlib.pyplot at all!
#self.canvas = FigureCanvas(self.figure)
self.canvas = CanvasCreation(self.main_widget)
self.NavBar = NavigationBar(self.canvas, self.main_widget)
# </editor-fold> ________________________________________END OF CREATION WIDGETS
#Button Functionality___________________________________________________________________________________________
# <editor-fold desc="Button Functionality">
###Graph Title###
self.TitleBtn.clicked.connect(self.TitleClicked)
#import1
self.BrowseBtn.clicked.connect(self.import1)
self.OpacitySlider.valueChanged.connect(self.OpacityVal)
###GraphChoice###
#self.CatDogBtn.clicked.connect(lambda :self.CatDog_click(self.RadioBtn1.isChecked(), self.RadioLabel))
#self.BoxPlt.toggled.connect(lambda: self.PlotChoice(self.WhiskerPlt.isChecked(), self.ScatterPlt.isChecked()))
self.BoxPlt.clicked.connect(self.PlotChoice)
self.WhiskerPlt.clicked.connect(self.PlotChoice)
self.ScatterPlt.clicked.connect(self.PlotChoice)
##Table###
# </editor-fold>_____________________________________________________________________END OF BUTTON FUNCTIONALITY
#Widget Layout
# <editor-fold desc="Layout">
self.hMAIN = QHBoxLayout(self.main_widget)
###Graph Title###
self.hbox = QHBoxLayout()
self.hbox.addWidget(self.TitlEdit)
self.hbox.addWidget(self.TitleBtn)
self.hbox.addStretch()
###First File Labels###
self.hbox2 = QHBoxLayout()
self.hbox2.addWidget(self.FileNmLabel)
self.hbox2.addStretch()
self.hbox2.addWidget(self.OpacityLabel)
###First File Widgets###
self.hbox3 = QHBoxLayout()
self.hbox3.addWidget(self.FileNameEdit)
self.hbox3.addWidget(self.BrowseBtn)
self.hbox3.addWidget(self.OpacitySlider)
self.hbox3.addWidget(self.ShowChkbx)
###Plot Types###
self.hbox4 = QHBoxLayout()
self.hbox4.addWidget(self.BoxPlt)
self.hbox4.addWidget(self.WhiskerPlt)
self.hbox4.addWidget(self.ScatterPlt)
###OverLay###
self.hbox5 = QHBoxLayout()
self.hbox5.addWidget(self.Overlay)
#________________________________________________Additional Trend Reports
# <editor-fold desc="ADDITIONAL TREND REPORTS">
###Second File Labels###
self.hbox6 = QHBoxLayout()
self.hbox6.addWidget(self.FileNmLabel2)
self.hbox6.addStretch()
self.hbox6.addWidget(self.OpacityLabel2)
###Second File Widgets###
self.hbox7 = QHBoxLayout()
self.hbox7.addWidget(self.FileNameEdit2)
self.hbox7.addWidget(self.BrowseBtn2)
self.hbox7.addWidget(self.OpacitySlider2)
self.hbox7.addWidget(self.ShowChkbx2)
###3rd File Widgets###
self.hbox8 = QHBoxLayout()
self.hbox8.addWidget(self.FileNmLabel3)
self.hbox8.addStretch()
self.hbox8.addWidget(self.OpacityLabel3)
###Second File Widgets###
self.hbox9 = QHBoxLayout()
self.hbox9.addWidget(self.FileNameEdit3)
self.hbox9.addWidget(self.BrowseBtn3)
self.hbox9.addWidget(self.OpacitySlider3)
self.hbox9.addWidget(self.ShowChkbx3)
# </editor-fold>
self.vbox = QVBoxLayout()
self.vbox.addLayout(self.hbox)
self.vbox.addLayout(self.hbox2)
self.vbox.addLayout(self.hbox3)
self.vbox.addLayout(self.hbox4)
self.vbox.addLayout(self.hbox5)
self.vbox.addLayout(self.hbox6)
self.vbox.addLayout(self.hbox7)
self.vbox.addLayout(self.hbox8)
self.vbox.addLayout(self.hbox9)
self.vboxRightBottom = QVBoxLayout()
self.vboxRIGHT = QVBoxLayout()
#vboxRIGHT.addWidget(Plot)
self.vboxRIGHT.addWidget(self.canvas)
self.vboxRIGHT.addWidget(self.NavBar)
self.vboxRIGHT.addLayout(self.vboxRightBottom)
self.hMAIN.addLayout(self.vbox)
self.hMAIN.addLayout(self.vboxRIGHT)
# </editor-fold>___________________________________________________________________________________END OF LAYOUT
self.show()
def import1(self):
###Actual importation and manipulation of Data CSV Files
fileName, _ = QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "",
"(*.csv)")
if fileName:
print(fileName)
self.FileNameEdit.setText(fileName)
Data = pd.read_csv(open(fileName))
print(Data)
self.BaseStats = Data.drop('Nominal Value', axis=1)
self.BaseStats.drop('median', axis=1, inplace=True)
self.BaseStats.drop('Tolerance', axis=1, inplace=True)
self.BaseStats.drop('mean', axis=1, inplace=True)
self.BaseStats.drop('min', axis=1, inplace=True)
self.BaseStats.drop('max', axis=1, inplace=True)
self.BaseStats.drop('range', axis=1, inplace=True)
self.BaseStats.drop('Deviation', axis=1, inplace=True)
self.BaseStats.drop('variance', axis=1, inplace=True)
self.BaseStats.drop('Standard Deviation', axis=1, inplace=True)
self.BaseStats.drop('LowerBound', axis=1, inplace=True)
self.BaseStats.drop('UpperBound', axis=1, inplace=True)
self.BaseStats.drop('Unnamed: 0', axis=1, inplace=True)
#print("Data has been dropped")
rowHeaders = self.BaseStats.index
colHeaders = self.BaseStats.columns.values
col = len(colHeaders)
row = len(rowHeaders)
print("table is about to be made")
self.Table = CreateTable(self.BaseStats, row, col, colHeaders, rowHeaders)
self.Table.dataSignal.connect(self.dataPlotter)
self.vboxRightBottom.addWidget(self.Table)
def PlotChoice(self):
sender = self.sender()
if sender.text() == "Whisker Plot":
#set the graph to whisker plot
print("whisker plot has been selected")
elif sender.text() == "Box Plot":
print("Box Plot has been selected")
else:
print("Scatter Plot has been selected")
def TitleClicked(self):
print("Enter Title")
sender = self.sender()
if sender.text() == "Enter":
ax.set_title(self.TitlEdit.text())
self.canvas.draw()
def OpacityVal(self):
print("Opacity value is being changed")
def dataPlotter(self, x_data,y_data):
self.Graph = Plotter(x_data, y_data)
self.vboxRightBottom.addWidget(self.Graph)
class CreateTable(QTableWidget): #QTableWidget
dataSignal = pyqtSignal(list, np.ndarray)
def __init__(self, Data, row, col, colHeaders, rowHeaders): #Index, ColumnHeaders
super(CreateTable, self).__init__()
self.setSelectionBehavior(self.SelectRows)
print("Start initialization")
self.ColHeader = colHeaders
self.setRowCount(row)
self.setColumnCount(col)
self.data = Data
self.setHorizontalHeaderLabels(colHeaders)
print("Right before for loop")
n = len(Data)
m = len(colHeaders)
for i in range(n):
DataValues = self.data.iloc[i,:]
print("values are {}".format(DataValues))
#m = len(values)
ConvertedVals = pd.to_numeric(DataValues)
ValList = DataValues.values.tolist()
print(ValList)
for j in range(0,m):
self.item = QTableWidgetItem(str(round(ValList[j],5)))
#print("{}, {}".format(i, j))
self.setItem(i,j, self.item)
def contextMenuEvent(self, event):
menu = QMenu(self)
graphAction = menu.addAction("Graph")
compareAction = menu.addAction("Compare")
scatterAction = menu.addAction("Plot types")
aboutAction = menu.addAction("about")
quitAction = menu.addAction("quit")
printAction = menu.addAction("Print Row")
action = menu.exec_(self.mapToGlobal(event.pos()))
if action == quitAction:
qApp.quit()
elif action == printAction:
self.selected = self.selectedItems()
n = len(self.selected)
print("n is {}".format(n))
for i in range(n):
self.selected[i] = str(self.selected[i].text())
for i in range(n):
self.selected[i] = float(self.selected[i])
print(self.selected)
elif action == graphAction:
self.selected = self.selectedItems()
n = len(self.selected)
for i in range(n):
self.selected[i] = str(self.selected[i].text())
for i in range(n):
self.selected[i] = float(self.selected[i])
print("right before plotter called")
print(type(self.selected), type(self.ColHeader))
self.dataSignal.emit(self.selected, self.ColHeader)
else:
print("u clicked something other than quit")
def main():
#main loop
app = QtWidgets.QApplication(sys.argv)
#instance
appWindow = MainWindow()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Unnamed: 0 8 ALPHA ER ROM S10 ASCST 4-12-2017 8 ALPHA ER ROM S9 ASCST 4-12-2017 8 ALPHA ER ROM S8 ASCST 4-12-2017 8 ALPHA ER ROM S7 ASCST 4-12-2017 8 ALPHA ER ROM S6 ASCST 4-12-2017 8 ALPHA ER ROM S5 ASCST 4-12-2017 8 ALPHA ER ROM S4 ASCST 4-12-2017 8 ALPHA ER ROM S3 ASCST 4-12-2017 8 ALPHA ER ROM S2 ASCST 4-12-2017 8 ALPHA ER ROM S1 ASCST 4-12-2017 Nominal Value Tolerance mean median min max range Deviation variance Standard Deviation LowerBound UpperBound
0 0.012 0.014 0.012 0.016 0.013 0.023 0.015 0.009 0.007 0.014 0.02 0.0135 0.0135 0.007 0.023 0.016 0 0
1 9.79 9.792 9.801 9.792 9.796 9.817 9.795 9.788 9.796 9.8 9.832 ア0.03 9.7967 9.7955 9.788 9.817 0.029 0.0353 0.0001 0.01 9.802 9.862
2 25.637 25.656 25.861 25.652 25.641 25.397 25.425 25.551 25.459 25.582 25 ア1 25.5861 25.6095 25.397 25.861 0.464 -0.5861 0.0188 0.137113092 24 26
3 0.02 0.013 0.025 0.022 0.017 0.019 0.019 0.014 0.016 0.014 0.063 0.0179 0.018 0.013 0.025 0.012 0 0
4 0.028 0.018 0.028 0.028 0.019 0.046 0.025 0.024 0.017 0.021 0.02 0.0254 0.0245 0.017 0.046 0.029 0.0001 0.01
@beatles0
Copy link

great source~!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment