├── README.md
├── README.md~
├── Pivot_Tables_Pandas_2014_07_18_GUI_V3_beta.py~
└── Pivot_Tables_Pandas_2014_07_18_GUI_V3_beta.py
/README.md:
--------------------------------------------------------------------------------
1 | NOTE - this software is not YET generalized. I will release a fully-working version in the near future. Stay tuned...
2 |
3 | Description: Tool to create pivot tables and make figures, using python and pandas.
4 |
5 | - [ ] Rename match excel convention - filters, columns, rows, values
6 | - [ ] Add filter capability for pivot tables.
7 | - [ ] Ability to change y-axis values in real-time.
8 | - [x] Add list widget - show what you have plotted previously.
9 | - [x] Remove all MPL figures that are real-time.
10 | - [x] Fix it so that every time new file is open, it does not create 3 new tabs.
11 | - [x] Fix how the Plot legend displays (text overlaps)
12 | - [x] Fix how plot legend overwrites old legends (make it clear).
13 | - [x] Fix combo box values that repeat
14 | - [x] Make the check marks display better - use a grid pattern.
15 | - [x] Make real-time plot display, with tabbed interface in GUI.
16 | - [x] Label x-axis in plots.
17 | - [x] Fix axes labeling.
18 | - [x] filled symbols with symbolBrush.
19 |
--------------------------------------------------------------------------------
/README.md~:
--------------------------------------------------------------------------------
1 | NOTE - this software is not YET generalized. I will release a fully-working version in the near future. Stay tuned...
2 |
3 | Description: Tool to create pivot tables and make figures, using python and pandas.
4 |
5 | - [ ] Rename match excel convention - filters, columns, rows, values
6 | - [ ] Add filter capability for pivot tables.
7 | - [ ] Ability to change y-axis values in real-time.
8 | - [x] Add list widget - show what you have plotted previously.
9 | - [x] Remove all MPL figures that are real-time.
10 | - [x] Fix it so that every time new file is open, it does not create 3 new tabs.
11 | - [x] Fix how the Plot legend displays (text overlaps)
12 | - [x] Fix how plot legend overwrites old legends (make it clear).
13 | - [x] Fix combo box values that repeat
14 | - [x] Make the check marks display better - use a grid pattern.
15 | - [x] Make real-time plot display, with tabbed interface in GUI.
16 | - [x] Label x-axis in plots.
17 | - [x] Fix axes labeling.
18 | - [x] filled symbols with symbolBrush.
19 |
--------------------------------------------------------------------------------
/Pivot_Tables_Pandas_2014_07_18_GUI_V3_beta.py~:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @author: mdb52
4 | """
5 |
6 | from __future__ import division
7 |
8 | # These allow mpl in PyQt
9 | from PyQt4.QtGui import QSizePolicy
10 | from PyQt4.QtCore import QSize
11 |
12 | import numpy as np
13 | import seaborn as sb
14 | from pylab import *
15 | import pandas as pd
16 | import itertools
17 | import matplotlib._pylab_helpers
18 | from PyQt4 import *
19 |
20 | import pyqtgraph as pg
21 |
22 | """
23 | This loads CSV of all fiber data and plots various parameters from pivot tables
24 |
25 | Must use SELF.COMMAND when you want to access that value outside of the function (gets stored to the class)
26 |
27 | GUI V1: beta just barely works
28 | V2: improving the "Real Time capability"
29 | V3: uses pyqtplot -- for real time plot, and fixed GUI layout
30 | started using GIT and GIT-HUB
31 |
32 | """
33 |
34 | def setSeabornParams():
35 | # Talk seems to be best choice for font size
36 | sb.set_context("talk")
37 |
38 | # use "cubehelix" colormap for printing; hls is used for SB
39 | # sb.palplot(sb.color_palette("jet", 8))
40 | sb.set_palette(sb.color_palette("jet", 8))
41 | sb.set_palette("jet",8)
42 |
43 | def loadData(fname):
44 | data = pd.read_csv(fname)
45 | return data;
46 |
47 | def filterGoodValues(data):
48 | print('Size before filtering: '+repr(np.shape(data)))
49 | print('FILTERING PERFORMED')
50 | # Remove rows that have yes in either column:
51 | # 'Not a new calibration?' and 'Diode Measured Scatter or Cerenov?'
52 | data = data[data.loc[:,'Not a new calibration?'] != 'Yes']
53 | data = data[data.loc[:,'Diode Measured Scatter or Cerenkov?'] != 'Yes']
54 | print('Size after filtering: '+repr(np.shape(data)))
55 | return data
56 |
57 | def plotBoxValues(data, value_list, row, col, showMPL):
58 | for xx in value_list:
59 | #Make a pivot table for every value
60 |
61 | table1 = pd.pivot_table(data, values=xx,
62 | rows=row, cols=col, dropna=True)
63 |
64 | # drop if all data is missing in an axis
65 | print('Size before removing nan: '+repr(np.shape(table1)))
66 | table1 = table1.dropna(axis=0, how='all')
67 | table1 = table1.dropna(axis=1, how='all')
68 | print('Size after removing nan: '+repr(np.shape(table1)))
69 |
70 | if showMPL == True:
71 |
72 | # GET N
73 | N_table1 = table1.count(axis=0)
74 | N_table1_T = table1.count(axis=1)
75 |
76 | # Get Avg
77 | meanX = table1.mean()
78 | meanY = table1.T.mean()
79 |
80 | print('Mean x, y: ' + repr(meanX) + ', ' + repr(meanY))
81 |
82 | p1=figure(figsize=(11,8))
83 | sb.set_palette("jet",8)
84 | table1.boxplot()
85 | title(xx + ' By '+col)
86 | yscale('log')
87 | xlabel(col, fontsize=12, fontweight='bold')
88 |
89 | locs, labels = xticks()
90 | ymin, ymax = ylim()
91 |
92 | for index in range(len(locs)):
93 | text(locs[index], 1.2*ymin, 'N: '+repr(N_table1.iloc[index]),
94 | horizontalalignment='center')
95 | text(locs[index], 2*ymin, '$\\bar{x}$: ' +'%.2g'%meanX.iloc[index],
96 | horizontalalignment='center')
97 |
98 |
99 | p2=figure(figsize=(11,8))
100 | sb.set_palette("jet",8)
101 | table1.T.boxplot()
102 | title(xx + ' By '+row)
103 | yscale('log')
104 | xticks(rotation=90)
105 | xlabel(row, fontsize=12, fontweight='bold')
106 |
107 | locs, labels = xticks()
108 | ymin, ymax = ylim()
109 |
110 | for index in range(len(locs)):
111 | text(locs[index], 1.2*ymin, 'N: '+repr(N_table1_T.iloc[index]),
112 | horizontalalignment='center')
113 |
114 | text(locs[index], 2*ymin, '$\\bar{x}$: ' +'%.2g'%meanY.iloc[index],
115 | horizontalalignment='center')
116 | show()
117 |
118 | return table1;
119 |
120 | class Table(QtGui.QDialog):
121 | def __init__(self, parent=None):
122 | super(Table, self).__init__(parent)
123 | layout = QtGui.QGridLayout()
124 | self.table = QtGui.QTableWidget(self) # Parent of table
125 | layout.addWidget(self.table, 0, 0)
126 | self.setLayout(layout)
127 |
128 | class MainWindow(QtGui.QMainWindow):
129 |
130 | def __init__(self):
131 | super(MainWindow, self).__init__()
132 |
133 | self.initUI()
134 |
135 | self.loadedData = []
136 | self.filteredData = []
137 | self.checkBoxList = []
138 | self.pivotData = []
139 |
140 | def setLoadedData(self, setValue):
141 | self.loadedData = setValue
142 |
143 | def setFilteredData(self, setValue):
144 | self.filteredData = setValue
145 |
146 | def setPivotData(self, setValue):
147 | self.pivotData = setValue
148 |
149 | def initUI(self):
150 |
151 | self.setWindowTitle('Main Program')
152 |
153 | exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self)
154 | exitAction.triggered.connect(QtGui.qApp.quit)
155 |
156 | self.statusBar()
157 |
158 | # For tabbed widgets, do not specify a parent
159 | mainWidget = QtGui.QWidget()
160 |
161 | # Quit Button
162 | btn_quit = QtGui.QPushButton('Quit', mainWidget)
163 | btn_quit.clicked.connect(QtCore.QCoreApplication.instance().quit)
164 | btn_quit.setToolTip('This is a QPushButton widget')
165 | btn_quit.resize(btn_quit.sizeHint())
166 |
167 | # Plot data button
168 | btnPlot = QtGui.QPushButton('Plot Data', mainWidget)
169 | btnPlot.setToolTip('This will plot the Displayed Data')
170 | btnPlot.resize(btnPlot.sizeHint())
171 |
172 | btnFilter = QtGui.QPushButton('Filter Data, Make Pivot', mainWidget)
173 | btnFilter.setToolTip('You can remove types of data from analysis here')
174 | btnFilter.resize(btnFilter.sizeHint())
175 |
176 | # LOAD DATA AND SAVE TO A VARIABLE
177 | openFile = QtGui.QAction(QtGui.QIcon('open.png'), 'Open', mainWidget)
178 | openFile.setShortcut('Ctrl+O')
179 | openFile.setStatusTip('Open new File')
180 | openFile.triggered.connect(self.openFileDialog)
181 |
182 | # Define what happens when buttons are clicked
183 | btnFilter.clicked.connect(self.filterClicked)
184 | btnPlot.clicked.connect(self.plotClicked)
185 |
186 | # make a list of values already plotted
187 | self.listPlotted = QtGui.QListWidget()
188 | self.listPlotted.resize(256,192)
189 |
190 |
191 | # Drop down select combo box
192 | lbl1 = QtGui.QLabel('Series', mainWidget)
193 | self.combo = QtGui.QComboBox(mainWidget)
194 |
195 | # Drop down select combo box
196 | lbl2 = QtGui.QLabel('X-Axis', mainWidget)
197 | self.combo2 = QtGui.QComboBox(mainWidget)
198 |
199 | # Troubleshooting print button
200 | btn_test = QtGui.QPushButton('Troubleshoot', mainWidget)
201 | btn_test.resize(btn_test.sizeHint())
202 | btn_test.clicked.connect(self.troubleshootClicked)
203 |
204 | # Check box to show MPL figures in addition to real time
205 | self.checkMPL = QtGui.QCheckBox("Enable MPL")
206 |
207 | # Plot Widget
208 | self.plotWindow = pg.PlotWidget()
209 | self.plotWindow.resize(self.plotWindow.sizeHint())
210 |
211 | # Grid LAYOUT 4 rows, 8 columns
212 | nRows = 8; nCols = 12
213 | layout = QtGui.QGridLayout()
214 | # addItem (self, QLayoutItem item, int row,
215 | # int column, int rowSpan = 1, int columnSpan = 1, Qt.Alignment alignment = 0)
216 | layout.addWidget(btn_test, 0, 0) # Goes in upper left
217 | layout.addWidget(btnFilter, 1, 0) # Goes in middle left
218 | layout.addWidget(btnPlot, 2, 0)
219 | layout.addWidget(btn_quit, nRows, 0) # Bottom left
220 | layout.addWidget(self.checkMPL, 3, 0)
221 | layout.addWidget(lbl1, 4, 1)
222 | layout.addWidget(self.combo, 4, 0)
223 | layout.addWidget(lbl2, 5, 1)
224 | layout.addWidget(self.combo2, 5, 0)
225 | layout.addWidget(self.listPlotted, 6, 0, 1, 2)
226 | layout.addWidget(self.plotWindow, 0, 2, nRows, nCols)
227 |
228 | mainWidget.setLayout(layout)
229 |
230 | # Add a tab bar with widgets (tab 1 is options and figure, tab 2 is table)
231 | self.tabBar = QtGui.QTabWidget(self)
232 | self.tabBar.addTab(mainWidget, "Plot Settings")
233 |
234 | # Add MENU Bar - goes mainWindow
235 | menuBar = self.menuBar()
236 | fileMenu = menuBar.addMenu('&File')
237 | fileMenu.addAction(openFile)
238 | fileMenu.addAction(exitAction)
239 |
240 | # SET Tabbed WIDGET AS CENTRAL
241 | self.setCentralWidget(self.tabBar)
242 |
243 | self.setGeometry(50, 50, 1200, 600) # x,y for corner and then x-y widths
244 | self.show()
245 |
246 | def plotReal(self, axes):
247 | self.plotWindow.clear() # refresh if old data is here
248 | print(np.asarray(self.pivotData))
249 | xVals = self.pivotData.columns.tolist()
250 | xVals = [str(x) for x in xVals]
251 | yVals = self.pivotData.index.tolist()
252 | yVals = [str(x) for x in yVals]
253 |
254 |
255 | print('x: '+repr(xVals))
256 | print('y: '+repr(yVals))
257 |
258 | # Delete any old legends
259 | try:
260 | legend = self.plotWindow.plotItem.legend
261 | legend.scene().removeItem(legend)
262 | except Exception, err:
263 | print('Error: '+repr(err))
264 | pass
265 | self.plotWindow.addLegend((100,100)) # This must go above the plot calls
266 | colorValues = ['r','g','b','c','m','y','k','w']
267 | colorCycles = itertools.cycle(colorValues)
268 | for ind, each in enumerate(np.asarray(self.pivotData)):
269 | color = colorCycles.next()
270 | self.plotWindow.plot(each, name=yVals[ind], symbol='o', symbolPen = color, pen =color, symbolBrush = color)
271 |
272 | self.plotWindow.setLabel('left', self.valuePlot)
273 | self.plotWindow.setLabel('bottom', self.combo2.currentText())
274 |
275 | # Make tick labels
276 | xAxis = self.plotWindow.getAxis('bottom')
277 | newTicks = zip(range(len(xVals)), (xVals))
278 | print('New Ticks: '+repr(newTicks))
279 | # xAxis.setStyle(autoExpandTextSpace = 1) # not out until version 0.9.9
280 | xAxis.setTicks([newTicks]) #
281 |
282 |
283 | def troubleshootClicked(self):
284 | print('Combo text value: '+repr(str(self.combo.currentText())))
285 | listDataToPlot = []
286 | for index, each in enumerate(self.checkBoxList):
287 | if each.checkState() > 0:
288 | # append a list of indices where boxes are checked!
289 | listDataToPlot.append(index)
290 | print('Indices of Data to Plot from checkboxes: '+repr(listDataToPlot))
291 | print('These are the text objects: '+str(self.loadedData.columns[listDataToPlot].tolist()))
292 |
293 | def plotClicked(self):
294 | sender = self.sender()
295 | self.statusBar().showMessage(sender.text() + ' was pressed')
296 |
297 | listDataToPlot = []
298 |
299 | # Check if we are going to enable Matplotlib
300 | if self.checkMPL.checkState() > 0:
301 | MPLFlag = True;
302 | else:
303 | MPLFlag = False
304 |
305 | for index, each in enumerate(self.checkBoxList):
306 | if each.checkState() > 0:
307 | # append a list of indices where boxes are checked!
308 | listDataToPlot.append(index)
309 |
310 | self.valuePlot =self.loadedData.columns[listDataToPlot].tolist()
311 | try:
312 | self.setPivotData(
313 | plotBoxValues(self.filteredData,
314 | self.valuePlot,
315 | str(self.combo.currentText()), str(self.combo2.currentText()),
316 | MPLFlag))
317 |
318 |
319 | except Exception, err:
320 | errorWin = QtGui.QMessageBox(self)
321 | errorWin.setText('Error: Try Filtering the data first')
322 | errorWin.show()
323 | print('Failed for this reason: ')
324 | print(repr(err))
325 | pass
326 |
327 | # PLOT FIGURE
328 | self.plotReal(self)
329 |
330 | # Update running list of whats already plotted
331 | self.listPlotted.addItem(self.combo.currentText()+', '+self.combo2.currentText())
332 |
333 |
334 | def filterClicked(self):
335 |
336 | sender = self.sender()
337 | self.statusBar().showMessage(sender.text() + ' was pressed')
338 | try:
339 | self.setFilteredData(filterGoodValues(self.loadedData))
340 | except:
341 | errorWin = QtGui.QMessageBox(self)
342 | errorWin.setText('Error: Try loading data first')
343 | errorWin.show()
344 |
345 | def openFileDialog(self):
346 | # SELF IS ALWAYS THE NAME OF THE CLASS
347 | fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
348 | '/home')
349 | print('Opening File: '+repr(fname))
350 | data = loadData(str(fname))
351 |
352 | # Store the values
353 | self.setLoadedData(data);
354 |
355 | # Create a checkbox WIDGET to store this data
356 | self.checkWidget = QtGui.QWidget()
357 | self.filterWidget = QtGui.QWidget()
358 |
359 | checkWidgetList = [self.checkWidget, self.filterWidget]
360 | nameWidgetList = ["Plot Values", "Filter Values"]
361 |
362 | # Delete the old tabs, if there are more than 3 tabs total now
363 | if self.tabBar.count() >= 4:
364 | # First try to delete existing tabs from previous runs
365 | # Tabs are numbers 1, 2
366 | self.tabBar.removeTab(1)
367 | self.tabBar.removeTab(1)
368 |
369 | # Combo box for FILTERING choices
370 | counts =0;
371 | # Reset any values that may have been set before
372 | try:
373 | del self.checkBoxList[:]
374 | except:
375 | pass
376 | self.combo.clear(); self.combo2.clear();
377 | for number, widget in enumerate(checkWidgetList):
378 | layout = QtGui.QGridLayout()
379 | for index, each in enumerate(data.columns):
380 | # Fill combo boxes, only once
381 | if number == 1:
382 | self.combo.addItem(each)
383 | self.combo2.addItem(each)
384 |
385 | # Make checkboxes for values - first half belowng to "Plot Values", second half "Filter"
386 | self.checkBoxList.append(QtGui.QCheckBox(each, widget))
387 | self.checkBoxList[counts].sizeHint()
388 | # make a grid, with 2 columns
389 | layout.addWidget(self.checkBoxList[counts], floor(counts/2), counts % 2)
390 | counts+=1;
391 |
392 | widget.setLayout(layout)
393 |
394 | # add a tab showing these values -- 2 tabs total
395 | self.tabBar.insertTab(number+1, widget, nameWidgetList[number])
396 |
397 | # Make a TABLE
398 | t = Table() # Do not put a parent here?
399 | t.table.setColumnCount(len(data.columns))
400 | t.table.setRowCount(len(data.index))
401 | for i in range(len(data.index)):
402 | for j in range(len(data.columns)):
403 | t.table.setItem(i,j,
404 | QtGui.QTableWidgetItem(str(data.iget_value(i, j))))
405 | for i, value in enumerate(data.columns):
406 | t.table.setHorizontalHeaderItem(i, QtGui.QTableWidgetItem(str(value)))
407 |
408 | # Show the table
409 | if self.tabBar.count() >= 4:
410 | self.tabBar.removeTab(3)
411 | self.tabBar.addTab(t, "Updated Table")
412 | else:
413 | # Set for first time
414 | self.tabBar.addTab(t, "Table") # Add Table Tab
415 |
416 |
417 | # Message Window
418 | multiPickWin = QtGui.QMessageBox(self)
419 | multiPickWin.setText('You can only choose ONE check box at a time')
420 | multiPickWin.show()
421 |
422 | if __name__ == '__main__':
423 | import sys
424 | app = QtGui.QApplication(sys.argv)
425 |
426 | setSeabornParams()
427 |
428 | w = MainWindow()
429 |
430 | sys.exit(app.exec_())
431 |
432 |
--------------------------------------------------------------------------------
/Pivot_Tables_Pandas_2014_07_18_GUI_V3_beta.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @author: mdb52
4 | """
5 |
6 | from __future__ import division
7 |
8 | # These allow mpl in PyQt
9 | from PyQt4.QtGui import QSizePolicy
10 | from PyQt4.QtCore import QSize
11 |
12 | import numpy as np
13 | import seaborn as sb
14 | from pylab import *
15 | import pandas as pd
16 | import itertools
17 | import matplotlib._pylab_helpers
18 | from PyQt4 import *
19 |
20 | import pyqtgraph as pg
21 |
22 | """
23 | This loads CSV of all fiber data and plots various parameters from pivot tables
24 |
25 | Must use SELF.COMMAND when you want to access that value outside of the function (gets stored to the class)
26 |
27 | GUI V1: beta just barely works
28 | V2: improving the "Real Time capability"
29 | V3: uses pyqtplot -- for real time plot, and fixed GUI layout
30 | started using GIT and GIT-HUB
31 |
32 | """
33 |
34 | def setSeabornParams():
35 | # Talk seems to be best choice for font size
36 | sb.set_context("talk")
37 |
38 | # use "cubehelix" colormap for printing; hls is used for SB
39 | # sb.palplot(sb.color_palette("jet", 8))
40 | sb.set_palette(sb.color_palette("jet", 8))
41 | sb.set_palette("jet",8)
42 |
43 | def loadData(fname):
44 | data = pd.read_csv(fname)
45 | return data;
46 |
47 | def filterGoodValues(data):
48 | print('Size before filtering: '+repr(np.shape(data)))
49 | print('FILTERING PERFORMED')
50 | # Remove rows that have yes in either column:
51 | # 'Not a new calibration?' and 'Diode Measured Scatter or Cerenov?'
52 | data = data[data.loc[:,'Not a new calibration?'] != 'Yes']
53 | data = data[data.loc[:,'Diode Measured Scatter or Cerenkov?'] != 'Yes']
54 | print('Size after filtering: '+repr(np.shape(data)))
55 | return data
56 |
57 | def plotBoxValues(data, value_list, row, col, showMPL):
58 | for xx in value_list:
59 | #Make a pivot table for every value
60 |
61 | table1 = pd.pivot_table(data, values=xx,
62 | rows=row, cols=col, dropna=True)
63 |
64 | # drop if all data is missing in an axis
65 | print('Size before removing nan: '+repr(np.shape(table1)))
66 | table1 = table1.dropna(axis=0, how='all')
67 | table1 = table1.dropna(axis=1, how='all')
68 | print('Size after removing nan: '+repr(np.shape(table1)))
69 |
70 | if showMPL == True:
71 |
72 | # GET N
73 | N_table1 = table1.count(axis=0)
74 | N_table1_T = table1.count(axis=1)
75 |
76 | # Get Avg
77 | meanX = table1.mean()
78 | meanY = table1.T.mean()
79 |
80 | print('Mean x, y: ' + repr(meanX) + ', ' + repr(meanY))
81 |
82 | p1=figure(figsize=(11,8))
83 | sb.set_palette("jet",8)
84 | table1.boxplot()
85 | title(xx + ' By '+col)
86 | yscale('log')
87 | xlabel(col, fontsize=12, fontweight='bold')
88 |
89 | locs, labels = xticks()
90 | ymin, ymax = ylim()
91 |
92 | for index in range(len(locs)):
93 | text(locs[index], 1.2*ymin, 'N: '+repr(N_table1.iloc[index]),
94 | horizontalalignment='center')
95 | text(locs[index], 2*ymin, '$\\bar{x}$: ' +'%.2g'%meanX.iloc[index],
96 | horizontalalignment='center')
97 |
98 |
99 | p2=figure(figsize=(11,8))
100 | sb.set_palette("jet",8)
101 | table1.T.boxplot()
102 | title(xx + ' By '+row)
103 | yscale('log')
104 | xticks(rotation=90)
105 | xlabel(row, fontsize=12, fontweight='bold')
106 |
107 | locs, labels = xticks()
108 | ymin, ymax = ylim()
109 |
110 | for index in range(len(locs)):
111 | text(locs[index], 1.2*ymin, 'N: '+repr(N_table1_T.iloc[index]),
112 | horizontalalignment='center')
113 |
114 | text(locs[index], 2*ymin, '$\\bar{x}$: ' +'%.2g'%meanY.iloc[index],
115 | horizontalalignment='center')
116 | show()
117 |
118 | return table1;
119 |
120 | class Table(QtGui.QDialog):
121 | def __init__(self, parent=None):
122 | super(Table, self).__init__(parent)
123 | layout = QtGui.QGridLayout()
124 | self.table = QtGui.QTableWidget(self) # Parent of table
125 | layout.addWidget(self.table, 0, 0)
126 | self.setLayout(layout)
127 |
128 | class MainWindow(QtGui.QMainWindow):
129 |
130 | def __init__(self):
131 | super(MainWindow, self).__init__()
132 |
133 | self.initUI()
134 |
135 | self.loadedData = []
136 | self.filteredData = []
137 | self.checkBoxList = []
138 | self.pivotData = []
139 |
140 | def setLoadedData(self, setValue):
141 | self.loadedData = setValue
142 |
143 | def setFilteredData(self, setValue):
144 | self.filteredData = setValue
145 |
146 | def setPivotData(self, setValue):
147 | self.pivotData = setValue
148 |
149 | def initUI(self):
150 |
151 | self.setWindowTitle('Main Program')
152 |
153 | exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self)
154 | exitAction.triggered.connect(QtGui.qApp.quit)
155 |
156 | self.statusBar()
157 |
158 | # For tabbed widgets, do not specify a parent
159 | mainWidget = QtGui.QWidget()
160 |
161 | # Quit Button
162 | btn_quit = QtGui.QPushButton('Quit', mainWidget)
163 | btn_quit.clicked.connect(QtCore.QCoreApplication.instance().quit)
164 | btn_quit.setToolTip('This is a QPushButton widget')
165 | btn_quit.resize(btn_quit.sizeHint())
166 |
167 | # Plot data button
168 | btnPlot = QtGui.QPushButton('Plot Data', mainWidget)
169 | btnPlot.setToolTip('This will plot the Displayed Data')
170 | btnPlot.resize(btnPlot.sizeHint())
171 |
172 | btnFilter = QtGui.QPushButton('Filter Data, Make Pivot', mainWidget)
173 | btnFilter.setToolTip('You can remove types of data from analysis here')
174 | btnFilter.resize(btnFilter.sizeHint())
175 |
176 | # LOAD DATA AND SAVE TO A VARIABLE
177 | openFile = QtGui.QAction(QtGui.QIcon('open.png'), 'Open', mainWidget)
178 | openFile.setShortcut('Ctrl+O')
179 | openFile.setStatusTip('Open new File')
180 | openFile.triggered.connect(self.openFileDialog)
181 |
182 | # Define what happens when buttons are clicked
183 | btnFilter.clicked.connect(self.filterClicked)
184 | btnPlot.clicked.connect(self.plotClicked)
185 |
186 | # make a list of values already plotted
187 | self.listPlotted = QtGui.QListWidget()
188 | self.listPlotted.resize(256,192)
189 |
190 |
191 | # Drop down select combo box
192 | lbl1 = QtGui.QLabel('Series', mainWidget)
193 | self.combo = QtGui.QComboBox(mainWidget)
194 |
195 | # Drop down select combo box
196 | lbl2 = QtGui.QLabel('X-Axis', mainWidget)
197 | self.combo2 = QtGui.QComboBox(mainWidget)
198 |
199 | # Troubleshooting print button
200 | btn_test = QtGui.QPushButton('Troubleshoot', mainWidget)
201 | btn_test.resize(btn_test.sizeHint())
202 | btn_test.clicked.connect(self.troubleshootClicked)
203 |
204 | # Check box to show MPL figures in addition to real time
205 | self.checkMPL = QtGui.QCheckBox("Enable MPL")
206 |
207 | # Plot Widget
208 | self.plotWindow = pg.PlotWidget()
209 | self.plotWindow.resize(self.plotWindow.sizeHint())
210 |
211 | # Grid LAYOUT 4 rows, 8 columns
212 | nRows = 8; nCols = 12
213 | layout = QtGui.QGridLayout()
214 | # addItem (self, QLayoutItem item, int row,
215 | # int column, int rowSpan = 1, int columnSpan = 1, Qt.Alignment alignment = 0)
216 | layout.addWidget(btn_test, 0, 0) # Goes in upper left
217 | layout.addWidget(btnFilter, 1, 0) # Goes in middle left
218 | layout.addWidget(btnPlot, 2, 0)
219 | layout.addWidget(btn_quit, nRows, 0) # Bottom left
220 | layout.addWidget(self.checkMPL, 3, 0)
221 | layout.addWidget(lbl1, 4, 1)
222 | layout.addWidget(self.combo, 4, 0)
223 | layout.addWidget(lbl2, 5, 1)
224 | layout.addWidget(self.combo2, 5, 0)
225 | layout.addWidget(self.listPlotted, 6, 0, 1, 2)
226 | layout.addWidget(self.plotWindow, 0, 2, nRows, nCols)
227 |
228 | mainWidget.setLayout(layout)
229 |
230 | # Add a tab bar with widgets (tab 1 is options and figure, tab 2 is table)
231 | self.tabBar = QtGui.QTabWidget(self)
232 | self.tabBar.addTab(mainWidget, "Plot Settings")
233 |
234 | # Add MENU Bar - goes mainWindow
235 | menuBar = self.menuBar()
236 | fileMenu = menuBar.addMenu('&File')
237 | fileMenu.addAction(openFile)
238 | fileMenu.addAction(exitAction)
239 |
240 | # SET Tabbed WIDGET AS CENTRAL
241 | self.setCentralWidget(self.tabBar)
242 |
243 | self.setGeometry(50, 50, 1200, 600) # x,y for corner and then x-y widths
244 | self.show()
245 |
246 | def plotReal(self, axes):
247 | self.plotWindow.clear() # refresh if old data is here
248 | print(np.asarray(self.pivotData))
249 | xVals = self.pivotData.columns.tolist()
250 | xVals = [str(x) for x in xVals]
251 | yVals = self.pivotData.index.tolist()
252 | yVals = [str(x) for x in yVals]
253 |
254 |
255 | print('x: '+repr(xVals))
256 | print('y: '+repr(yVals))
257 |
258 | # Delete any old legends
259 | try:
260 | legend = self.plotWindow.plotItem.legend
261 | legend.scene().removeItem(legend)
262 | except Exception, err:
263 | print('Error: '+repr(err))
264 | pass
265 | self.plotWindow.addLegend((100,100)) # This must go above the plot calls
266 | colorValues = ['r','g','b','c','m','y','k','w']
267 | colorCycles = itertools.cycle(colorValues)
268 | for ind, each in enumerate(np.asarray(self.pivotData)):
269 | color = colorCycles.next()
270 | self.plotWindow.plot(each, name=yVals[ind], symbol='o', symbolPen = color, pen =color, symbolBrush = color)
271 |
272 | self.plotWindow.setLabel('left', self.valuePlot[0])
273 | self.plotWindow.setLabel('bottom', self.combo2.currentText())
274 |
275 | # Make tick labels
276 | xAxis = self.plotWindow.getAxis('bottom')
277 | newTicks = zip(range(len(xVals)), (xVals))
278 | print('New Ticks: '+repr(newTicks))
279 | # xAxis.setStyle(autoExpandTextSpace = 1) # not out until version 0.9.9
280 | xAxis.setTicks([newTicks]) #
281 |
282 |
283 | def troubleshootClicked(self):
284 | print('Combo text value: '+repr(str(self.combo.currentText())))
285 | listDataToPlot = []
286 | for index, each in enumerate(self.checkBoxList):
287 | if each.checkState() > 0:
288 | # append a list of indices where boxes are checked!
289 | listDataToPlot.append(index)
290 | print('Indices of Data to Plot from checkboxes: '+repr(listDataToPlot))
291 | print('These are the text objects: '+str(self.loadedData.columns[listDataToPlot].tolist()))
292 |
293 | def plotClicked(self):
294 | sender = self.sender()
295 | self.statusBar().showMessage(sender.text() + ' was pressed')
296 |
297 | listDataToPlot = []
298 |
299 | # Check if we are going to enable Matplotlib
300 | if self.checkMPL.checkState() > 0:
301 | MPLFlag = True;
302 | else:
303 | MPLFlag = False
304 |
305 | for index, each in enumerate(self.checkBoxList):
306 | if each.checkState() > 0:
307 | # append a list of indices where boxes are checked!
308 | listDataToPlot.append(index)
309 |
310 | self.valuePlot =self.loadedData.columns[listDataToPlot].tolist()
311 | try:
312 | self.setPivotData(
313 | plotBoxValues(self.filteredData,
314 | self.valuePlot,
315 | str(self.combo.currentText()), str(self.combo2.currentText()),
316 | MPLFlag))
317 |
318 |
319 | except Exception, err:
320 | errorWin = QtGui.QMessageBox(self)
321 | errorWin.setText('Error: Try Filtering the data first')
322 | errorWin.show()
323 | print('Failed for this reason: ')
324 | print(repr(err))
325 | pass
326 |
327 | # PLOT FIGURE
328 | self.plotReal(self)
329 |
330 | # Update running list of whats already plotted
331 | self.listPlotted.addItem(self.combo.currentText()+', '+self.combo2.currentText())
332 |
333 |
334 | def filterClicked(self):
335 |
336 | sender = self.sender()
337 | self.statusBar().showMessage(sender.text() + ' was pressed')
338 | try:
339 | self.setFilteredData(filterGoodValues(self.loadedData))
340 | except:
341 | errorWin = QtGui.QMessageBox(self)
342 | errorWin.setText('Error: Try loading data first')
343 | errorWin.show()
344 |
345 | def openFileDialog(self):
346 | # SELF IS ALWAYS THE NAME OF THE CLASS
347 | fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
348 | '/home')
349 | print('Opening File: '+repr(fname))
350 | data = loadData(str(fname))
351 |
352 | # Store the values
353 | self.setLoadedData(data);
354 |
355 | # Create a checkbox WIDGET to store this data
356 | self.checkWidget = QtGui.QWidget()
357 | self.filterWidget = QtGui.QWidget()
358 |
359 | checkWidgetList = [self.checkWidget, self.filterWidget]
360 | nameWidgetList = ["Plot Values", "Filter Values"]
361 |
362 | # Delete the old tabs, if there are more than 3 tabs total now
363 | if self.tabBar.count() >= 4:
364 | # First try to delete existing tabs from previous runs
365 | # Tabs are numbers 1, 2
366 | self.tabBar.removeTab(1)
367 | self.tabBar.removeTab(1)
368 |
369 | # Combo box for FILTERING choices
370 | counts =0;
371 | # Reset any values that may have been set before
372 | try:
373 | del self.checkBoxList[:]
374 | except:
375 | pass
376 | self.combo.clear(); self.combo2.clear();
377 | for number, widget in enumerate(checkWidgetList):
378 | layout = QtGui.QGridLayout()
379 | for index, each in enumerate(data.columns):
380 | # Fill combo boxes, only once
381 | if number == 1:
382 | self.combo.addItem(each)
383 | self.combo2.addItem(each)
384 |
385 | # Make checkboxes for values - first half belowng to "Plot Values", second half "Filter"
386 | self.checkBoxList.append(QtGui.QCheckBox(each, widget))
387 | self.checkBoxList[counts].sizeHint()
388 | # make a grid, with 2 columns
389 | layout.addWidget(self.checkBoxList[counts], floor(counts/2), counts % 2)
390 | counts+=1;
391 |
392 | widget.setLayout(layout)
393 |
394 | # add a tab showing these values -- 2 tabs total
395 | self.tabBar.insertTab(number+1, widget, nameWidgetList[number])
396 |
397 | # Make a TABLE
398 | t = Table() # Do not put a parent here?
399 | t.table.setColumnCount(len(data.columns))
400 | t.table.setRowCount(len(data.index))
401 | for i in range(len(data.index)):
402 | for j in range(len(data.columns)):
403 | t.table.setItem(i,j,
404 | QtGui.QTableWidgetItem(str(data.iget_value(i, j))))
405 | for i, value in enumerate(data.columns):
406 | t.table.setHorizontalHeaderItem(i, QtGui.QTableWidgetItem(str(value)))
407 |
408 | # Show the table
409 | if self.tabBar.count() >= 4:
410 | self.tabBar.removeTab(3)
411 | self.tabBar.addTab(t, "Updated Table")
412 | else:
413 | # Set for first time
414 | self.tabBar.addTab(t, "Table") # Add Table Tab
415 |
416 |
417 | # Message Window
418 | multiPickWin = QtGui.QMessageBox(self)
419 | multiPickWin.setText('You can only choose ONE check box at a time')
420 | multiPickWin.show()
421 |
422 | if __name__ == '__main__':
423 | import sys
424 | app = QtGui.QApplication(sys.argv)
425 |
426 | setSeabornParams()
427 |
428 | w = MainWindow()
429 |
430 | sys.exit(app.exec_())
431 |
432 |
--------------------------------------------------------------------------------