Last active
December 19, 2023 13:54
-
-
Save eyllanesc/47a3e2e650e299958979890eb006fd0a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
great source~!