def __init__(self, window): wx.Panel.__init__(self, window) sizer = wx.BoxSizer(wx.VERTICAL) hbox1 = wx.BoxSizer(wx.HORIZONTAL) hbox2 = wx.BoxSizer(wx.HORIZONTAL) vbox1 = wx.BoxSizer(wx.VERTICAL) vbox2 = wx.BoxSizer(wx.VERTICAL) space = wx.BoxSizer(wx.HORIZONTAL) plotBox = wx.BoxSizer(wx.VERTICAL) ctrlBox = wx.BoxSizer(wx.HORIZONTAL) self.toggleParams = { "grid":False, "error":False, "stats":False, "poly":False, "corr":False } self.graphParams = { "file":None, "plot":'Scatter', "xLabel":None, "yLabel":None, "xRange":[0,1], "yRange":[0,1] } self.__polyVal = None self.__file = None self.__plotType = 'Scatter' self.__xLabel = None self.__yLabel = None self.__xRange = [0,1] self.__yRange = [0,1] self.figure = plt.Figure(figsize=(2,2)) self.axes = self.figure.add_subplot(111) self.statusLabels = ["\tStatus_Box", "File: None", "Has_Data: False", "PlotType: Scatter", "xLabel: None", "yLabel: None", "xLimit: None", "yLimit: None"] self.canvas = FigureCanvas(self, -1, self.figure) self.xLimit = Axis_Range(self, 'x', self.__xRange[0], self.__xRange[1]) self.yLimit = Axis_Range(self, 'y', self.__yRange[0], self.__yRange[1]) self.xLabel = wx.ComboBox(self, value="X-Axis", choices=[]) self.yLabel = wx.ComboBox(self, value="Y-Axis", choices=[]) self.plotChoices = wx.RadioBox(self, label='Graph Style', choices=['Scatter', 'Line', 'Bar']) self.toggleGrid = wx.CheckBox(self, label="Toggle Grid") self.toggleErr = wx.CheckBox(self, label="Toggle Error: Line Only") self.toggleStats = wx.CheckBox(self, label="Toggle Stats: Bar Only") self.togglePoly = wx.CheckBox(self, label="Polyfit: Scatter Only") self.toggleCorr = wx.CheckBox(self, label="Correlate: Scatter Only") self.status = wx.ListBox(self, choices=self.statusLabels) self.plotChoices.Bind(wx.EVT_RADIOBOX, self.updateStyle) self.xLabel.Bind(wx.EVT_COMBOBOX, self.setX) self.yLabel.Bind(wx.EVT_COMBOBOX, self.setY) self.toggleGrid.Bind(wx.EVT_CHECKBOX, self.__gridToggle) self.toggleErr.Bind(wx.EVT_CHECKBOX, self.__errorToggle) self.toggleStats.Bind(wx.EVT_CHECKBOX, self.__statsToggle) self.togglePoly.Bind(wx.EVT_CHECKBOX, self.__polyToggle) self.toggleCorr.Bind(wx.EVT_CHECKBOX, self.__corrToggle) hbox1.Add(self.yLimit, proportion=1, flag=wx.EXPAND) hbox1.Add(self.canvas, proportion=12, flag=wx.EXPAND) plotBox.Add(hbox1, proportion=8, flag=wx.EXPAND) hbox2.Add(space, proportion=1, flag=wx.EXPAND) hbox2.Add(self.xLimit, proportion=12, flag=wx.EXPAND) plotBox.Add(hbox2, proportion=1, flag=wx.EXPAND) ctrlBox.Add(self.status, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleGrid, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleErr, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleStats, proportion=1, flag=wx.EXPAND) vbox1.Add(self.togglePoly, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleCorr, proportion=1, flag=wx.EXPAND) ctrlBox.Add(vbox1, proportion=1, flag=wx.EXPAND) vbox2.Add(self.plotChoices, proportion=1, flag=wx.EXPAND) vbox2.Add(self.xLabel, proportion=1, flag=wx.EXPAND) vbox2.Add(self.yLabel, proportion=1, flag=wx.EXPAND) ctrlBox.Add(vbox2, proportion=1, flag=wx.EXPAND) sizer.Add(plotBox, proportion=2, flag=wx.EXPAND) sizer.Add(ctrlBox, proportion=1, flag=wx.EXPAND) self.SetSizer(sizer)
class PlotPanel(wx.Panel): def __init__(self, window): wx.Panel.__init__(self, window) sizer = wx.BoxSizer(wx.VERTICAL) hbox1 = wx.BoxSizer(wx.HORIZONTAL) hbox2 = wx.BoxSizer(wx.HORIZONTAL) vbox1 = wx.BoxSizer(wx.VERTICAL) vbox2 = wx.BoxSizer(wx.VERTICAL) space = wx.BoxSizer(wx.HORIZONTAL) plotBox = wx.BoxSizer(wx.VERTICAL) ctrlBox = wx.BoxSizer(wx.HORIZONTAL) self.toggleParams = { "grid":False, "error":False, "stats":False, "poly":False, "corr":False } self.graphParams = { "file":None, "plot":'Scatter', "xLabel":None, "yLabel":None, "xRange":[0,1], "yRange":[0,1] } self.__polyVal = None self.__file = None self.__plotType = 'Scatter' self.__xLabel = None self.__yLabel = None self.__xRange = [0,1] self.__yRange = [0,1] self.figure = plt.Figure(figsize=(2,2)) self.axes = self.figure.add_subplot(111) self.statusLabels = ["\tStatus_Box", "File: None", "Has_Data: False", "PlotType: Scatter", "xLabel: None", "yLabel: None", "xLimit: None", "yLimit: None"] self.canvas = FigureCanvas(self, -1, self.figure) self.xLimit = Axis_Range(self, 'x', self.__xRange[0], self.__xRange[1]) self.yLimit = Axis_Range(self, 'y', self.__yRange[0], self.__yRange[1]) self.xLabel = wx.ComboBox(self, value="X-Axis", choices=[]) self.yLabel = wx.ComboBox(self, value="Y-Axis", choices=[]) self.plotChoices = wx.RadioBox(self, label='Graph Style', choices=['Scatter', 'Line', 'Bar']) self.toggleGrid = wx.CheckBox(self, label="Toggle Grid") self.toggleErr = wx.CheckBox(self, label="Toggle Error: Line Only") self.toggleStats = wx.CheckBox(self, label="Toggle Stats: Bar Only") self.togglePoly = wx.CheckBox(self, label="Polyfit: Scatter Only") self.toggleCorr = wx.CheckBox(self, label="Correlate: Scatter Only") self.status = wx.ListBox(self, choices=self.statusLabels) self.plotChoices.Bind(wx.EVT_RADIOBOX, self.updateStyle) self.xLabel.Bind(wx.EVT_COMBOBOX, self.setX) self.yLabel.Bind(wx.EVT_COMBOBOX, self.setY) self.toggleGrid.Bind(wx.EVT_CHECKBOX, self.__gridToggle) self.toggleErr.Bind(wx.EVT_CHECKBOX, self.__errorToggle) self.toggleStats.Bind(wx.EVT_CHECKBOX, self.__statsToggle) self.togglePoly.Bind(wx.EVT_CHECKBOX, self.__polyToggle) self.toggleCorr.Bind(wx.EVT_CHECKBOX, self.__corrToggle) hbox1.Add(self.yLimit, proportion=1, flag=wx.EXPAND) hbox1.Add(self.canvas, proportion=12, flag=wx.EXPAND) plotBox.Add(hbox1, proportion=8, flag=wx.EXPAND) hbox2.Add(space, proportion=1, flag=wx.EXPAND) hbox2.Add(self.xLimit, proportion=12, flag=wx.EXPAND) plotBox.Add(hbox2, proportion=1, flag=wx.EXPAND) ctrlBox.Add(self.status, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleGrid, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleErr, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleStats, proportion=1, flag=wx.EXPAND) vbox1.Add(self.togglePoly, proportion=1, flag=wx.EXPAND) vbox1.Add(self.toggleCorr, proportion=1, flag=wx.EXPAND) ctrlBox.Add(vbox1, proportion=1, flag=wx.EXPAND) vbox2.Add(self.plotChoices, proportion=1, flag=wx.EXPAND) vbox2.Add(self.xLabel, proportion=1, flag=wx.EXPAND) vbox2.Add(self.yLabel, proportion=1, flag=wx.EXPAND) ctrlBox.Add(vbox2, proportion=1, flag=wx.EXPAND) sizer.Add(plotBox, proportion=2, flag=wx.EXPAND) sizer.Add(ctrlBox, proportion=1, flag=wx.EXPAND) self.SetSizer(sizer) def __gridToggle(self, evt): self.toggleParams["grid"] = not self.toggleParams["grid"] if self.__canPlot(): self.__getData() def __errorToggle(self, evt): self.toggleParams["error"] = not self.toggleParams["error"] if self.__canPlot(): self.__getData() def __statsToggle(self, evt): self.toggleParams["stats"] = not self.toggleParams["stats"] if self.__canPlot(): self.__getData() def __polyToggle(self, evt): pass def __corrToggle(self, evt): pass def setRange(self): #Called by sliders and get data, this is the only place __updatePlot is called self.__xRange = self.xLimit.getRange() self.__yRange = self.yLimit.getRange() self.__updateStatus("xLimit", str(self.__xRange)) self.__updateStatus("yLimit", str(self.__yRange)) self.__updatePlot() def updateStyle(self, evt): #Everytime radiobox changes self.__plotType = evt.EventObject.GetStringSelection() self.__updateStatus("Plot", self.__plotType) if self.__canPlot(): self.__getData() def setX(self, evt): #Everytime x Combo changes self.__xLabel = evt.EventObject.GetStringSelection() self.__updateStatus("xLabel", self.__xLabel) if self.__canPlot(): self.__getData() def setY(self, evt): #Everytime y Combo changes self.__yLabel = evt.EventObject.GetStringSelection() self.__updateStatus("yLabel", self.__yLabel) if self.__canPlot(): self.__getData() def setFile(self, file): self.__file = file self.graphParams["file"] = file self.__updateStatus("File", file.name) self.__updateDataLabels() self.__xLabel = None self.__yLabel = None self.__xRange = [0,1] self.__yRange = [0,1] self.xLabel.SetValue("X-Axis") self.yLabel.SetValue("Y-Axis") def __updateDataLabels(self): if isinstance(self.__file, File): self.xLabel.SetItems('') self.yLabel.SetItems('') self.xLabel.Append('testIndex') self.yLabel.Append('testIndex') for column in self.__file.columns: self.xLabel.Append(column) self.yLabel.Append(column) def __getData(self): #Only called if the plot is ready if self.__xLabel and self.__yLabel == 'testIndex': self.__x = list(self.__file.data.index.values) self.__y = list(self.__file.data.index.values) elif self.__xLabel == 'testIndex': self.__x = list(self.__file.data.index.values) self.__y = list(self.__file.data[self.__yLabel]) elif self.__yLabel == 'testIndex': self.__x = list(self.__file.data[self.__xLabel]) self.__y = list(self.__file.data.index.values) else: self.__x = list(self.__file.data[self.__xLabel]) self.__y = list(self.__file.data[self.__yLabel]) if self.__plotType == 'Line': #Line charts plot the average y values for each x value and has an option to show errorbars self.__x, self.__y, self.__err = self.__meanYforX() elif self.__plotType == 'Bar': self.__x, self.__y = self.__freqX() self.xLimit.setRange([np.min(self.__x),np.max(self.__x)]) self.yLimit.setRange([np.min(self.__y),np.max(self.__y)]) self.setRange() #Updates plot also def __updatePlot(self): #Everything below here is for plotting """This is where all the plotting happens""" if not self.__canPlot(): return self.axes.clear() if self.__plotType == 'Scatter': self.axes.scatter(self.__x, self.__y) elif self.__plotType == 'Line': self.axes.plot(self.__x, self.__y) if not self.toggleParams["error"] else self.axes.errorbar(self.__x, self.__y, yerr=self.__err) elif self.__plotType == 'Bar': self.axes.bar(self.__x, self.__y) if self.toggleParams["stats"]: self.axes.text(self.__xRange[1]*0.5, self.__yRange[1]*0.9, r'$\mu=%s,\ \sigma=%s$'%(np.around(np.average(self.__x), decimals=2),np.around(np.std(self.__x), decimals=2))) self.axes.axis([self.__xRange[0], self.__xRange[1], self.__yRange[0], self.__yRange[1]]) if self.toggleParams["grid"]: self.axes.grid() self.canvas.draw() def __meanYforX(self): xDist = [] yDist = [] for i in range(len(self.__x)): if self.__x[i] not in xDist: xDist.append(self.__x[i]) if self.__y[i] not in yDist: yDist.append(self.__y[i]) lineX = [] lineY = [] deviations = [] for value in sorted(xDist): lineX.append(value) yList = [] indexList = [] for i, val in enumerate(self.__x): if self.__x[i] == value: indexList.append(i) for num in indexList: yList.append(self.__y[num]) lineY.append(np.average(yList)) deviations.append(np.std(yList)) return lineX, lineY, deviations def __freqX(self): xDist = [] for i in range(len(self.__x)): if self.__x[i] not in xDist: xDist.append(self.__x[i]) freq = [0]*len(xDist) for i, num in enumerate(xDist): for val in self.__x: if val == num: freq[i] += 1 return xDist, freq def __updateStatus(self, parameter, label): key = self.__getKey() assert(parameter in key.keys()), "Parameter needs to be " + str(key.keys()) self.status.SetString(self.status.FindString(key[parameter]), key[parameter].split(' ')[0] + ' ' + label) def getFile(self): return self.__file def __getKey(self): return {"File":self.status.GetString(1), "Data":self.status.GetString(2), "Plot":self.status.GetString(3), "xLabel":self.status.GetString(4), "yLabel":self.status.GetString(5), "xLimit":self.status.GetString(6), "yLimit": self.status.GetString(7)} def __canPlot(self): if self.__plotType == 'Bar': return (True if self.__xLabel != None else False) else: return (True if self.__xLabel and self.__yLabel != None else False)