class Plot(wx.Panel): def __init__(self, parent, dpi=None, **kwargs): wx.Panel.__init__(self, parent, **kwargs) self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2, 2)) self.canvas = Canvas(self, wx.ID_ANY, self.figure) self.check = wx.CheckBox(self, wx.ID_ANY, "Show contour") self.Bind(wx.EVT_CHECKBOX, self.OnChange, self.check) self.distMod = SinModulator(self, 'Amplitude modulator', cycles=(2,100), phase=(0, 999)) self.Bind(EVT_UPDATE_EVENT, self.OnChange, self.distMod) sizerV = wx.BoxSizer(wx.VERTICAL) sizerV.Add(self.distMod) sizerV.Add(self.check, 0, wx.EXPAND) sizerH = wx.BoxSizer(wx.HORIZONTAL) sizerH.Add(self.canvas, 0, wx.SHAPED | wx.EXPAND) sizerH.Add(sizerV) self.SetSizer(sizerH) self.width, self.height = 256, 256 def CalcPixel(self, i, j): x = 2.0 * i / self.width - 1.0 y = 2.0 * j / self.height - 1.0 dist = np.sqrt(x**2 + y**2) angle = np.arctan2(y, x) data = self.distMod if data.active: phase = data.phase * 2.0 * np.pi newAngle = angle * data.cycles + phase distDiff = np.cos(newAngle) * dist / data.cycles else: distDiff = 0.0 return 1.0 - (dist + distDiff) def Draw(self): self.figure.clear() subplot = self.figure.add_subplot(111) x = np.arange(0.0, self.width, 1.0) y = np.arange(0.0, self.height, 1.0) I, J = np.meshgrid(x, y) C = np.clip(self.CalcPixel(I, J), 0.0, 1.0) if self.check.IsChecked(): self.CS = subplot.contour(I, J, C) subplot.clabel(self.CS, inline=0.1, fontsize=8) im = subplot.imshow(C, cmap=cm.gray) im.set_interpolation('bilinear') def OnChange(self, _): self.Draw() self.canvas.draw()
class CanvasPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.figure = Figure() self.axes = self.figure.add_subplot(111) self.canvas = FigureCanvas(self, -1, self.figure) self.toolbar = Toolbar(self.canvas) #matplotlib toolbar self.toolbar.Realize() self.sizer = wx.BoxSizer(wx.VERTICAL) #self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.sizer.Add(self.canvas, 1, wx.EXPAND | wx.ALL) # Best to allow the toolbar to resize! self.sizer.Add(self.toolbar, 0, wx.GROW) self.SetSizer(self.sizer) self.Fit() def GetToolBar(self): # You will need to override GetToolBar if you are using an # unmanaged toolbar in your frame return self.toolbar def draw(self): t = arange(0.0, 3.0, 0.01) s = sin(2 * pi * t) self.axes.plot(t, s) def OnPaint(self, event): self.canvas.draw()
class WattrGraphPanel( WattrGUI.GraphPanel ): subplot = 0 plots = {} def __init__(self, parent, fgsize=None, dpi=None): super(WattrGraphPanel, self).__init__(parent) self.figure = Figure(fgsize, dpi) #Transparent figure face color self.figure.set_facecolor((0,0,0,0,)) self.canvas = FigureCanvasWxAgg(self, -1, self.figure) # Now put all into a sizer sizer = self.GetSizer() # This way of adding to sizer allows resizing sizer.Add(self.canvas, 1, wx.LEFT|wx.TOP|wx.GROW) # Best to allow the toolbar to resize! self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() sizer.Add(self.toolbar, 0, wx.GROW) self.Fit() def add_plot(self, x=1, y=1): self.subplot += 1 plot = self.figure.add_subplot(x, y, self.subplot) plot.ticklabel_format(axis='y', style='plain', useOffset=False) plot.ticklabel_format(axis='x', style='plain', useOffset=False) self.plots[self.subplot] = plot return plot def draw(self): self.canvas.draw()
class RealTimePlot(wx.Frame): def __init__(self,data): wx.Frame.__init__(self, None, -1, "Real time data plot") self.redraw_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer) self.redraw_timer.Start(100) self.data=data self.init_plot() def init_plot(self): self.data.next() self.panel = wx.Panel(self) self.fig = Figure((6.0, 3.0)) self.canvas = FigureCanvasWxAgg(self.panel, -1, self.fig) self.axes = self.fig.add_subplot(111) self.plot_data, = self.axes.plot(self.data.get_curr()[0],self.data.get_curr()[1]) self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW) self.panel.SetSizer(self.vbox) self.vbox.Fit(self) def draw_plot(self): x=self.data.get_curr()[0] y=self.data.get_curr()[1] self.plot_data.set_data(x,y) self.axes.set_xlim((x[0],x[-1])) self.axes.set_ylim((min(y),max(y))) self.canvas.draw() def on_redraw_timer(self,event): self.data.next() self.draw_plot()
class GraphPanel(wx.Panel): def __init__(self, parent, streamValuesHistory): wx.Panel.__init__(self, parent) self._streamValuesHistory = streamValuesHistory self.figure = Figure() self.figure.patch.set_facecolor('black') self.axes = self.figure.add_axes([0.1, 0.025, 0.9, 0.95]) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.Fit() self._colors = [(0.0, 1.0, 0.0), (1.0, 0.0, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 0.0, 1.0)] def UpdateGraphs(self): self.axes.clear() self.axes.patch.set_facecolor((0, 0, 0)) self.axes.grid(b=True, color=(0, 0.1, 0), which='major', linestyle='-', linewidth=1) self.axes.yaxis.set_tick_params(labelcolor=(0.6, 0.6, 0.6)) self.axes.set_axisbelow(True) """Draw data.""" iColor = 0 for streamValues in self._streamValuesHistory.itervalues(): valuesNumber = int(self.axes.get_window_extent().width) X = range(0, valuesNumber) Y = [streamValues[-min(valuesNumber, len(streamValues))]] * (valuesNumber - len(streamValues)) + streamValues[-valuesNumber:] self.axes.plot( X, Y, color=self._colors[iColor%len(self._colors)], linewidth=1) iColor+=1 self.canvas.draw()
class CanvasPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.figure = Figure(facecolor="black") self.axes = self.figure.add_axes((0, 0, 1, 1)) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.Fit() self.axes.set_axis_bgcolor('black') self.delta = 0 t = arange(0.0, 3.0, 0.01) s = sin(2 * pi * (t)) self.datatoplot, = self.axes.plot(t, s, 'w', linewidth=3.0) self.axes.set_ylim((-10,10)) self.axes.grid(True, color="w") def draw(self): self.delta = (self.delta + 0.05) % 1 t = arange(0.0, 3.0, 0.01) s = sin(2 * pi * (t-self.delta)) self.datatoplot.set_ydata(s) wx.CallLater(10, self.draw) self.canvas.draw() self.canvas.Refresh()
class PlotPanel2(wx.Panel): def __init__(self, parent, **kwargs): wx.Panel.__init__(self, parent, **kwargs) self.figure = mpl.figure.Figure() self.axes = self.figure.add_subplot(111) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer.Add(self.canvas, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER) self.SetSizer(self.sizer) self.Fit() def Draw(self): global XSlice, YSlice, SSlice, DataSlice self.axes.cla() XSlice = np.linspace(coord1.x,coord2.x,200) YSlice = np.linspace(coord1.y,coord2.y,200) self.localdx = XSlice[1] - XSlice[0] self.localdy = YSlice[1] - YSlice[0] self.localds = np.sqrt(self.localdx**2 + self.localdy**2) SSlice = [self.localds*x for x in range(200)] DataSlice = [] for x,y in zip(XSlice,YSlice): DataSlice.append(DataFit(x,y)) self.axes.plot(SSlice,DataSlice) self.canvas.draw()
def __init__(self,parent): self.data_t = [0] self.data_y = [0] self.data_y2 = [0] self.dpi = 100 self.fig = Figure((3.0, 3.0), dpi=self.dpi) self.axes = self.fig.add_subplot(111) pylab.setp(self.axes.get_xticklabels(), fontsize=10) pylab.setp(self.axes.get_yticklabels(), fontsize=10) # plot the data as a line series, and save the reference # to the plotted line series # self.plot_data = self.axes.plot( self.data_t,self.data_y,'y', self.data_t,self.data_y2,'c', ) ymin = -30 ymax = 30 self.axes.set_ybound(lower=ymin, upper=ymax) self.axes.set_xlim(0, 20) self.axes.grid(True) FigCanvas.__init__(self, parent, -1, self.fig) self.drawing = False
def init_graph(self): '''initalizing the graph setup inside the panel ''' self.fig = Figure(figsize=(8, 6), dpi=40) self.fig2 = Figure(figsize=(8, 6), dpi=40) # setting the axes fo the figure graph self.axes = self.fig.add_subplot(1, 1, 1) self.axes.set_axis_bgcolor('black') self.axes.set_title('XXX', size=20) self.axes.grid(True, color='white', linewidth=2) pylab.setp(self.axes.get_xticklabels(), fontsize=21) pylab.setp(self.axes.get_yticklabels(), fontsize=21) self.axes2 = self.fig2.add_subplot(1, 1, 1) self.axes2.set_axis_bgcolor('black') self.axes2.set_title('XXX', size=20) self.axes2.grid(True, color='white', linewidth=2) pylab.setp(self.axes2.get_xticklabels(), fontsize=21) pylab.setp(self.axes2.get_yticklabels(), fontsize=21) # creates the tamb graph plot inside the first panel self.tamb_canvas = FigCanvas(self.tamb_panel_1, -1, self.fig) #createst the tobj graph plot inside the second panel self.tobj_canvas = FigCanvas(self.tobj_panel_2, -1, self.fig2) mylog10.debug(repr(self.tamb_canvas) ) mylog10.debug(repr(self.tobj_canvas) )
class CanvasFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(wx.NamedColor("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) t = arange(0.0,3.0,0.01) s = sin(2*pi*t) self.axes.plot(t,s) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.Fit() self.add_toolbar() # comment this out for no toolbar def add_toolbar(self): self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() if wx.Platform == '__WXMAC__': self.SetToolBar(self.toolbar) else: tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wx.Size(fw, th)) self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) self.toolbar.update() def OnPaint(self, event): self.canvas.draw()
def end_pan_all(self, x, y, axesList): """ End panning for multiple subplots. Use this function to correctly reset limits for all axes. """ if not self.enabled: return i = 0 xmin, xmax = 0, 0 for axes in axesList: if not is_log_x(axes): # TBF: matplotlib's Axes' panx method is broken, so we do it # here for them. axes.xaxis.pan(-self.panx) if i==0: # we want to keep all plots on a common x-axis xmin, xmax = axes.viewLim.intervalx().get_bounds() axes.set_xlim(xmin, xmax) axes._send_xlim_event() if not is_log_y(axes): axes.pany(-self.pany) axes._send_ylim_event() i += 1 self.panx = 0 self.pany = 0 FigureCanvasWxAgg.draw(self.getView())
def rightButtonUp(self, evt, x, y): """ Completely overrides base class functionality. """ view = self.getView() if self.selectedAxes is None: axes, xdata, ydata = self.find_axes(view, x, y) else: axes = self.selectedAxes xdata, ydata = get_data(axes, x, y) self.setActiveSubplot(axes) if self.zoomEnabled and self.rightClickUnzoom: xmin = xmax = None for axes in self.find_all_axes(view, x, y): # unzoom all axes self.limits.restore(axes) if not self.limits.can_unzoom(axes): # rescale manually - wxmpl will try to autoscale if xmin is None or xmax is None: # make sure x-axis matches xmin, xmax = axes.viewLim.intervalx().get_bounds() axes.set_xlim(xmin, xmax) axes._send_xlim_event() view.crosshairs.clear() view.draw() view.crosshairs.set(x, y) if self.IsInfoMode() and axes is not None: self.DisplayAllSubplots() FigureCanvasWxAgg.draw(view) if self.IsPanMode() and axes is not None: self.panTool.end_pan_all(x, y, self.find_all_axes(view, x, y))
def pan(self, x, y, axes): """ Modifies the desired axes limits to make it appear to the user that the axes are panning as he/she moves the mouse. """ if not self.enabled: return if not is_log_x(axes): xtick = axes.get_xaxis()._get_tick(major=False)._size movex = (self.getX() - x) / xtick / 10 # TBF: matplotlib's Axes' panx method is broken, so we do it here # in the next two lines for them. axes.xaxis.pan(movex) axes._send_xlim_event() self.panx += movex if not is_log_y(axes): ytick = axes.get_yaxis()._get_tick(major=False)._size movey = (self.getY() - y) / ytick / 10 axes.pany(movey) self.pany += movey self.setX(x) self.setY(y) FigureCanvasWxAgg.draw(self.getView())
def panAll(self, x, y, axesList): """ Pans across multiple subplots simultaneously. Use this function rather than pan to avoid lag on the x-axis. """ if not self.enabled: return i=0 movex, movey = 0, 0 xmin, xmax = 0, 0 for axes in axesList: if not is_log_x(axes): xtick = axes.get_xaxis()._get_tick(major=False)._size movex = (self.getX() - x) / xtick / 10 # TBF: matplotlib's Axes' panx method is broken, so we do it here axes.xaxis.pan(movex) if i==0: # we want to keep all plots on a common x-axis xmin, xmax = axes.viewLim.intervalx().get_bounds() axes.set_xlim(xmin, xmax) axes._send_xlim_event() if not is_log_y(axes): ytick = axes.get_yaxis()._get_tick(major=False)._size movey = (self.getY() - y) / ytick / 10 axes.pany(movey) i += 1 self.panx += movex self.pany += movey self.setX(x) self.setY(y) FigureCanvasWxAgg.draw(self.getView())
class PlotPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.parent = parent self.fig = Figure() self.axes = self.fig.add_subplot(111) self.canvas = FigureCanvas(self, -1, self.fig) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.GROW) self.SetSizer(self.sizer) self.Fit() self.reset() @property def size(self): return self.parent.plot_size.v def new_plot(self, name, c): self.plots[name] = self.axes.plot(np.zeros(self.size), c)[0] self.axes.set_ylim([-1, 255]) def new_line(self, name, val, c): self.lines[name] = self.axes.plot(np.repeat(val, self.size), c+'--')[0] def update_line(self, name, val): self.lines[name].set_ydata(np.repeat(val, self.size)) self.canvas.draw() def reset(self): self.plots = {} self.lines = {} saelf.aces.clear() def update_plot(self, name, data): if len(data) != self.size: data = np.append(data, np.repeat(None, self.size-len(data))) self.plots[name].set_ydata(data) self.canvas.draw()
def rightButtonUp(self, evt, x, y): """ Completely overrides base class functionality. """ view = self.getView() if self.selectedAxes is None: axes, xdata, ydata = wxmpl.find_axes(view, x, y) else: axes = self.selectedAxes xdata, ydata = get_data(axes, x, y) self.setActiveSubplot(axes) if (axes is not None and self.zoomEnabled and self.rightClickUnzoom and self.limits.restore(axes)): view.crosshairs.clear() view.draw() view.crosshairs.set(x, y) if self.IsInfoMode() and axes is not None: self.DisplayAllSubplots() FigureCanvasWxAgg.draw(view) if self.IsPanMode() and axes is not None: self.panTool.end_pan(x, y, axes)
class PlotPanel( wx.Panel ): def __init__(self, parent, dpi = None, color=None, *args, **kwargs): from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg wx.Panel.__init__(self, parent, wx.ID_ANY, *args, **kwargs) self.parent = parent self.figure = mpl.figure.Figure( None, dpi ) self.canvas = FigureCanvasWxAgg(self, -1, self.figure) self._resizeflag = False self._SetSize() self.Bind(wx.EVT_IDLE, self._onIdle) self.Bind(wx.EVT_SIZE, self._SetSize) def _SetSize(self, event=None): pixels = self.GetSize() self.SetSize(pixels) self.canvas.SetSize(pixels) self.figure.set_size_inches( float(pixels[0])/self.figure.get_dpi(), float(pixels[1])/self.figure.get_dpi() ) def _onIdle(self,event): self.canvas.draw() if self._resizeflag: self._SetSize() self._resizeflag = False def draw(self): pass # To be overriden by children def make(self): pass # To be overriden by children
class CanvasFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, 'CanvasFrame', size=(550, 350)) self.figure = Figure(figsize=(5, 4), dpi=100) self.axes = self.figure.add_subplot(111) t = arange(0.0, 3.0, 0.01) s = sin(2 * pi * t) self.axes.plot(t, s) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) # Capture the paint message self.Bind(wx.EVT_PAINT, self.OnPaint) self.toolbar = MyNavigationToolbar(self.canvas, True) self.toolbar.Realize() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) # update the axes menu on the toolbar self.toolbar.update() self.SetSizer(self.sizer) self.Fit() def OnPaint(self, event): self.canvas.draw() event.Skip()
class CanvasPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.figure = Figure() self.axes = self.figure.add_subplot(111) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.Fit() def show_data(self,fbfile,fields=['cond','imu_a']): if fbfile.data is None: return self.figure.clear() axs=[] for axi,varname in enumerate(fields): if axi==0: sharex=None else: sharex=axs[0] ax=self.figure.add_subplot(len(fields),1,axi+1,sharex=sharex) axs.append(ax) ax.plot_date( fbfile.data['dn_py'], fbfile.data[varname], 'g-') self.figure.autofmt_xdate() # Not sure how to trigger it to actually draw things. self.canvas.draw() self.Fit()
class ChartCanvas(): """ Container for the matplotlib (or any other) chart object """ def __init__(self, container, config): # Create the matplotlib figure and attach it to a canvas self.figure = Figure( (config.chart_width, config.chart_height), dpi=config.chart_dpi) self.canvas = FigureCanvasWxAgg(container, -1, self.figure) self.chart = self.figure.add_subplot(111) def layout(self): return self.canvas def draw(self, data, _): """ Redraw figure """ logging.debug('Redrawing time series') self.chart.clear() # self.axes.grid(self.cb_grid.IsChecked()) self.chart.plot(data['dates'], data['values']) self.figure.autofmt_xdate() self.canvas.draw()
class DemoPanel2(wx.Panel): def __init__(self, *args, **kwds): # begin wxGlade: DemoPanel2.__init__ kwds["style"] = wx.TAB_TRAVERSAL wx.Panel.__init__(self, *args, **kwds) self.__set_properties() self.__do_layout() # end wxGlade self.figure = Figure(figsize=(6,4), dpi=80) self.axes = self.figure.add_subplot(111) self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure) self.axes.set_autoscale_on(False) self.axes.axis([-20,20,0,0.7]) self.axes.set_title('Histogram') #self.particles = [None] #self.axes.hist(self.particles, 25, label = "Histogram") #hist return 3 elements tuple #self.axes.legend() self.canvas.draw() #self.bg = self.canvas.copy_from_bbox(self.axes.bbox) def __set_properties(self): # begin wxGlade: DemoPanel2.__set_properties pass # end wxGlade def __do_layout(self): # begin wxGlade: DemoPanel2.__do_layout pass
class CanvasPanel(wx.Panel): def __init__(self, parent, id=wx.ID_ANY): wx.Panel.__init__(self, parent, id=id) self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.canvas = FigureCanvas(self, -1, self.figure) self.canvas.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.Fit() self.Bind(wx.EVT_PAINT, self.OnPaint) def OnEnterWindow(self, event): "http://matplotlib.sourceforge.net/examples/user_interfaces/wxcursor_demo.html" self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_CROSS)) def OnPaint(self, event): logging.debug("%s: OnPaint!!!" % self.__class__.__name__) self.canvas.draw() def SendFigurePosEvent(self, t0, t1): # issue event logging.debug("EVENT sent!!") evt = FigurePosEvent(t0, t1, id=self.GetId()) self.GetEventHandler().ProcessEvent(evt) def OnFigurePosEvent(self, event): # logging.debug("EVENT received!!") self.zoom(event.t0, event.t1, send_event=False)
class EdgesCumulBarGraph(wx.Panel): ''' This panel holds edges cumulative bar graph. ''' def __init__(self, parent): ''' parent is a fram instance. ''' wx.Panel.__init__(self, parent = parent, id = -1) self.figure = Figure(dpi = DPI, figsize = (8, 4)) self.canvas = FigureCanvas(self, -1, self.figure) self.axes = self.figure.add_subplot(111) # Labels self.axes.set_title("Cumulative Number of Major Edges per Interval") self.axes.set_ylabel("Cumulative number of edges") self.axes.set_xlabel("Intervals (%)") # Sizers bSizer = wx.BoxSizer(wx.HORIZONTAL) bSizer.Add(self.canvas, 1, wx.EXPAND) self.SetSizer(bSizer) def DefineBarGraph(self, left, height): ''' Create bar graph. ''' self.axes.bar(left = left, height = height, width = 5, bottom = 0, color = "b") def DrawBarGraph(self): ''' Draw the bar graph. ''' self.canvas.draw()
class GraphPanel(wx.Panel): def __init__(self,parent): wx.Panel.__init__(self,parent) self.SetBackgroundColour('#FFFFFF') self.quote = wx.StaticText(self,label = "GRAPH PANEL", pos = (200,10)) self.figure = Figure(dpi=100,figsize=(5,8)) self.axes = self.figure.add_subplot(111) self.axes.axis([0,1,0,60]) self.axes.set_ylabel('time (s)') green = self.axes.axhline(y=-1,color='g',lw=4) blue = self.axes.axhline(y=-1,color='b',lw=4) red = self.axes.axhline(y=-1,color='r',lw=4) self.axes.legend((green,blue,red),("Tone","Level Press","Reward"),loc="upper right") self.canvas = FigureCanvas(self, -1, self.figure) wx.EVT_PAINT(self, self.OnPaint) def OnPaint(self, event): self.canvas.draw() event.Skip() def OnSetFocus(self, event): #self.color = '#0099f7' self.color = 'yellow' self.Refresh() def OnKillFocus(self, event): self.color = '#b3b3b3' self.Refresh()
def _create_canvas(self, parent): panel = QtGui.QWidget() def mousemoved(event): if event.xdata is not None: x, y = event.xdata, event.ydata name = "Axes" else: x, y = event.x, event.y name = "Figure" panel.info.setText("%s: %g, %g" % (name, x, y)) panel.mousemoved = mousemoved vbox = QtGui.QVBoxLayout() panel.setLayout(vbox) mpl_control = FigureCanvas(self.value) #❷ vbox.addWidget(mpl_control) if hasattr(self.value, "canvas_events"): for event_name, callback in self.value.canvas_events: mpl_control.mpl_connect(event_name, callback) mpl_control.mpl_connect("motion_notify_event", mousemoved) if self.factory.toolbar: #❸ toolbar = Toolbar(mpl_control, panel) vbox.addWidget(toolbar) panel.info = QtGui.QLabel(panel) vbox.addWidget(panel.info) return panel
class CanvasFrame(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, -1, title, size=(550, 350)) self.SetBackgroundColour(wx.NamedColor("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) self.change_plot(0) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.VERTICAL) self.add_buttonbar() self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.add_toolbar() # comment this out for no toolbar menuBar = wx.MenuBar() menu = wx.Menu() menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample") menuBar.Append(menu, "&File") if IS_GTK or IS_WIN: menu = wx.Menu() for i, (mt, func) in enumerate(functions): bm = mathtext_to_wxbitmap(mt) item = wx.MenuItem(menu, 1000 + i, "") item.SetBitmap(bm) menu.AppendItem(item) self.Bind(wx.EVT_MENU, self.OnChangePlot, item) menuBar.Append(menu, "&Functions") self.SetMenuBar(menuBar) self.SetSizer(self.sizer) self.Fit() def add_buttonbar(self): self.button_bar = wx.Panel(self) self.button_bar_sizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer.Add(self.button_bar, 0, wx.LEFT | wx.TOP | wx.GROW) for i, (mt, func) in enumerate(functions): bm = mathtext_to_wxbitmap(mt) button = wx.BitmapButton(self.button_bar, 1000 + i, bm) self.button_bar_sizer.Add(button, 1, wx.GROW) self.Bind(wx.EVT_BUTTON, self.OnChangePlot, button) self.button_bar.SetSizer(self.button_bar_sizer) def add_toolbar(self): """Copied verbatim from embedding_wx2.py""" self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() if IS_MAC: self.SetToolBar(self.toolbar) else: tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wx.Size(fw, th)) self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) self.toolbar.update() def OnPaint(self, event): self.canvas.draw() def OnChangePlot(self, event): self.change_plot(event.GetId() - 1000) def change_plot(self, plot_number): t = arange(1.0,3.0,0.01) s = functions[plot_number][1](t) self.axes.clear() self.axes.plot(t, s) self.Refresh()
class CapacityPanel(MyPanel): def __init__(self, *args, **kwargs): MyPanel.__init__(self, *args, **kwargs) self.vbox = wx.BoxSizer(wx.VERTICAL) fig = Figure(facecolor=self.face_col) self.ax = fig.add_subplot(111) self.canvas = FigureCanvas(self, -1, fig) self.vbox.Add(self.canvas, flag = wx.EXPAND | wx.ALL) self.SetSizerAndFit(self.vbox) pub.subscribe(self.redraw, "assignments_calced") def redraw(self, message): """Create a histogram""" e_caps = self.model.excessCap() e_caps = [x * 100 for x in e_caps] self.ax.clear() n, bins, patches = self.ax.hist(e_caps, normed=False, bins=10, color="cornflowerblue", rwidth=.8, linewidth=0) self.ax.set_xlabel("Excess Capacity (%)") self.ax.set_ylabel("No. of Courses") self.ax.set_title("Distribution of Excess Capacity") num_courses = float(len(e_caps)) s_labels = [ 100 * p.get_height()/num_courses for p in patches] s_labels = [ "%.0f%%" % p for p in s_labels] self.labelBars(patches, s_labels, self.ax) self.canvas.draw()
class BarsFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None) self.data = [5, 6, 9, 14] self.create_main_panel() self.draw_figure() def create_main_panel(self): self.panel = wx.Panel(self) self.fig = Figure((5.0, 4.0)) self.canvas = FigCanvas(self.panel, -1, self.fig) self.axes = self.fig.add_subplot(111) self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas) self.panel.SetSizer(self.vbox) self.vbox.Fit(self) def draw_figure(self): x = range(len(self.data)) self.axes.clear() self.axes.bar(left=x, height=self.data) self.canvas.draw() def on_exit(self, event): self.Destroy()
class PageThree(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.figure = Figure(dpi=50) self.canvas = FigureCanvasWxAgg(self, -1, self.figure) self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() self.plotLast = wx.Button(self,-1,label="Plot Last") self.Bind(wx.EVT_BUTTON, self.plotLastButtonClick, self.plotLast) topSizer = wx.BoxSizer(wx.HORIZONTAL) sizer = wx.BoxSizer(wx.VERTICAL) topSizer.Add(self.plotLast, 0, wxFIXED_MINSIZE) topSizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) sizer.Add(topSizer,1,wx.GROW) sizer.Add(self.toolbar, 0, wx.GROW) self.SetSizer(sizer) self.Fit() def plotLastButtonClick(self, evt): gh.plotGraph(self.figure) self.canvas.draw()
def __init__(self, parent, *args, **kwargs): """wx.Panel with a matplotlib figure Parameters ---------- figsize : tuple Figure dimensions (width, height) in inches dpi : int Dots per inch. facecolor : mpl color The figure patch facecolor; defaults to rc ``figure.facecolor`` edgecolor : mpl color The figure patch edge color; defaults to rc ``figure.edgecolor`` linewidth : scalar The figure patch edge linewidth; the default linewidth of the frame frameon : bool If ``False``, suppress drawing the figure frame subplotpars : A :class:`SubplotParams` instance, defaults to rc tight_layout : bool | dict If ``False`` use ``subplotpars``; if ``True`` adjust subplot parameters using :meth:`tight_layout` with default padding. When providing a dict containing the keys `pad`, `w_pad`, `h_pad` and `rect`, the default :meth:`tight_layout` paddings will be overridden. Defaults to rc ``figure.autolayout``. """ self.figure = Figure(*args, **kwargs) FigureCanvasWxAgg.__init__(self, parent, wx.ID_ANY, self.figure) self.Bind(wx.EVT_ENTER_WINDOW, self.ChangeCursor)
class GraphFrame(wx.Frame): """ The main frame of the application """ def __init__(self, state): wx.Frame.__init__(self, None, -1, state.title) self.state = state self.data = [] for i in range(len(state.fields)): self.data.append([]) self.paused = False self.create_main_panel() self.Bind(wx.EVT_IDLE, self.on_idle) self.redraw_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer) self.redraw_timer.Start(1000 * self.state.tickresolution) def create_main_panel(self): from matplotlib.backends.backend_wxagg import \ FigureCanvasWxAgg as FigCanvas self.panel = wx.Panel(self) self.init_plot() self.canvas = FigCanvas(self.panel, -1, self.fig) self.close_button = wx.Button(self.panel, -1, "Close") self.Bind(wx.EVT_BUTTON, self.on_close_button, self.close_button) self.pause_button = wx.Button(self.panel, -1, "Pause") self.Bind(wx.EVT_BUTTON, self.on_pause_button, self.pause_button) self.Bind(wx.EVT_UPDATE_UI, self.on_update_pause_button, self.pause_button) self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) self.hbox1.Add(self.close_button, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox1.AddSpacer(1) self.hbox1.Add(self.pause_button, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW) self.vbox.Add(self.hbox1, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.panel.SetSizer(self.vbox) self.vbox.Fit(self) def init_plot(self): self.dpi = 100 import pylab, numpy from matplotlib.figure import Figure self.fig = Figure((6.0, 3.0), dpi=self.dpi) self.axes = self.fig.add_subplot(111) self.axes.set_axis_bgcolor('white') pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) # plot the data as a line series, and save the reference # to the plotted line series # self.plot_data = [] if len(self.data[0]) == 0: max_y = min_y = 0 else: max_y = min_y = self.data[0][0] for i in range(len(self.data)): p = self.axes.plot( self.data[i], linewidth=1, color=self.state.colors[i], label=self.state.fields[i], )[0] self.plot_data.append(p) if len(self.data[i]) != 0: min_y = min(min_y, min(self.data[i])) max_y = max(max_y, max(self.data[i])) # create X data self.xdata = numpy.arange(-self.state.timespan, 0, self.state.tickresolution) self.axes.set_xbound(lower=self.xdata[0], upper=0) if min_y == max_y: self.axes.set_ybound(min_y, max_y + 0.1) self.axes.legend(self.state.fields, loc='upper left', bbox_to_anchor=(0, 1.1)) def draw_plot(self): """ Redraws the plot """ import numpy, pylab state = self.state if len(self.data[0]) == 0: print("no data to plot") return vhigh = max(self.data[0]) vlow = min(self.data[0]) for i in range(1, len(self.plot_data)): vhigh = max(vhigh, max(self.data[i])) vlow = min(vlow, min(self.data[i])) ymin = vlow - 0.05 * (vhigh - vlow) ymax = vhigh + 0.05 * (vhigh - vlow) if ymin == ymax: ymax = ymin + 0.1 ymin = ymin - 0.1 self.axes.set_ybound(lower=ymin, upper=ymax) self.axes.grid(True, color='gray') pylab.setp(self.axes.get_xticklabels(), visible=True) pylab.setp(self.axes.get_legend().get_texts(), fontsize='small') for i in range(len(self.plot_data)): ydata = numpy.array(self.data[i]) xdata = self.xdata if len(ydata) < len(self.xdata): xdata = xdata[-len(ydata):] self.plot_data[i].set_xdata(xdata) self.plot_data[i].set_ydata(ydata) self.canvas.draw() def on_pause_button(self, event): self.paused = not self.paused def on_update_pause_button(self, event): label = "Resume" if self.paused else "Pause" self.pause_button.SetLabel(label) def on_close_button(self, event): self.redraw_timer.Stop() self.Destroy() def on_idle(self, event): import time time.sleep(self.state.tickresolution * 0.5) def on_redraw_timer(self, event): # if paused do not add data, but still redraw the plot # (to respond to scale modifications, grid change, etc.) # state = self.state if state.close_graph.wait(0.001): self.redraw_timer.Stop() self.Destroy() return while state.child_pipe.poll(): state.values = state.child_pipe.recv() if self.paused: return for i in range(len(self.plot_data)): if state.values[i] is not None: self.data[i].append(state.values[i]) while len(self.data[i]) > len(self.xdata): self.data[i].pop(0) for i in range(len(self.plot_data)): if state.values[i] is None or len(self.data[i]) < 2: return self.draw_plot()
class GraphFrame(wx.Frame): """ The main frame of the application """ title = 'Demo: dynamic matplotlib graph' def __init__(self): wx.Frame.__init__(self, None, -1, self.title) self.datagen = DataGen() self.data = [self.datagen.next()] self.paused = False self.create_menu() self.create_status_bar() self.create_main_panel() self.redraw_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer) self.redraw_timer.Start(REFRESH_INTERVAL_MS) def create_menu(self): self.menubar = wx.MenuBar() menu_file = wx.Menu() m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S", "Save plot to file") self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt) menu_file.AppendSeparator() m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit") self.Bind(wx.EVT_MENU, self.on_exit, m_exit) self.menubar.Append(menu_file, "&File") self.SetMenuBar(self.menubar) def create_main_panel(self): self.panel = wx.Panel(self) self.init_plot() self.canvas = FigCanvas(self.panel, -1, self.fig) self.xmin_control = BoundControlBox(self.panel, -1, "X min", 0) self.xmax_control = BoundControlBox(self.panel, -1, "X max", 50) self.ymin_control = BoundControlBox(self.panel, -1, "Y min", 0) self.ymax_control = BoundControlBox(self.panel, -1, "Y max", 100) self.pause_button = wx.Button(self.panel, -1, "Pause") self.Bind(wx.EVT_BUTTON, self.on_pause_button, self.pause_button) self.Bind(wx.EVT_UPDATE_UI, self.on_update_pause_button, self.pause_button) self.cb_grid = wx.CheckBox(self.panel, -1, "Show Grid", style=wx.ALIGN_RIGHT) self.Bind(wx.EVT_CHECKBOX, self.on_cb_grid, self.cb_grid) self.cb_grid.SetValue(True) self.cb_xlab = wx.CheckBox(self.panel, -1, "Show X labels", style=wx.ALIGN_RIGHT) self.Bind(wx.EVT_CHECKBOX, self.on_cb_xlab, self.cb_xlab) self.cb_xlab.SetValue(True) self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) self.hbox1.Add(self.pause_button, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox1.AddSpacer(20) self.hbox1.Add(self.cb_grid, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox1.AddSpacer(10) self.hbox1.Add(self.cb_xlab, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) self.hbox2.Add(self.xmin_control, border=5, flag=wx.ALL) self.hbox2.Add(self.xmax_control, border=5, flag=wx.ALL) self.hbox2.AddSpacer(24) self.hbox2.Add(self.ymin_control, border=5, flag=wx.ALL) self.hbox2.Add(self.ymax_control, border=5, flag=wx.ALL) self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW) self.vbox.Add(self.hbox1, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.vbox.Add(self.hbox2, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.panel.SetSizer(self.vbox) self.vbox.Fit(self) def create_status_bar(self): self.statusbar = self.CreateStatusBar() def init_plot(self): self.dpi = 100 self.fig = Figure((3.0, 3.0), dpi=self.dpi) self.axes = self.fig.add_subplot(111) self.axes.set_axis_bgcolor('black') self.axes.set_title('Arduino Serial Data', size=12) pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) # plot the data as a line series, and save the reference # to the plotted line series # self.plot_data = self.axes.plot( self.data, linewidth=1, color=(1, 1, 0), )[0] def draw_plot(self): """ Redraws the plot """ # when xmin is on auto, it "follows" xmax to produce a # sliding window effect. therefore, xmin is assigned after # xmax. # if self.xmax_control.is_auto(): xmax = len(self.data) if len(self.data) > 50 else 50 else: xmax = int(self.xmax_control.manual_value()) if self.xmin_control.is_auto(): xmin = xmax - 50 else: xmin = int(self.xmin_control.manual_value()) # for ymin and ymax, find the minimal and maximal values # in the data set and add a mininal margin. # # note that it's easy to change this scheme to the # minimal/maximal value in the current display, and not # the whole data set. # if self.ymin_control.is_auto(): ymin = round(min(self.data), 0) - 1 else: ymin = int(self.ymin_control.manual_value()) if self.ymax_control.is_auto(): ymax = round(max(self.data), 0) + 1 else: ymax = int(self.ymax_control.manual_value()) self.axes.set_xbound(lower=xmin, upper=xmax) self.axes.set_ybound(lower=ymin, upper=ymax) # anecdote: axes.grid assumes b=True if any other flag is # given even if b is set to False. # so just passing the flag into the first statement won't # work. # if self.cb_grid.IsChecked(): self.axes.grid(True, color='gray') else: self.axes.grid(False) # Using setp here is convenient, because get_xticklabels # returns a list over which one needs to explicitly # iterate, and setp already handles this. # pylab.setp(self.axes.get_xticklabels(), visible=self.cb_xlab.IsChecked()) self.plot_data.set_xdata(np.arange(len(self.data))) self.plot_data.set_ydata(np.array(self.data)) self.canvas.draw() def on_pause_button(self, event): self.paused = not self.paused def on_update_pause_button(self, event): label = "Resume" if self.paused else "Pause" self.pause_button.SetLabel(label) def on_cb_grid(self, event): self.draw_plot() def on_cb_xlab(self, event): self.draw_plot() def on_save_plot(self, event): file_choices = "PNG (*.png)|*.png" dlg = wx.FileDialog( self, message="Save plot as...", defaultDir=os.getcwd(), defaultFile="plot.png", wildcard=file_choices, style=wx.SAVE) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.canvas.print_figure(path, dpi=self.dpi) self.flash_status_message("Saved to %s" % path) def on_redraw_timer(self, event): # if paused do not add data, but still redraw the plot # (to respond to scale modifications, grid change, etc.) # if not self.paused: self.data.append(self.datagen.next()) self.draw_plot() def on_exit(self, event): self.Destroy() def flash_status_message(self, msg, flash_len_ms=1500): self.statusbar.SetStatusText(msg) self.timeroff = wx.Timer(self) self.Bind( wx.EVT_TIMER, self.on_flash_status_off, self.timeroff) self.timeroff.Start(flash_len_ms, oneShot=True) def on_flash_status_off(self, event): self.statusbar.SetStatusText('')
class MainWindow(wx.Frame): MENU_ITEM_LOAD_STREAM = 0x00 MENU_ITEM_CLOSE_STREAM = 0x01 MENU_ITEM_DRAW_ALL_FRAMES = 0x02 MENU_ITEM_EXPORT_ALL_FRAMES = 0x03 MENU_ITEM_STREAM_PROPERTIES = 0xFE MENU_ITEM_EXIT = 0x04 MENU_ITEM_GO_TO_FIRST = 0x05 MENU_ITEM_GO_TO_LAST = 0x06 MENU_ITEM_GO_TO_PREVIOUS = 0x07 MENU_ITEM_GO_TO_NEXT = 0x08 MENU_ITEM_GO_TO = 0x09 MENU_ITEM_FRAME_SAVE = 0x0A MENU_ITEM_PLAY = 0x0B MENU_ITEM_STOP = 0x0C MENU_ITEM_COLORMAP = 0xFF MENU_ITEM_COLORMAP_JET = 0x0D MENU_ITEM_COLORMAP_HSV = 0x0E MENU_ITEM_COLORMAP_GRAY = 0x0F MENU_ITEM_COLORBAR = 0x10 MENU_ITEM_SET_LIMITS = 0x11 TOOL_FIRST = 0x20 TOOL_PREVIOUS = 0x21 TOOL_NEXT = 0x22 TOOL_LAST = 0x23 __figure = None __canvas = None __clim = -1.0, 1.0 __timer = None __filename = None __stream = None __frame = None def __init__(self, filename=None): super().__init__(parent=None, title="Stream view", size=(700, 500)) self.__createMenuBar() self.__createToolbar() self.__createAxes() self.CreateStatusBar() self.__timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, lambda event: self.autoNext(), self.__timer) self.Centre(wx.BOTH) self.SetMinSize((200, 100)) self.Show() self.drawClosedState() if filename is not None: self.loadStream(filename) self.Bind(wx.EVT_CLOSE, lambda event: self.onClose()) def onClose(self): self.closeStream() self.Destroy() def __createMenuBar(self): mainMenu = wx.MenuBar() fileMenu = wx.Menu() fileLoad = fileMenu.Append(self.MENU_ITEM_LOAD_STREAM, "L&oad stream...\tCTRL+O", "Loads stream from the hard disk", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.loadStreamCallback(), fileLoad) fileClose = fileMenu.Append(self.MENU_ITEM_CLOSE_STREAM, "&Close stream\tCTRL+W", "Coses the stream", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.closeStream(), fileClose) fileMenu.AppendSeparator() fileDraw = fileMenu.Append( self.MENU_ITEM_DRAW_ALL_FRAMES, "&Draw all frames...", "Saves each frame of the stream as an image in the certain folder", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.drawAllFramesCallback(), fileDraw) fileExport = fileMenu.Append( self.MENU_ITEM_EXPORT_ALL_FRAMES, "Export all frames...", "Saves all frames as data stored in a MATLAB file", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.exportAllFramesCallback(), fileExport) fileStreamProperties = fileMenu.Append( self.MENU_ITEM_STREAM_PROPERTIES, "Stream &properties\tALT+ENTER", "Prints all stream properties...", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.getStreamProperties(), fileStreamProperties) fileMenu.AppendSeparator() fileExit = fileMenu.Append(self.MENU_ITEM_EXIT, "&Exit\tCTRL+Q", "Quits from the program", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.Close(), fileExit) mainMenu.Append(fileMenu, "&File") frameMenu = wx.Menu() frameFirst = frameMenu.Append(self.MENU_ITEM_GO_TO_FIRST, "&First frame\tHOME", "Moves to the first frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.goToFirst(), frameFirst) framePrevious = frameMenu.Append(self.MENU_ITEM_GO_TO_PREVIOUS, "&Previous frame\tKP_4", "Moves to the previous frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.goToPrevious(), framePrevious) frameNext = frameMenu.Append(self.MENU_ITEM_GO_TO_NEXT, "&Next frame\tKP_6", "Moves to the next frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.goToNext(), frameNext) frameLast = frameMenu.Append(self.MENU_ITEM_GO_TO_LAST, "&Last frame\tEND", "Moves to the last frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.goToLast(), frameLast) frameGoto = frameMenu.Append(self.MENU_ITEM_GO_TO, "&Go to...\tCTRL+G", "Moves to the specified frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.goToCallback(), frameGoto) frameMenu.AppendSeparator() frameSave = frameMenu.Append(self.MENU_ITEM_FRAME_SAVE, "&Save frame...\tCTRL+S", "Saves a certain frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.saveFrameCallback(), frameSave) mainMenu.Append(frameMenu, "F&rame") viewMenu = wx.Menu() viewPlay = viewMenu.Append(self.MENU_ITEM_PLAY, "&Play...\tCTRL+P", "Plays the stream", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.play(), viewPlay) viewStop = viewMenu.Append(self.MENU_ITEM_STOP, "&Stop...\tCTRL+L", "Stops playing of the stream", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.stop(), viewStop) viewMenu.AppendSeparator() colormapMenu = wx.Menu() colormapJet = colormapMenu.Append( self.MENU_ITEM_COLORMAP_JET, "&Jet", "Specifies colored image representing non-periodic values", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, lambda event: self.jet(), colormapJet) colormapHsv = colormapMenu.Append( self.MENU_ITEM_COLORMAP_HSV, "&Hsv", "Speficies colored image representing periodic values", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, lambda event: self.hsv(), colormapHsv) colormapGray = colormapMenu.Append( self.MENU_ITEM_COLORMAP_GRAY, "&Gray", "Specifies black-and-white image for non-pediodic values", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, lambda event: self.gray(), colormapGray) viewMenu.Append(self.MENU_ITEM_COLORMAP, "Color&map", colormapMenu, "Specifies color codes for the matrix values") colormapMenu.Check(self.MENU_ITEM_COLORMAP_JET, True) viewColorbar = viewMenu.Append( self.MENU_ITEM_COLORBAR, "Color&bar", "Toggles on/off colorbar at the right of the frame image", wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.colorbarCallback, viewColorbar) viewSetLimits = viewMenu.Append( self.MENU_ITEM_SET_LIMITS, "Set &limits...", "Sets minimum and maximum value for the color axis", wx.ITEM_NORMAL) self.Bind(wx.EVT_MENU, lambda event: self.setLimitsCallback(), viewSetLimits) mainMenu.Append(viewMenu, "&View") self.SetMenuBar(mainMenu) def __createToolbar(self): toolbar = self.CreateToolBar() current_dir = os.path.dirname(__file__) first_icon_filename = os.path.join(current_dir, "beginning-media-button-arrow.svg") first_icon = wx.Bitmap(first_icon_filename) first = toolbar.AddTool(self.TOOL_FIRST, "Go to first frame", first_icon, "Moves to the first frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_TOOL, lambda event: self.goToFirst(), first) previous_icon_filename = os.path.join(current_dir, "left-arrow.svg") previous_icon = wx.Bitmap(previous_icon_filename) previous = toolbar.AddTool(self.TOOL_PREVIOUS, "Go to previous frame", previous_icon, "Moves to the previous frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_TOOL, lambda event: self.goToPrevious(), previous) next_icon_filename = os.path.join(current_dir, "right-arrow.svg") next_icon = wx.Bitmap(next_icon_filename) next = toolbar.AddTool(self.TOOL_NEXT, "Go to next frame", next_icon, "Moves to the next frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_TOOL, lambda event: self.goToNext(), next) last_icon_filename = os.path.join(current_dir, "finishing-media-button-arrow.svg") last_icon = wx.Bitmap(last_icon_filename) last = toolbar.AddTool(self.TOOL_LAST, "Go to last frame", last_icon, "Moves to the last frame", wx.ITEM_NORMAL) self.Bind(wx.EVT_TOOL, lambda event: self.goToLast(), last) toolbar.Realize() def __createAxes(self): panel = wx.Panel(self) self.__figure = Figure() self.__axes = self.__figure.add_subplot(111) self.__canvas = FigureCanvas(panel, -1, self.__figure) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.__canvas, 1, wx.ALL | wx.EXPAND, 10) panel.SetSizer(sizer) panel.Fit() def drawClosedState(self): self.SetTitle("Stream view") menu = self.GetMenuBar() menu.Enable(self.MENU_ITEM_CLOSE_STREAM, False) menu.Enable(self.MENU_ITEM_DRAW_ALL_FRAMES, False) menu.Enable(self.MENU_ITEM_EXPORT_ALL_FRAMES, False) menu.Enable(self.MENU_ITEM_STREAM_PROPERTIES, False) menu.EnableTop(1, False) menu.EnableTop(2, False) toolbar = self.GetToolBar() toolbar.EnableTool(self.TOOL_FIRST, False) toolbar.EnableTool(self.TOOL_LAST, False) toolbar.EnableTool(self.TOOL_PREVIOUS, False) toolbar.EnableTool(self.TOOL_NEXT, False) self.__figure.clf() self.__canvas.draw() def drawFrame(self): self.SetTitle("{0} - Stream view".format( os.path.basename(self.__filename))) menu = self.GetMenuBar() tools = self.GetToolBar() menu.Enable(self.MENU_ITEM_CLOSE_STREAM, True) menu.Enable(self.MENU_ITEM_DRAW_ALL_FRAMES, True) menu.Enable(self.MENU_ITEM_EXPORT_ALL_FRAMES, True) menu.Enable(self.MENU_ITEM_STREAM_PROPERTIES, True) menu.EnableTop(1, True) menu.EnableTop(2, True) tools.EnableTool(self.TOOL_FIRST, True) tools.EnableTool(self.TOOL_LAST, True) current_frame = self.__stream.getHeaders()['current_frame'] if current_frame > 1: menu.Enable(self.MENU_ITEM_GO_TO_PREVIOUS, True) tools.EnableTool(self.TOOL_PREVIOUS, True) else: menu.Enable(self.MENU_ITEM_GO_TO_PREVIOUS, False) tools.EnableTool(self.TOOL_PREVIOUS, False) if current_frame < self.__stream.getHeaders()['nframes']: menu.Enable(self.MENU_ITEM_GO_TO_NEXT, True) tools.EnableTool(self.TOOL_NEXT, True) else: menu.Enable(self.MENU_ITEM_GO_TO_NEXT, False) tools.EnableTool(self.TOOL_NEXT, False) self.__figure.clf() ax = self.__figure.add_subplot(111) img = ax.imshow(self.__frame, cmap=self.getColormap(), vmin=self.__clim[0], vmax=self.__clim[1]) ax.set_aspect("equal") time = 1000 * (current_frame - 1) / self.__stream.getHeaders()['sample_rate'] ax.set_title("t = {0:.2f} ms".format(time)) if self.isColorbar(): self.__figure.colorbar(img) self.__canvas.draw() def getColormap(self): menu = self.GetMenuBar() if menu.IsChecked(self.MENU_ITEM_COLORMAP_JET): return "jet" if menu.IsChecked(self.MENU_ITEM_COLORMAP_HSV): return "hsv" if menu.IsChecked(self.MENU_ITEM_COLORMAP_GRAY): return "gray" def isColorbar(self): return self.GetMenuBar().IsChecked(self.MENU_ITEM_COLORBAR) def loadStreamCallback(self): dlg = wx.FileDialog(self, "Open the stream file", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) result = dlg.ShowModal() if result == wx.ID_CANCEL: return filename = dlg.GetPath() self.loadStream(filename) def loadStream(self, filename): self.closeStream() import vis_brain.streams import inspect from vis_brain.streams.Stream import Stream for module_name in dir(vis_brain.streams): instance = getattr(vis_brain.streams, module_name) if inspect.isclass(instance): if issubclass(instance, Stream): try: self.__loadSpecifiedStream(filename, instance) return except Exception as exc: print( "Stream class {0} gave {1}. Trying another class". format(instance.__name__, exc)) wx.MessageDialog( self, "Unsupported stream format or error opening the stream", "Load stream", wx.OK | wx.ICON_ERROR | wx.CENTRE).ShowModal() def __loadSpecifiedStream(self, filename, streamclass): stream = streamclass(filename, stream_mode="read") stream.open() self.__filename = filename self.__stream = stream self.__frame = stream.read() self.drawFrame() def closeStream(self): if self.__stream is not None and self.__stream.getHeaders()['opened']: self.__stream.close() self.drawClosedState() def drawAllFramesCallback(self): dlg = wx.DirDialog(self, "Folder where a set of PNG files shall be located") if dlg.ShowModal() == wx.ID_OK: dirname = dlg.GetPath() if not os.path.isdir(dirname): os.mkdir(dirname) self.drawAllFrames(dirname) def drawAllFrames(self, dirname): self.goToFirst() while self.__stream.getHeaders( )['current_frame'] < self.__stream.getHeaders()['nframes']: time = (self.__stream.getHeaders()['current_frame'] - 1) * 1000.0 / self.__stream.getHeaders()['sample_rate'] short_file = "t={0}ms.png".format(time) full_file = os.path.join(dirname, short_file) self.__figure.savefig(full_file) self.GetStatusBar().SetStatusText("Saving {0} ms...".format(time)) self.goToNext() self.GetStatusBar().SetStatusText("") def exportAllFramesCallback(self): dlg = wx.FileDialog(self, "Export all frames to .mat file", wildcard="MAT files (.mat)|*.mat", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetPath() if filename[-4:] != ".mat": filename += ".mat" self.exportAllFrames(filename) def exportAllFrames(self, filename): import scipy.io output_data = { "stream_name": self.__filename, "times": [], "time_units": "ms", "frames": [], "nframes": self.__stream.getHeaders()['nframes'], "sample_rate": self.__stream.getHeaders()['sample_rate'], "height": self.__stream.getHeaders()['height'], "width": self.__stream.getHeaders()['width'], "height_um": self.__stream.getHeaders()['height_um'], "width_um": self.__stream.getHeaders()['width_um'] } print(self.__stream) self.__stream.first() while self.__stream.getHeaders( )['current_frame'] < self.__stream.getHeaders()['nframes']: time = self.__stream.getHeaders( )['current_frame'] * 1000 / self.__stream.getHeaders( )['sample_rate'] self.GetStatusBar().SetStatusText( "Exporting t = {0} ms".format(time)) output_data["times"].append(time) frame = self.__stream.read() output_data["frames"].append(frame) output_data['times'] = np.array(output_data['times']) scipy.io.savemat(filename, output_data) self.GetStatusBar().SetStatusText("") self.goToFirst() def getStreamProperties(self): from .StreamPropertiesWindow import StreamPropertiesWindow dlg = StreamPropertiesWindow(self, self.__stream) dlg.ShowModal() def goToFirst(self): try: self.__stream.first() self.__frame = self.__stream.read() self.drawFrame() except Exception as err: wx.MessageBox(str(err), "Moving to the beginning of the stream", wx.OK | wx.ICON_ERROR | wx.CENTRE) def goToPrevious(self): try: self.__stream.move(-2) self.__frame = self.__stream.read() self.drawFrame() except Exception as err: wx.MessageBox(str(err), "Moving to the previous frame", wx.OK | wx.ICON_ERROR | wx.CENTRE) def goToNext(self): try: self.__frame = self.__stream.read() self.drawFrame() except Exception as err: wx.MessageBox(str(err), "Moving to the next frame", wx.OK | wx.ICON_ERROR | wx.CENTRE) def autoNext(self): headers = self.__stream.getHeaders() if headers['current_frame'] == headers['nframes']: self.goToFirst() else: self.goToNext() def goToLast(self): try: self.__stream.last() self.__frame = self.__stream.read() self.drawFrame() except Exception as err: wx.MessageBox(str(err), "Moving to the last frame", wx.OK + wx.ICON_ERROR | wx.CENTRE) def goToCallback(self): from .GoToWindow import GoToWindow dlg = GoToWindow(self, self.__stream) if dlg.ShowModal() == wx.ID_OK: n = dlg.getFrameNumber() self.goTo(n) def goTo(self, n): self.__stream.first() self.__stream.move(n) self.__frame = self.__stream.read() self.drawFrame() def saveFrameBin(self, filename): if filename[-4:] != ".bin": filename += ".bin" from vis_brain.readers import BinReader reader = BinReader(filename) reader.setHeightUm(self.__stream.getHeaders()["height_um"]) reader.setWidthUm(self.__stream.getHeaders()["width_um"]) reader.save(self.__frame) def saveFrameMat(self, filename): if filename[-4:] != ".mat": filename += ".mat" import scipy.io output_data = { "stream_name": self.__filename, "frame_number": self.__stream.getHeaders()["current_frame"], "frame_time": (self.__stream.getHeaders()["current_frame"] - 1) * 1000 / self.__stream.getHeaders()['sample_rate'], "frame_time_units": "ms", "height": self.__stream.getHeaders()['height'], "width": self.__stream.getHeaders()["width"], "height_um": self.__stream.getHeaders()["height_um"], "width_um": self.__stream.getHeaders()["width_um"], "data": self.__frame } scipy.io.savemat(filename, output_data) def saveFramePng(self, filename): print("SAVE FRAME TO PNG: " + filename) def saveFrameCallback(self): dlg = wx.FileDialog( self, "Save Frame", wildcard="vis-brain data file (.bin)|*.bin|" + "MATLAB/Octave file (.mat)|*.mat|Image (.png)|*.png", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetPath() index = dlg.GetFilterIndex() if index == 0: self.saveFrameBin(filename) if index == 1: self.saveFrameMat(filename) if index == 2: self.saveFramePng(filename) def play(self): actualTime = 1000 / self.__stream.getHeaders()['sample_rate'] presentationTime = int(actualTime * 20) self.__timer.Start(presentationTime, wx.TIMER_CONTINUOUS) def stop(self): self.__timer.Stop() def jet(self): self.drawFrame() def hsv(self): self.drawFrame() def gray(self): self.drawFrame() def colorbarCallback(self, event): self.drawFrame() def setLimits(self, minValue, maxValue): self.__clim = minValue, maxValue self.drawFrame() def setLimitsCallback(self): from .SetLimitsWindow import SetLimitsWindow dlg = SetLimitsWindow(self, self.__clim) if dlg.ShowModal() == wx.ID_OK: limits = dlg.getLimits() self.setLimits(limits[0], limits[1])
class GraphCanvasPanel(wx.Panel): def __init__(self, graphFrame, parent): super().__init__(parent) self.graphFrame = graphFrame # Remove matplotlib font cache, see #234 try: cache_dir = mpl._get_cachedir() except (KeyboardInterrupt, SystemExit): raise except: cache_dir = os.path.expanduser(os.path.join('~', '.matplotlib')) cache_file = os.path.join(cache_dir, 'fontList.cache') if os.access(cache_dir, os.W_OK | os.X_OK) and os.path.isfile(cache_file): os.remove(cache_file) mainSizer = wx.BoxSizer(wx.VERTICAL) self.figure = Figure(figsize=(5, 3), tight_layout={'pad': 1.08}) rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get() clr = [c / 255. for c in rgbtuple] self.figure.set_facecolor(clr) self.figure.set_edgecolor(clr) self.canvas = Canvas(self, -1, self.figure) self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple)) self.canvas.mpl_connect('button_press_event', self.OnMplCanvasClick) self.subplot = self.figure.add_subplot(111) self.subplot.grid(True) mainSizer.Add(self.canvas, 1, wx.EXPAND | wx.ALL, 0) self.SetSizer(mainSizer) self.xMark = None self.mplOnDragHandler = None self.mplOnReleaseHandler = None def draw(self, accurateMarks=True): self.subplot.clear() self.subplot.grid(True) allXs = set() allYs = set() plotData = {} legendData = [] chosenX = self.graphFrame.ctrlPanel.xType chosenY = self.graphFrame.ctrlPanel.yType self.subplot.set(xlabel=self.graphFrame.ctrlPanel.formatLabel(chosenX), ylabel=self.graphFrame.ctrlPanel.formatLabel(chosenY)) mainInput, miscInputs = self.graphFrame.ctrlPanel.getValues() view = self.graphFrame.getView() sources = self.graphFrame.ctrlPanel.sources if view.hasTargets: iterList = tuple( itertools.product(sources, self.graphFrame.ctrlPanel.targets)) else: iterList = tuple((f, None) for f in sources) # Draw plot lines and get data for legend for source, target in iterList: # Get line style data try: colorData = BASE_COLORS[source.colorID] except KeyError: pyfalog.warning('Invalid color "{}" for "{}"'.format( source.colorID, source.name)) continue color = colorData.hsl lineStyle = 'solid' if target is not None: try: lightnessData = LIGHTNESSES[target.lightnessID] except KeyError: pyfalog.warning('Invalid lightness "{}" for "{}"'.format( target.lightnessID, target.name)) continue color = lightnessData.func(color) try: lineStyleData = STYLES[target.lineStyleID] except KeyError: pyfalog.warning('Invalid line style "{}" for "{}"'.format( target.lightnessID, target.name)) continue lineStyle = lineStyleData.mplSpec color = hsv_to_rgb(hsl_to_hsv(color)) # Get point data try: xs, ys = view.getPlotPoints(mainInput=mainInput, miscInputs=miscInputs, xSpec=chosenX, ySpec=chosenY, src=source, tgt=target) if not self.__checkNumbers(xs, ys): pyfalog.warning( 'Failed to plot "{}" vs "{}" due to inf or NaN in values' .format(source.name, '' if target is None else target.name)) continue plotData[(source, target)] = (xs, ys) allXs.update(xs) allYs.update(ys) # If we have single data point, show marker - otherwise line won't be shown if len(xs) == 1 and len(ys) == 1: self.subplot.plot(xs, ys, color=color, linestyle=lineStyle, marker='.') else: self.subplot.plot(xs, ys, color=color, linestyle=lineStyle) # Fill data for legend if target is None: legendData.append((color, lineStyle, source.shortName)) else: legendData.append( (color, lineStyle, '{} vs {}'.format(source.shortName, target.shortName))) except (KeyboardInterrupt, SystemExit): raise except Exception: pyfalog.warning('Failed to plot "{}" vs "{}"'.format( source.name, '' if target is None else target.name)) self.canvas.draw() self.Refresh() return # Setting Y limits for canvas if self.graphFrame.ctrlPanel.showY0: allYs.add(0) canvasMinY, canvasMaxY = self._getLimits(allYs, minExtra=0.05, maxExtra=0.1) canvasMinX, canvasMaxX = self._getLimits(allXs, minExtra=0.02, maxExtra=0.02) self.subplot.set_ylim(bottom=canvasMinY, top=canvasMaxY) self.subplot.set_xlim(left=canvasMinX, right=canvasMaxX) # Process X marks line if self.xMark is not None: minX = min(allXs, default=None) maxX = max(allXs, default=None) if minX is not None and maxX is not None: minY = min(allYs, default=None) maxY = max(allYs, default=None) yDiff = (maxY or 0) - (minY or 0) xMark = max(min(self.xMark, maxX), minX) # If in top 10% of X coordinates, align labels differently if xMark > canvasMinX + 0.9 * (canvasMaxX - canvasMinX): labelAlignment = 'right' labelPrefix = '' labelSuffix = ' ' else: labelAlignment = 'left' labelPrefix = ' ' labelSuffix = '' # Draw line self.subplot.axvline(x=xMark, linestyle='dotted', linewidth=1, color=(0, 0, 0)) # Draw its X position if chosenX.unit is None: xLabel = '{}{}{}'.format(labelPrefix, roundToPrec(xMark, 4), labelSuffix) else: xLabel = '{}{} {}{}'.format(labelPrefix, roundToPrec(xMark, 4), chosenX.unit, labelSuffix) self.subplot.annotate(xLabel, xy=(xMark, canvasMaxY - 0.01 * (canvasMaxY - canvasMinY)), xytext=(0, 0), annotation_clip=False, textcoords='offset pixels', ha=labelAlignment, va='top', fontsize='small') # Get Y values yMarks = set() def addYMark(val): if val is None: return # Round according to shown Y range - the bigger the range, # the rougher the rounding if yDiff != 0: rounded = roundToPrec(val, 4, nsValue=yDiff) else: rounded = val # If due to some bug or insufficient plot density we're # out of bounds, do not add anything if minY <= val <= maxY or minY <= rounded <= maxY: yMarks.add(rounded) for source, target in iterList: xs, ys = plotData[(source, target)] if not xs or xMark < min(xs) or xMark > max(xs): continue # Fetch values from graphs when we're asked to provide accurate data if accurateMarks: try: y = view.getPoint(x=xMark, miscInputs=miscInputs, xSpec=chosenX, ySpec=chosenY, src=source, tgt=target) addYMark(y) except (KeyboardInterrupt, SystemExit): raise except Exception: pyfalog.warning( 'Failed to get X mark for "{}" vs "{}"'.format( source.name, '' if target is None else target.name)) # Silently skip this mark, otherwise other marks and legend display will fail continue # Otherwise just do linear interpolation between two points else: if xMark in xs: # We might have multiples of the same value in our sequence, pick value for the last one idx = len(xs) - xs[::-1].index(xMark) - 1 addYMark(ys[idx]) continue idx = bisect(xs, xMark) yMark = self._interpolateX(x=xMark, x1=xs[idx - 1], y1=ys[idx - 1], x2=xs[idx], y2=ys[idx]) addYMark(yMark) # Draw Y values for yMark in yMarks: self.subplot.annotate('{}{}{}'.format( labelPrefix, yMark, labelSuffix), xy=(xMark, yMark), xytext=(0, 0), textcoords='offset pixels', ha=labelAlignment, va='center', fontsize='small') legendLines = [] for i, iData in enumerate(legendData): color, lineStyle, label = iData legendLines.append( Line2D([0], [0], color=color, linestyle=lineStyle, label=label.replace('$', '\$'))) if len(legendLines) > 0 and self.graphFrame.ctrlPanel.showLegend: legend = self.subplot.legend(handles=legendLines) for t in legend.get_texts(): t.set_fontsize('small') for l in legend.get_lines(): l.set_linewidth(1) self.canvas.draw() self.Refresh() def markXApproximate(self, x): if x is not None: self.xMark = x self.draw(accurateMarks=False) def unmarkX(self): self.xMark = None self.draw() @staticmethod def _getLimits(vals, minExtra=0, maxExtra=0): minVal = min(vals, default=0) maxVal = max(vals, default=0) # Extend range a little for some visual space valRange = maxVal - minVal minVal -= valRange * minExtra maxVal += valRange * maxExtra # Extend by % of value if we show function of a constant if minVal == maxVal: minVal -= minVal * 0.05 maxVal += minVal * 0.05 # If still equal, function is 0, spread out visual space as special case if minVal == maxVal: minVal -= 5 maxVal += 5 return minVal, maxVal @staticmethod def _interpolateX(x, x1, y1, x2, y2): pos = (x - x1) / (x2 - x1) y = y1 + pos * (y2 - y1) return y @staticmethod def __checkNumbers(xs, ys): for number in itertools.chain(xs, ys): if math.isnan(number) or math.isinf(number): return False return True # Matplotlib event handlers def OnMplCanvasClick(self, event): if event.button == 1: if not self.mplOnDragHandler: self.mplOnDragHandler = self.canvas.mpl_connect( 'motion_notify_event', self.OnMplCanvasDrag) if not self.mplOnReleaseHandler: self.mplOnReleaseHandler = self.canvas.mpl_connect( 'button_release_event', self.OnMplCanvasRelease) self.markXApproximate(event.xdata) elif event.button == 3: self.unmarkX() def OnMplCanvasDrag(self, event): self.markXApproximate(event.xdata) def OnMplCanvasRelease(self, event): if event.button == 1: if self.mplOnDragHandler: self.canvas.mpl_disconnect(self.mplOnDragHandler) self.mplOnDragHandler = None if self.mplOnReleaseHandler: self.canvas.mpl_disconnect(self.mplOnReleaseHandler) self.mplOnReleaseHandler = None # Do not write markX here because of strange mouse behavior: when dragging, # sometimes when you release button, x coordinate changes. To avoid that, # we just re-use coordinates set on click/drag and just request to redraw # using accurate data self.draw(accurateMarks=True)
class MPL_Panel_base(wx.Panel): ''' #MPL_Panel_base面板,可以继承或者创建实例''' def __init__(self, parent): wx.Panel.__init__(self, parent=parent, id=-1) self.Figure = matplotlib.figure.Figure(figsize=(4, 3)) self.axes = self.Figure.add_axes([0.1, 0.1, 0.8, 0.8]) self.FigureCanvas = FigureCanvas(self, -1, self.Figure) self.NavigationToolbar = NavigationToolbar(self.FigureCanvas) self.StaticText = wx.StaticText(self, -1, label='Show Help String') self.SubBoxSizer = wx.BoxSizer(wx.HORIZONTAL) self.SubBoxSizer.Add(self.NavigationToolbar, proportion=0, border=2, flag=wx.ALL | wx.EXPAND) self.SubBoxSizer.Add(self.StaticText, proportion=-1, border=2, flag=wx.ALL | wx.EXPAND) self.TopBoxSizer = wx.BoxSizer(wx.VERTICAL) self.TopBoxSizer.Add(self.SubBoxSizer, proportion=-1, border=2, flag=wx.ALL | wx.EXPAND) self.TopBoxSizer.Add(self.FigureCanvas, proportion=-10, border=2, flag=wx.ALL | wx.EXPAND) self.SetSizer(self.TopBoxSizer) ###方便调用 self.pylab = pylab self.pl = pylab self.pyplot = pyplot self.numpy = np self.np = np self.plt = pyplot self.pylab.gray() # 总是显示灰度图 def UpdatePlot(self): '''#修改图形的任何属性后都必须使用self.UpdatePlot()更新GUI界面 ''' self.FigureCanvas.draw() def plot(self, *args, **kwargs): '''#最常用的绘图命令plot ''' self.axes.plot(*args, **kwargs) self.UpdatePlot() def imshow(self, im): self.axes.imshow(im) self.UpdatePlot() def semilogx(self, *args, **kwargs): ''' #对数坐标绘图命令 ''' self.axes.semilogx(*args, **kwargs) self.UpdatePlot() def semilogy(self, *args, **kwargs): ''' #对数坐标绘图命令 ''' self.axes.semilogy(*args, **kwargs) self.UpdatePlot() def loglog(self, *args, **kwargs): ''' #对数坐标绘图命令 ''' self.axes.loglog(*args, **kwargs) self.UpdatePlot() def grid(self, flag=True): ''' ##显示网格 ''' if flag: self.axes.grid() else: self.axes.grid(False) def title_MPL(self, TitleString="wxMatPlotLib Example In wxPython"): ''' # 给图像添加一个标题 ''' self.axes.set_title(TitleString) def xlabel(self, XabelString="X"): ''' # Add xlabel to the plotting ''' self.axes.set_xlabel(XabelString) def ylabel(self, YabelString="Y"): ''' # Add ylabel to the plotting ''' self.axes.set_ylabel(YabelString) def xticker(self, major_ticker=1.0, minor_ticker=0.1): ''' # 设置X轴的刻度大小 ''' self.axes.xaxis.set_major_locator(MultipleLocator(major_ticker)) self.axes.xaxis.set_minor_locator(MultipleLocator(minor_ticker)) def yticker(self, major_ticker=1.0, minor_ticker=0.1): ''' # 设置Y轴的刻度大小 ''' self.axes.yaxis.set_major_locator(MultipleLocator(major_ticker)) self.axes.yaxis.set_minor_locator(MultipleLocator(minor_ticker)) def legend(self, *args, **kwargs): ''' #图例legend for the plotting ''' self.axes.legend(*args, **kwargs) def xlim(self, x_min, x_max): ''' # 设置x轴的显示范围 ''' self.axes.set_xlim(x_min, x_max) def ylim(self, y_min, y_max): ''' # 设置y轴的显示范围 ''' self.axes.set_ylim(y_min, y_max) def savefig(self, *args, **kwargs): ''' #保存图形到文件 ''' self.Figure.savefig(*args, **kwargs) def cla(self): ''' # 再次画图前,必须调用该命令清空原来的图形 ''' self.axes.clear() self.Figure.set_canvas(self.FigureCanvas) self.UpdatePlot() def ShowHelpString(self, HelpString="Show Help String"): ''' #可以用它来显示一些帮助信息,如鼠标位置等 ''' self.StaticText.SetLabel(HelpString)
class DialogWinFunc(wx.Dialog): def __init__(self, parent, winFunc): self.winFunc = winFunc x = numpy.linspace(-numpy.pi, numpy.pi, 1000) self.data = numpy.sin(x) + 0j wx.Dialog.__init__(self, parent=parent, title="Window Function") self.figure = matplotlib.figure.Figure(facecolor='white', figsize=(5, 4)) self.figure.suptitle('Window Function') self.canvas = FigureCanvas(self, -1, self.figure) self.axesWin = self.figure.add_subplot(211) self.axesFft = self.figure.add_subplot(212) text = wx.StaticText(self, label='Function') self.choice = wx.Choice(self, choices=WINFUNC[::2]) self.choice.SetSelection(WINFUNC[::2].index(winFunc)) sizerButtons = wx.StdDialogButtonSizer() buttonOk = wx.Button(self, wx.ID_OK) buttonCancel = wx.Button(self, wx.ID_CANCEL) sizerButtons.AddButton(buttonOk) sizerButtons.AddButton(buttonCancel) sizerButtons.Realize() sizerFunction = wx.BoxSizer(wx.HORIZONTAL) sizerFunction.Add(text, flag=wx.ALL, border=5) sizerFunction.Add(self.choice, flag=wx.ALL, border=5) sizerGrid = wx.GridBagSizer(5, 5) sizerGrid.Add(self.canvas, pos=(0, 0), span=(1, 2), border=5) sizerGrid.Add(sizerFunction, pos=(1, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) sizerGrid.Add(sizerButtons, pos=(2, 1), flag=wx.ALIGN_RIGHT | wx.ALL, border=5) self.Bind(wx.EVT_CHOICE, self.__on_choice, self.choice) self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk) self.__plot() self.SetSizerAndFit(sizerGrid) def __plot(self): pos = WINFUNC[::2].index(self.winFunc) function = WINFUNC[1::2][pos](512) self.axesWin.clear() self.axesWin.plot(function, 'g') self.axesWin.set_xlabel('Time') self.axesWin.set_ylabel('Multiplier') self.axesWin.set_xlim(0, 512) self.axesWin.set_xticklabels([]) self.axesFft.clear() self.axesFft.psd(self.data, NFFT=512, Fs=1000, window=function) self.axesFft.set_xlabel('Frequency') self.axesFft.set_ylabel('$\mathsf{dB/\sqrt{Hz}}$') self.axesFft.set_xlim(-256, 256) self.axesFft.set_xticklabels([]) self.figure.tight_layout() self.canvas.draw() def __on_choice(self, _event): self.winFunc = WINFUNC[::2][self.choice.GetSelection()] self.plot() def __on_ok(self, _event): self.EndModal(wx.ID_OK) def get_win_func(self): return self.winFunc
def __init__(self, parent, device, offset, winFunc): self.device = device self.offset = offset * 1e3 self.winFunc = winFunc self.band1 = None self.band2 = None wx.Dialog.__init__(self, parent=parent, title="Scan Offset") figure = matplotlib.figure.Figure(facecolor='white') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(self, -1, figure) textHelp = wx.StaticText( self, label="Remove the aerial and press refresh, " "adjust the offset so the shaded areas overlay the flattest parts " "of the plot_line.") textFreq = wx.StaticText(self, label="Test frequency (MHz)") self.spinFreq = wx.SpinCtrl(self) self.spinFreq.SetRange(F_MIN, F_MAX) self.spinFreq.SetValue(200) textGain = wx.StaticText(self, label="Test gain (dB)") self.spinGain = wx.SpinCtrl(self) self.spinGain.SetRange(-100, 200) self.spinGain.SetValue(200) refresh = wx.Button(self, wx.ID_ANY, 'Refresh') self.Bind(wx.EVT_BUTTON, self.__on_refresh, refresh) textOffset = wx.StaticText(self, label="Offset (kHz)") self.spinOffset = wx.SpinCtrl(self) self.spinOffset.SetRange(0, ((SAMPLE_RATE / 2) - BANDWIDTH) / 1e3) self.spinOffset.SetValue(offset) self.Bind(wx.EVT_SPINCTRL, self.__on_spin, self.spinOffset) sizerButtons = wx.StdDialogButtonSizer() buttonOk = wx.Button(self, wx.ID_OK) buttonCancel = wx.Button(self, wx.ID_CANCEL) sizerButtons.AddButton(buttonOk) sizerButtons.AddButton(buttonCancel) sizerButtons.Realize() self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk) boxSizer1 = wx.BoxSizer(wx.HORIZONTAL) boxSizer1.Add(textFreq, border=5) boxSizer1.Add(self.spinFreq, border=5) boxSizer1.Add(textGain, border=5) boxSizer1.Add(self.spinGain, border=5) boxSizer2 = wx.BoxSizer(wx.HORIZONTAL) boxSizer2.Add(textOffset, border=5) boxSizer2.Add(self.spinOffset, border=5) gridSizer = wx.GridBagSizer(5, 5) gridSizer.Add(self.canvas, pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(textHelp, pos=(1, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(boxSizer1, pos=(2, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(refresh, pos=(3, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(boxSizer2, pos=(4, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(sizerButtons, pos=(5, 1), flag=wx.ALIGN_RIGHT | wx.ALL, border=5) self.SetSizerAndFit(gridSizer) self.__draw_limits() self.__setup_plot()
class DialogOffset(wx.Dialog): def __init__(self, parent, device, offset, winFunc): self.device = device self.offset = offset * 1e3 self.winFunc = winFunc self.band1 = None self.band2 = None wx.Dialog.__init__(self, parent=parent, title="Scan Offset") figure = matplotlib.figure.Figure(facecolor='white') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(self, -1, figure) textHelp = wx.StaticText( self, label="Remove the aerial and press refresh, " "adjust the offset so the shaded areas overlay the flattest parts " "of the plot_line.") textFreq = wx.StaticText(self, label="Test frequency (MHz)") self.spinFreq = wx.SpinCtrl(self) self.spinFreq.SetRange(F_MIN, F_MAX) self.spinFreq.SetValue(200) textGain = wx.StaticText(self, label="Test gain (dB)") self.spinGain = wx.SpinCtrl(self) self.spinGain.SetRange(-100, 200) self.spinGain.SetValue(200) refresh = wx.Button(self, wx.ID_ANY, 'Refresh') self.Bind(wx.EVT_BUTTON, self.__on_refresh, refresh) textOffset = wx.StaticText(self, label="Offset (kHz)") self.spinOffset = wx.SpinCtrl(self) self.spinOffset.SetRange(0, ((SAMPLE_RATE / 2) - BANDWIDTH) / 1e3) self.spinOffset.SetValue(offset) self.Bind(wx.EVT_SPINCTRL, self.__on_spin, self.spinOffset) sizerButtons = wx.StdDialogButtonSizer() buttonOk = wx.Button(self, wx.ID_OK) buttonCancel = wx.Button(self, wx.ID_CANCEL) sizerButtons.AddButton(buttonOk) sizerButtons.AddButton(buttonCancel) sizerButtons.Realize() self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk) boxSizer1 = wx.BoxSizer(wx.HORIZONTAL) boxSizer1.Add(textFreq, border=5) boxSizer1.Add(self.spinFreq, border=5) boxSizer1.Add(textGain, border=5) boxSizer1.Add(self.spinGain, border=5) boxSizer2 = wx.BoxSizer(wx.HORIZONTAL) boxSizer2.Add(textOffset, border=5) boxSizer2.Add(self.spinOffset, border=5) gridSizer = wx.GridBagSizer(5, 5) gridSizer.Add(self.canvas, pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(textHelp, pos=(1, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(boxSizer1, pos=(2, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(refresh, pos=(3, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(boxSizer2, pos=(4, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL, border=5) gridSizer.Add(sizerButtons, pos=(5, 1), flag=wx.ALIGN_RIGHT | wx.ALL, border=5) self.SetSizerAndFit(gridSizer) self.__draw_limits() self.__setup_plot() def __setup_plot(self): self.axes.clear() self.band1 = None self.band2 = None self.axes.set_xlabel("Frequency (MHz)") self.axes.set_ylabel('Level ($\mathsf{dB/\sqrt{Hz}}$)') self.axes.set_yscale('log') self.axes.set_xlim(-1, 1) self.axes.set_ylim(auto=True) self.axes.grid(True) self.__draw_limits() def __plot(self, capture): self.__setup_plot() pos = WINFUNC[::2].index(self.winFunc) function = WINFUNC[1::2][pos] powers, freqs = matplotlib.mlab.psd(capture, NFFT=1024, Fs=SAMPLE_RATE / 1e6, window=function(1024)) plot = [] for x, y in itertools.izip(freqs, powers): plot.append((x, y)) plot.sort() x, y = numpy.transpose(plot) self.axes.plot(x, y, linewidth=0.4) self.canvas.draw() def __on_ok(self, _event): self.EndModal(wx.ID_OK) def __on_refresh(self, _event): dlg = wx.BusyInfo('Please wait...') try: if self.device.isDevice: sdr = rtlsdr.RtlSdr(self.device.indexRtl) else: sdr = RtlTcp(self.device.server, self.device.port, None) sdr.set_sample_rate(SAMPLE_RATE) sdr.set_center_freq(self.spinFreq.GetValue() * 1e6) sdr.set_gain(self.spinGain.GetValue()) capture = sdr.read_samples(2**21) sdr.close() except IOError as error: if self.device.isDevice: message = error.message else: message = error dlg.Destroy() dlg = wx.MessageDialog(self, 'Capture failed:\n{}'.format(message), 'Error', wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return self.__plot(capture) dlg.Destroy() def __on_spin(self, _event): self.offset = self.spinOffset.GetValue() * 1e3 self.__draw_limits() def __draw_limits(self): limit1 = self.offset limit2 = limit1 + BANDWIDTH / 2 limit1 /= 1e6 limit2 /= 1e6 if self.band1 is not None: self.band1.remove() if self.band2 is not None: self.band2.remove() self.band1 = self.axes.axvspan(limit1, limit2, color='g', alpha=0.25) self.band2 = self.axes.axvspan(-limit1, -limit2, color='g', alpha=0.25) self.canvas.draw() def get_offset(self): return self.offset / 1e3
class KMatrixFrame(util.GenericView): helpTitle = "Help" helpMessage = """Run K""" helpPage = os.environ["RTTOV_GUI_PREFIX"] + "/doc/helpKMatrixFrame.html" def __init__(self, parent, title, fname, runNumber=1): util.GenericView.__init__(self, parent, title) self.CreateMenuBar() self.runNumber = runNumber self.mykProfileView = None self.SetSize((900, 650)) self.SetPosition((10, 10)) self.sbgen = self.CreateStatusBar() self.sbgen.SetBackgroundColour('WHITE') txt = 'KMatrix file = %s' % fname self.sbgen.SetStatusText(txt) # timer affichage StatusBar self.txtsb = '' self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.refreshSB, self.timer) """ read kmat.h5 file """ self.fh5 = fname self.kmat = rttov.kmatrix.Kmatrix() self.kmat101 = rttov.kmatrix.Kmatrix() """ read profile in kmat.h5 """ self.baseProfile = rttov.profile.Profile() self.baseProfile = rmodel.project.OpenAProfile(self.fh5, 1) t0 = time.clock() frad = h5py.File(self.fh5, 'r') h5 = frad['/'] self.kmat.loadh5(h5) frad.close() t1 = time.clock() txt = 'lecture fichier %s : %d sec.' % (self.fh5, (t1 - t0)) self.sat = self.kmat.misc['SATELLITE'] self.ins = self.kmat.misc['INSTRUMENT'] self.lev = self.kmat.profile['NLEVELS'] self.tabP = self.kmat.profile['P'] # # growth the levels < 101 # # map the levels self.tabilevels = np.zeros(levx, int) for l in range(0, levx): self.tabilevels[l] = round(l * self.lev / levx) if self.lev < levx: tabNP = np.zeros(levx) for l in range(0, levx): tabNP[l] = self.tabP[self.tabilevels[l]] self.tabP = tabNP self.tabW = self.kmat.misc['WAVENUMBERS'] self.tabY = {} self.chn = self.kmat.kmatrix['T'].shape[1] """ gasplot : 0.0 not shown ? """ self.tcomm = {} self.tunit = {} self.tcbar = {} self.gasplot = [] for gas in ['T', 'Q'] + gaslist: if self.kmat.kmatrix[gas] is None: continue kmin = np.amin(self.kmat.kmatrix[gas]) kmax = np.amax(self.kmat.kmatrix[gas]) self.tcbar[gas] = 1 if kmin == 0.0 and kmax == 0.0: self.tcbar[gas] = 0 attr = '%s_ATTRIBUTE' % gas self.tcomm[gas] = self.kmat.kmatrix[attr]['COMMENT'] self.tunit[gas] = self.kmat.kmatrix[attr]['UNITS'] if not gas == 'T' and not gas == 'Q': self.gasplot.append(gas) # # init figure # self.fig = figPlot() self.cnv = FigureCanvas(self, -1, self.fig) self.cnv.mpl_connect('motion_notify_event', self.onMMotion) self.cnv.mpl_connect('key_press_event', self.onkeypress) # # subplot width # self.barwidth = max(1, int(wix / self.chn)) self.yMax = self.lev if self.chn >= chnx: self.xMax = self.chn else: self.xMax = self.barwidth * self.chn self.txtsb = '%s / %s' % (self.sat.replace( ' ', '').upper(), self.ins.upper()) # # choice gas in subplot 313 # self.glabel = {} self.gasID = {} self.tlb = MyCustomToolbar(self.cnv) if len(self.gasplot) > 1: for ig in self.gasplot: self.gasID[ig] = wx.NewId() self.glabel[self.gasID[ig]] = ig ico = os.environ["RTTOV_GUI_PREFIX"] + '/icons/%s.png' % ig self.tlb.AddSimpleTool(self.gasID[ig], _load_bitmap(ico), ig, '') wx.EVT_TOOL(self.tlb, self.gasID[ig], self.gaschoice) # # toolbar : custom buttons # self.LEFTLEFT_ID = wx.NewId() self.tlb.AddSimpleTool(self.LEFTLEFT_ID, _load_bitmap('hand.xpm'), 'One screen left', '') wx.EVT_TOOL(self.tlb, self.LEFTLEFT_ID, self.onleftleft) self.LEFT_ID = wx.NewId() self.tlb.AddSimpleTool(self.LEFT_ID, _load_bitmap('stock_left.xpm'), 'left', '') wx.EVT_TOOL(self.tlb, self.LEFT_ID, self.onleft) self.RIGHT_ID = wx.NewId() self.tlb.AddSimpleTool(self.RIGHT_ID, _load_bitmap('stock_right.xpm'), 'right', '') wx.EVT_TOOL(self.tlb, self.RIGHT_ID, self.onright) self.RIGHTRIGHT_ID = wx.NewId() self.tlb.AddSimpleTool(self.RIGHTRIGHT_ID, _load_bitmap('hand.xpm'), 'One screen right', '') wx.EVT_TOOL(self.tlb, self.RIGHTRIGHT_ID, self.onrightright) self.UP_ID = wx.NewId() self.tlb.AddSimpleTool(self.UP_ID, _load_bitmap('stock_up.xpm'), 'scroll up', '') wx.EVT_TOOL(self.tlb, self.UP_ID, self.onup) self.DOWN_ID = wx.NewId() self.tlb.AddSimpleTool(self.DOWN_ID, _load_bitmap('stock_down.xpm'), 'scroll down', '') wx.EVT_TOOL(self.tlb, self.DOWN_ID, self.ondown) # # add kscale icon : K / K% # self.scalek = 0 self.SCALE10K_ID = wx.NewId() self.tlb.AddSimpleTool( self.SCALE10K_ID, _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/k10.png'), 'scale Kx10%', '') wx.EVT_TOOL(self.tlb, self.SCALE10K_ID, self.onscale10k) self.RESETK_ID = wx.NewId() self.tlb.AddSimpleTool( self.RESETK_ID, _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/reset.png'), 'reset K', '') wx.EVT_TOOL(self.tlb, self.RESETK_ID, self.onresetk) # # add box : select channel # self.SELCHAN_ID = wx.NewId() self.tlb.AddSimpleTool( self.SELCHAN_ID, _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/kP.png'), 'select channnel', '') wx.EVT_TOOL(self.tlb, self.SELCHAN_ID, self.onselchan) self.tlb.Realize() # canvas and toolbar in sizer sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.tlb, 0, wx.GROW) sizer.Add(self.cnv, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(sizer) self.Fit() # self.kprof = None # self.subP = {} self.cax = {} # # subplots T and Q # self.subP['T'] = self.fig.add_subplot(3, 1, 1) self.tabY['T'] = self.extract_kgas('T') tt = '%s : %s' % ('T', self.tcomm['T']) self.subP['T'].set_title(tt) img = self.subP['T'].imshow(self.tabY['T'], origin='upper') self.subP['T'].set_ylabel('P levels') divider = make_axes_locatable(self.subP['T']) self.cax['T'] = divider.append_axes("right", size="1%", pad=0.05) self.fig.colorbar(img, cax=self.cax['T']) self.subP['T'].set_xlim([0, min(self.xMax, wix)]) self.draw_plot('T', 'T', self.kmat.kmatrix['%s_ATTRIBUTE' % 'T']['COMMENT']) self.subP['Q'] = self.fig.add_subplot(3, 1, 2, sharex=self.subP['T'], sharey=self.subP['T']) self.tabY['Q'] = self.extract_kgas('Q') tt = '%s : %s' % ('Q', self.tcomm['Q']) self.subP['Q'].set_title(tt) img = self.subP['Q'].imshow(self.tabY['Q'], origin='upper') self.subP['Q'].set_ylabel('P levels') divider = make_axes_locatable(self.subP['Q']) self.cax['Q'] = divider.append_axes("right", size="1%", pad=0.05) self.fig.colorbar(img, cax=self.cax['Q']) self.subP['Q'].set_xlim([0, min(self.xMax, wix)]) self.draw_plot('Q', 'Q', self.kmat.kmatrix['%s_ATTRIBUTE' % 'Q']['COMMENT']) # # subplot other gases if exist # if self.gasplot: for gas in self.gasplot: self.tabY[gas] = self.extract_kgas(gas) gas = self.gasplot[0] self.subP['G'] = self.fig.add_subplot(3, 1, 3, sharex=self.subP['T'], sharey=self.subP['T']) tt = '%s : %s' % (gas, self.tcomm[gas]) self.subP['G'].set_title(tt) img = self.subP['G'].imshow(self.tabY[gas], origin='upper') self.subP['G'].set_ylabel('P levels') divider = make_axes_locatable(self.subP['G']) self.cax['G'] = divider.append_axes("right", size="1%", pad=0.05) self.fig.colorbar(img, cax=self.cax['G']) self.subP['G'].set_xlim([0, min(self.xMax, wix)]) self.draw_plot('G', gas, self.kmat.kmatrix['%s_ATTRIBUTE' % gas]['COMMENT']) self.fig.tight_layout() self.fig.canvas.draw() def zoomp(self, evt): zp = int(self.szp.val) print "z :", zp axes = self.subP['T'] y1, y2 = axes.get_ylim() ym = (y1 - y2) / 2 print 'avant :', y1, y2, ym yy1 = ym + 50 / zp yy2 = ym - 50 / zp axes.set_ylim(yy1, yy2) print 'apres :', yy1, yy2 self.redraw_fig() def gaschoice(self, evt): gas = self.glabel[evt.GetId()] self.draw_plot('G', gas, self.tcomm[gas]) return def onkeypress(self, evt): if (evt.key == 'p' or evt.key == 'P') and evt.inaxes: if self.chn > chnx: c = int(round(evt.xdata)) + 1 else: c = int(round(evt.xdata) / self.barwidth) + 1 # print 'x=', evt.xdata ,' c=',c if c < 0 or c > self.chn: return txt = 'display profile channel : %d from %s' % (c, self.fh5) self.writeSB(txt, 'green', 5, 1) pchan = self.kmat.getchanprof(c - 1) self.mykProfileView = rview.kprofileframe.KProfileView( self, pchan, channel=c, baseProfile=self.baseProfile, runNumber=self.runNumber) def extract_kgas(self, gas): # levels : 101 niveaux qqsoit le profil tab101 = np.zeros((levx, self.chn)) for l in range(0, levx): tab101[l][:] = self.kmat.kmatrix[gas][self.tabilevels[l]][:] self.kmat101.kmatrix[gas] = tab101 if self.chn >= chnx: return self.kmat101.kmatrix[gas] else: tY = np.zeros(shape=((self.barwidth) * self.chn, levx)) kmin = np.amin(self.kmat101.kmatrix[gas]) kmax = np.amax(self.kmat101.kmatrix[gas]) kmoy = (kmax + kmin) / 2 pc = 0 for ic in range(0, self.chn): for ir in range(0, self.barwidth - 1): tY[pc] = np.transpose(self.kmat101.kmatrix[gas])[ic] pc += 1 # # separation bandes # tY[pc] = kmoy pc += 1 return np.transpose(tY) # pan the graph to the left def onleftleft(self, evt): if evt.GetId() == self.LEFTLEFT_ID: axes = self.cnv.figure.axes[0] x1, x2 = axes.get_xlim() shift = x2 - x1 if x1 - shift <= 0: axes.set_xlim(0, shift) else: axes.set_xlim(x1 - shift, x2 - shift) self.redraw_fig() def onleft(self, evt): if evt.GetId() == self.LEFT_ID: axes = self.cnv.figure.axes[0] x1, x2 = axes.get_xlim() shift = (x2 - x1) / 10 axes.set_xlim(x1 - shift, x2 - shift) self.redraw_fig() def onrightright(self, evt): if evt.GetId() == self.RIGHTRIGHT_ID: axes = self.cnv.figure.axes[0] x1, x2 = axes.get_xlim() shift = x2 - x1 if x2 + shift >= self.xMax: axes.set_xlim(self.xMax - shift, self.xMax) else: axes.set_xlim(x1 + shift, x2 + shift) self.redraw_fig() def onright(self, evt): if evt.GetId() == self.RIGHT_ID: axes = self.cnv.figure.axes[0] x1, x2 = axes.get_xlim() shift = (x2 - x1) / 10 axes.set_xlim(x1 + shift, x2 + shift) self.redraw_fig() def onup(self, evt): if evt.GetId() == self.UP_ID: axes = self.cnv.figure.axes[0] y1, y2 = axes.get_ylim() axes.set_ylim(y1 - 1, y2 - 1) self.redraw_fig() def ondown(self, evt): if evt.GetId() == self.DOWN_ID: axes = self.cnv.figure.axes[0] y1, y2 = axes.get_ylim() axes.set_ylim(y1 + 1, y2 + 1) self.redraw_fig() def redraw_y(self): axes = self.cnv.figure.axes[0] y1, y2 = axes.get_ylim() axes.set_ylim(y1, y2) # scale K-K% def onscale5k(self, evt): if evt.GetId() == self.SCALE5K_ID: self.scalexk(0.05) def onscale10k(self, evt): if evt.GetId() == self.SCALE10K_ID: self.scalexk(0.1) def onscale20k(self, evt): if evt.GetId() == self.SCALE20K_ID: self.scalexk(0.2) def scalexk(self, coeff): if self.scalek == 1: return self.scalek = 1 text = 'init kmatrix scale' self.writeSB(text, 'yellow', 5, 1) t1 = time.clock() print "Q :", self.tabY['Q'].shape self.kmat.kscale(coeff) t2 = time.clock() text1 = 'end k scale : %s seconds' % (t2 - t1) self.writeSB(text, 'green', 5, 1) # # update for all present gases # for ig in ['Q'] + self.gasplot: self.tabY[ig] = self.extract_kgas(ig) self.tcomm[ig] = '%s scaled by %3.2f input profile' % ( self.tcomm[ig], coeff) # # redraw subplots # for a in self.cnv.figure.axes: gas = a.get_title().split(' :')[0] if gas == 'T': continue elif gas: if gas == 'Q': plot = 'Q' else: plot = 'G' img = self.subP[plot].imshow(self.tabY[gas], origin='upper') self.fig.colorbar(img, cax=self.cax[plot]) tt = '%s : %s' % (gas, self.tcomm[gas]) self.subP[plot].set_title(tt) self.draw_plot(plot, gas, self.tcomm[gas]) self.redraw_fig() t3 = time.clock() text2 = ' / update graph % sec.' % (t3 - t2) self.writeSB(text1 + text2, 'green', 5, 1) def onresetk(self, evt): if self.scalek == 0: return self.scalek = 0 text = 'init kmatix reset' self.writeSB(text, 'yellow', 5, 1) t1 = time.clock() frad = h5py.File(self.fh5, 'r') h5 = frad['/'] self.kmat.loadh5(h5) frad.close() t2 = time.clock() text1 = 'end k reset : %s seconds' % (t2 - t1) # # update for all present gases # for ig in ['Q'] + self.gasplot: self.tabY[ig] = self.extract_kgas(ig) attr = '%s_ATTRIBUTE' % ig self.tcomm[ig] = self.kmat.kmatrix[attr]['COMMENT'] for a in self.cnv.figure.axes: gas = a.get_title().split(' :')[0] if gas == 'T': continue elif gas: if gas == 'Q': self.draw_plot('Q', 'Q', self.tcomm[gas]) else: self.draw_plot('G', gas, self.tcomm[gas]) self.redraw_fig() t3 = time.clock() text2 = ' / update graph % sec.' % (t3 - t2) self.writeSB(text1 + text2, 'green', 5, 1) def onselchan(self, evt): if evt.GetId() != self.SELCHAN_ID: return txtbox = 'Select a channel number [%01d..%d] : ' % (1, self.chn) chnbox = util.SimpleFSDialogBox(self, -1, "Select channel", text=txtbox, text2="Channel", minval=1, maxval=self.chn, increment=1) chnbox.CenterOnParent() if (chnbox.ShowModal() == wx.ID_OK): c = chnbox.GetSelections() txt = 'display profile channel : %d from %s' % (c, self.fh5) self.writeSB(txt, 'green', 5, 1) pchan = self.kmat.getchanprof(c - 1) self.mykProfileView = rview.kprofileframe.KProfileView( self, pchan, channel=c, baseProfile=self.baseProfile, runNumber=self.runNumber) chnbox.Destroy() def draw_plot(self, plot, gas, comment): tt = '%s : %s' % (gas, comment) self.subP[plot].set_title(tt) img = self.subP[plot].imshow(self.tabY[gas], origin='upper') if self.tcbar[gas]: self.fig.colorbar(img, cax=self.cax[plot]) # x ticks = channel number if self.chn <= chnx: if self.chn <= 10: xtl = [] xtp = [] if gas == "T": for i in range(0, self.chn + 1): xtl.append(i + 1) xtp.append((xtl[i] - 1) * self.barwidth + int(self.barwidth) / 2) self.subP[gas].set_xticks(xtp) self.subP[gas].set_xticklabels(xtl) else: xtl = [] xtp = [] if gas == "T": for i in range(0, (self.chn + 1) / 2): xtl.append(2 * i + 1) xtp.append( int(self.barwidth / 2) + (xtl[i] - 1) * self.barwidth) self.subP[gas].set_xticks(xtp) self.subP[gas].set_xticklabels( xtl, horizontalalignment='center') else: xa = self.subP[plot].get_xaxis() xa.set_major_locator(MaxNLocator(nbins=10, integer=True)) self.redraw_fig() def redraw_fig(self): # # for each axes compute and set yticklables # taxes = self.fig.get_axes() for ax in range(0, len(taxes)): if taxes[ax].get_title(): ylabs = np.zeros(len(taxes[ax].get_yticks()), int) for yl in range(0, len(taxes[ax].get_yticks())): ylabs[yl] = (int( round(taxes[ax].get_yticks()[yl] * self.lev / levx))) taxes[ax].set_yticklabels(ylabs) self.fig.tight_layout() self.fig.canvas.draw_idle() return def MenuData(self): return ( ( "&File", # File Menu ('&Quit', 'Quit', self.OnQuit, "quit", True)), ( "&Help", # Help Menu ("About", "About screen", self.OnAbout, "about", True), ("&Help", "Help", self.OnHelpHTML, "help", True))) def onMMotion(self, evt): if evt.inaxes: gas = evt.inaxes.title.get_text().split(' :')[0] if self.chn > chnx: c = int(round(evt.xdata)) + 1 else: c = int(round(evt.xdata) / self.barwidth) + 1 # print 'x=', evt.xdata ,' c=',c, 'xmax=', self.xMax if c < 0 or c > self.xMax: return y = int(evt.ydata) # separation canaux if (c > 1 and self.barwidth > 1 and round(evt.xdata) % self.barwidth == 0.0): self.writeSB('channel separator', 'grey', 5, 0) return # # pression, canal, k # try: tabwc = self.tabW[c - 1] except: tabwc = self.tabW try: k = self.tabY[gas][y][int(round(evt.xdata))] if tabwc >= wnx: txt0 = ' %s=%.3f %sm]' % (u'\u03BB', (10000 / tabwc), u'\u03BC') else: txt0 = ' %s=%.4f GHz]' % (u'\u03BD', (spl * tabwc / 1000000000)) mylevel = self.tabilevels[y] + 1 text = "%s : C=#%d P(%d)=%.3f hPa k=%g %s [wn=%.3f cm-1" % ( gas, c, mylevel, self.tabP[y], k, self.tunit[gas], tabwc) + txt0 # # ecriture message dans status bar # self.writeSB(text, 'grey', 15, 0) except: return
def __init__(self, parent, title, fname, runNumber=1): util.GenericView.__init__(self, parent, title) self.CreateMenuBar() self.runNumber = runNumber self.mykProfileView = None self.SetSize((900, 650)) self.SetPosition((10, 10)) self.sbgen = self.CreateStatusBar() self.sbgen.SetBackgroundColour('WHITE') txt = 'KMatrix file = %s' % fname self.sbgen.SetStatusText(txt) # timer affichage StatusBar self.txtsb = '' self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.refreshSB, self.timer) """ read kmat.h5 file """ self.fh5 = fname self.kmat = rttov.kmatrix.Kmatrix() self.kmat101 = rttov.kmatrix.Kmatrix() """ read profile in kmat.h5 """ self.baseProfile = rttov.profile.Profile() self.baseProfile = rmodel.project.OpenAProfile(self.fh5, 1) t0 = time.clock() frad = h5py.File(self.fh5, 'r') h5 = frad['/'] self.kmat.loadh5(h5) frad.close() t1 = time.clock() txt = 'lecture fichier %s : %d sec.' % (self.fh5, (t1 - t0)) self.sat = self.kmat.misc['SATELLITE'] self.ins = self.kmat.misc['INSTRUMENT'] self.lev = self.kmat.profile['NLEVELS'] self.tabP = self.kmat.profile['P'] # # growth the levels < 101 # # map the levels self.tabilevels = np.zeros(levx, int) for l in range(0, levx): self.tabilevels[l] = round(l * self.lev / levx) if self.lev < levx: tabNP = np.zeros(levx) for l in range(0, levx): tabNP[l] = self.tabP[self.tabilevels[l]] self.tabP = tabNP self.tabW = self.kmat.misc['WAVENUMBERS'] self.tabY = {} self.chn = self.kmat.kmatrix['T'].shape[1] """ gasplot : 0.0 not shown ? """ self.tcomm = {} self.tunit = {} self.tcbar = {} self.gasplot = [] for gas in ['T', 'Q'] + gaslist: if self.kmat.kmatrix[gas] is None: continue kmin = np.amin(self.kmat.kmatrix[gas]) kmax = np.amax(self.kmat.kmatrix[gas]) self.tcbar[gas] = 1 if kmin == 0.0 and kmax == 0.0: self.tcbar[gas] = 0 attr = '%s_ATTRIBUTE' % gas self.tcomm[gas] = self.kmat.kmatrix[attr]['COMMENT'] self.tunit[gas] = self.kmat.kmatrix[attr]['UNITS'] if not gas == 'T' and not gas == 'Q': self.gasplot.append(gas) # # init figure # self.fig = figPlot() self.cnv = FigureCanvas(self, -1, self.fig) self.cnv.mpl_connect('motion_notify_event', self.onMMotion) self.cnv.mpl_connect('key_press_event', self.onkeypress) # # subplot width # self.barwidth = max(1, int(wix / self.chn)) self.yMax = self.lev if self.chn >= chnx: self.xMax = self.chn else: self.xMax = self.barwidth * self.chn self.txtsb = '%s / %s' % (self.sat.replace( ' ', '').upper(), self.ins.upper()) # # choice gas in subplot 313 # self.glabel = {} self.gasID = {} self.tlb = MyCustomToolbar(self.cnv) if len(self.gasplot) > 1: for ig in self.gasplot: self.gasID[ig] = wx.NewId() self.glabel[self.gasID[ig]] = ig ico = os.environ["RTTOV_GUI_PREFIX"] + '/icons/%s.png' % ig self.tlb.AddSimpleTool(self.gasID[ig], _load_bitmap(ico), ig, '') wx.EVT_TOOL(self.tlb, self.gasID[ig], self.gaschoice) # # toolbar : custom buttons # self.LEFTLEFT_ID = wx.NewId() self.tlb.AddSimpleTool(self.LEFTLEFT_ID, _load_bitmap('hand.xpm'), 'One screen left', '') wx.EVT_TOOL(self.tlb, self.LEFTLEFT_ID, self.onleftleft) self.LEFT_ID = wx.NewId() self.tlb.AddSimpleTool(self.LEFT_ID, _load_bitmap('stock_left.xpm'), 'left', '') wx.EVT_TOOL(self.tlb, self.LEFT_ID, self.onleft) self.RIGHT_ID = wx.NewId() self.tlb.AddSimpleTool(self.RIGHT_ID, _load_bitmap('stock_right.xpm'), 'right', '') wx.EVT_TOOL(self.tlb, self.RIGHT_ID, self.onright) self.RIGHTRIGHT_ID = wx.NewId() self.tlb.AddSimpleTool(self.RIGHTRIGHT_ID, _load_bitmap('hand.xpm'), 'One screen right', '') wx.EVT_TOOL(self.tlb, self.RIGHTRIGHT_ID, self.onrightright) self.UP_ID = wx.NewId() self.tlb.AddSimpleTool(self.UP_ID, _load_bitmap('stock_up.xpm'), 'scroll up', '') wx.EVT_TOOL(self.tlb, self.UP_ID, self.onup) self.DOWN_ID = wx.NewId() self.tlb.AddSimpleTool(self.DOWN_ID, _load_bitmap('stock_down.xpm'), 'scroll down', '') wx.EVT_TOOL(self.tlb, self.DOWN_ID, self.ondown) # # add kscale icon : K / K% # self.scalek = 0 self.SCALE10K_ID = wx.NewId() self.tlb.AddSimpleTool( self.SCALE10K_ID, _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/k10.png'), 'scale Kx10%', '') wx.EVT_TOOL(self.tlb, self.SCALE10K_ID, self.onscale10k) self.RESETK_ID = wx.NewId() self.tlb.AddSimpleTool( self.RESETK_ID, _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/reset.png'), 'reset K', '') wx.EVT_TOOL(self.tlb, self.RESETK_ID, self.onresetk) # # add box : select channel # self.SELCHAN_ID = wx.NewId() self.tlb.AddSimpleTool( self.SELCHAN_ID, _load_bitmap(os.environ["RTTOV_GUI_PREFIX"] + '/icons/kP.png'), 'select channnel', '') wx.EVT_TOOL(self.tlb, self.SELCHAN_ID, self.onselchan) self.tlb.Realize() # canvas and toolbar in sizer sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.tlb, 0, wx.GROW) sizer.Add(self.cnv, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(sizer) self.Fit() # self.kprof = None # self.subP = {} self.cax = {} # # subplots T and Q # self.subP['T'] = self.fig.add_subplot(3, 1, 1) self.tabY['T'] = self.extract_kgas('T') tt = '%s : %s' % ('T', self.tcomm['T']) self.subP['T'].set_title(tt) img = self.subP['T'].imshow(self.tabY['T'], origin='upper') self.subP['T'].set_ylabel('P levels') divider = make_axes_locatable(self.subP['T']) self.cax['T'] = divider.append_axes("right", size="1%", pad=0.05) self.fig.colorbar(img, cax=self.cax['T']) self.subP['T'].set_xlim([0, min(self.xMax, wix)]) self.draw_plot('T', 'T', self.kmat.kmatrix['%s_ATTRIBUTE' % 'T']['COMMENT']) self.subP['Q'] = self.fig.add_subplot(3, 1, 2, sharex=self.subP['T'], sharey=self.subP['T']) self.tabY['Q'] = self.extract_kgas('Q') tt = '%s : %s' % ('Q', self.tcomm['Q']) self.subP['Q'].set_title(tt) img = self.subP['Q'].imshow(self.tabY['Q'], origin='upper') self.subP['Q'].set_ylabel('P levels') divider = make_axes_locatable(self.subP['Q']) self.cax['Q'] = divider.append_axes("right", size="1%", pad=0.05) self.fig.colorbar(img, cax=self.cax['Q']) self.subP['Q'].set_xlim([0, min(self.xMax, wix)]) self.draw_plot('Q', 'Q', self.kmat.kmatrix['%s_ATTRIBUTE' % 'Q']['COMMENT']) # # subplot other gases if exist # if self.gasplot: for gas in self.gasplot: self.tabY[gas] = self.extract_kgas(gas) gas = self.gasplot[0] self.subP['G'] = self.fig.add_subplot(3, 1, 3, sharex=self.subP['T'], sharey=self.subP['T']) tt = '%s : %s' % (gas, self.tcomm[gas]) self.subP['G'].set_title(tt) img = self.subP['G'].imshow(self.tabY[gas], origin='upper') self.subP['G'].set_ylabel('P levels') divider = make_axes_locatable(self.subP['G']) self.cax['G'] = divider.append_axes("right", size="1%", pad=0.05) self.fig.colorbar(img, cax=self.cax['G']) self.subP['G'].set_xlim([0, min(self.xMax, wix)]) self.draw_plot('G', gas, self.kmat.kmatrix['%s_ATTRIBUTE' % gas]['COMMENT']) self.fig.tight_layout() self.fig.canvas.draw()
def __init__(self,frame,id): wx.Panel.__init__(self,frame,id,style = wx.BORDER_RAISED) z_layer = 0 self.omf = frame.omf self.halfstep = (float(self.omf.parameters['zstepsize'])/2.0)*1.0e10 self.figure = Figure(frameon = True) self.figure.set_facecolor('.82') self.canvas = FigureCanvas(self, -1, self.figure) fm = FigureManagerBase(self.canvas, 0) _pylab_helpers.Gcf.set_active(fm) self.wheel_cmap = LinearSegmentedColormap.from_list('wheel_rgby', ['red', 'green', 'blue', 'yellow', 'red']) mpl_toolbar = Toolbar(self.canvas) mpl_toolbar.Realize() x,y = indices((100,100), dtype = float) - 50. wheel_angle = arctan2(x,y) self.ax1 = self.figure.add_axes([0.1,0.1,0.7,0.8]) self.angle = ma.array(arctan2(-self.omf.my[:,:,z_layer], self.omf.mx[:,:,z_layer]), mask=(self.omf.M[:,:,z_layer] == 0.0)) self.angle[self.angle==360] = 0.0 print ma.getdata(self.angle) xmax = (float(self.omf.parameters['xnodes']) * float(self.omf.parameters['xstepsize']) * 1.0e10) ymax = (float(self.omf.parameters['ynodes']) * float(self.omf.parameters['ystepsize']) * 1.0e10) self.extent = [0., xmax, 0., ymax] self.im = self.ax1.imshow(self.angle.T, origin='lower', interpolation = 'nearest', extent = self.extent, cmap = self.wheel_cmap, vmin = -pi, vmax = pi) self.ax1.set_title('Z Slice = ' + str(z_layer*float(self.omf.parameters['zstepsize'])* 1.0e10 + self.halfstep) +' Ang' ,size = 'xx-large') self.ax1.set_xlabel('$x (\AA)$', size = 'x-large') self.ax1.set_ylabel('$y (\AA)$', size = 'x-large') self.ax1w = self.figure.add_axes([0.75,0.4,0.3,0.2], polar=True) self.ax1w.yaxis.set_visible(False) self.ax1w.imshow(wheel_angle, cmap=self.wheel_cmap, extent=[0,2*pi,0,pi]) self.ax1w.set_title('M direction\n(in-plane)') self.zselect = wx.Slider(self,-1,size = [300,40],minValue = int(0), maxValue = int(self.omf.dims[2]-1), style = wx.SL_AUTOTICKS) self.datavalue = wx.StatusBar(self,-1) self.datavalue.SetStatusText('Angle Value: ') self.label = wx.StaticText(self,-1,'Select Z layer: ') self.minVal = wx.StaticText(self,-1, '0.0') self.maxVal = wx.StaticText(self,-1, str(self.omf.dims[2]* (float(self.omf.parameters['zstepsize'])* 1.0e10) -self.halfstep)) #Sizer Creation toolSize = wx.BoxSizer(wx.HORIZONTAL) BotSize = wx.BoxSizer(wx.HORIZONTAL) vertSize = wx.BoxSizer(wx.VERTICAL) BotSize.Add(self.label,0,wx.LEFT|wx.RIGHT,border = 5) BotSize.Add(self.minVal,0,wx.LEFT|wx.RIGHT,border = 5) BotSize.Add(self.zselect,0,wx.TOP|wx.LEFT|wx.RIGHT,border = 5) BotSize.Add(self.maxVal,0,wx.LEFT|wx.RIGHT,border = 5) toolSize.Add(mpl_toolbar,0,wx.RIGHT,border = 20) toolSize.Add(self.datavalue,0,wx.LEFT|wx.RIGHT|wx.TOP,border = 20) vertSize.Add(self.canvas,-1,wx.EXPAND|wx.LEFT|wx.RIGHT,border = 5) vertSize.Add(toolSize,0) vertSize.Add(BotSize,0,wx.ALL, border = 10) self.SetSizer(vertSize) self.Fit() self.zselect.Bind(wx.EVT_SCROLL,self.newMomentZ) self.canvas.mpl_connect('motion_notify_event',self.onMouseOver)
class wavCanvasPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) dpi = 60 width = PLOT_PANEL_WIDTH / dpi height = PLOT_PANEL_HEIGHT / dpi self.wavFigure = Figure(figsize=[width, height], dpi=dpi, facecolor='#404040') self.wavCanvas = FigureCanvas(self, -1, self.wavFigure) self.wavSizer = wx.BoxSizer(wx.VERTICAL) self.wavSizer.Add(self.wavCanvas, 1, wx.EXPAND | wx.ALL) self.SetSizerAndFit(self.wavSizer) self.wavAxes = [None] * MAX_AUDIO_CHANNEL self.wavCursor = [None] * MAX_AUDIO_CHANNEL def fromstring(self, wavData, alignedByte): if alignedByte <= 8: src = numpy.ndarray(len(wavData), numpy.dtype('>i1'), wavData) dest = numpy.zeros(len(wavData) / alignedByte, numpy.dtype('>i8')) for i in range(alignedByte): dest.view(dtype='>i1')[alignedByte - 1 - i::8] = src.view( dtype='>i1')[i::alignedByte] [hex(x) for x in dest] return True, dest else: return False, wavData def readWave(self, wavPath, wavInfo): if os.path.isfile(wavPath): # Open the wav file to get wave data and parameters wavFile = wave.open(wavPath, "rb") wavParams = wavFile.getparams() wavChannels = wavParams[0] wavSampwidth = wavParams[1] wavFramerate = wavParams[2] wavFrames = wavParams[3] wavInfo.SetStatusText('Opened Audio Info = ' + 'Channels:' + str(wavChannels) + ', SampWidth:' + str(wavSampwidth) + 'Byte' + ', SampRate:' + str(wavFramerate) + 'kHz' + ', FormatTag:' + wavParams[4]) wavData = wavFile.readframes(wavFrames) wavFile.close() # Transpose the wav data if wave has multiple channels if wavSampwidth == 1: dtype = numpy.int8 elif wavSampwidth == 2: dtype = numpy.int16 elif wavSampwidth == 3: dtype = None elif wavSampwidth == 4: dtype = numpy.float32 else: return 0, 0, 0 if dtype != None: retData = numpy.fromstring(wavData, dtype=dtype) else: # Implement int24 manually status, retData = self.fromstring(wavData, 3) if not status: return 0, 0, 0 if wavChannels != 1: retData.shape = -1, wavChannels retData = retData.T # Calculate and arange wave time retTime = numpy.arange(0, wavFrames) * (1.0 / wavFramerate) retChannels = wavChannels return retChannels, retData, retTime else: return 0, 0, 0 def showWave(self, wavPath, wavDomain, wavInfo): self.wavFigure.clear() waveChannels, waveData, waveTime = self.readWave(wavPath, wavInfo) if waveChannels != 0: # Note: only show max supported channel if actual channel > max supported channel if waveChannels > MAX_AUDIO_CHANNEL: waveChannels = MAX_AUDIO_CHANNEL # Polt the waveform of each channel in sequence for i in range(waveChannels): left = PLOT_AXES_HEIGHT_LABEL bottom = (1.0 / waveChannels) * (waveChannels - 1 - i) + PLOT_AXES_HEIGHT_LABEL height = 1.0 / waveChannels - (PLOT_AXES_WIDTH_TITLE + PLOT_AXES_HEIGHT_LABEL) width = 1 - left - 0.05 self.wavAxes[i] = self.wavFigure.add_axes( [left, bottom, width, height], facecolor='k') if waveChannels == 1: waveAmplitude = waveData else: waveAmplitude = waveData[i] if wavDomain == 'Time': self.wavAxes[i].set_prop_cycle(color='#00F279', lw=[1]) self.wavAxes[i].set_xlabel('time (s)', color='w') self.wavAxes[i].plot(waveTime, waveAmplitude) self.wavCursor[i] = wavCursor(self.wavAxes[i], waveTime, waveAmplitude) elif wavDomain == 'Frequency': self.wavAxes[i].set_prop_cycle(color='red', lw=[1]) self.wavAxes[i].set_xlabel('Frequency (Hz)', color='w') waveMagnitude = numpy.absolute( numpy.fft.rfft(waveAmplitude)) waveFreq = numpy.fft.rfftfreq(len(waveTime), numpy.diff(waveTime)[0]) self.wavAxes[i].plot(waveFreq, waveMagnitude) self.wavCursor[i] = wavCursor(self.wavAxes[i], waveFreq, waveMagnitude) self.wavAxes[i].set_ylabel('value', color='w') self.wavAxes[i].grid() self.wavAxes[i].tick_params(labelcolor='w') self.wavAxes[i].set_title('Audio Channel ' + str(i), color='w') self.wavCanvas.mpl_connect('motion_notify_event', self.wavCursor[i].moveMouse) # Note!!!: draw() must be called if figure has been cleared once self.wavCanvas.draw() def showWelcome(self): self.wavFigure.clear() # Get Code from below link # https://matplotlib.org/gallery/images_contours_and_fields/tripcolor_demo.html#sphx-glr-gallery-images-contours-and-fields-tripcolor-demo-py n_angles = 36 n_radii = 8 min_radius = 0.25 radii = numpy.linspace(min_radius, 0.95, n_radii) angles = numpy.linspace(0, 2 * numpy.pi, n_angles, endpoint=False) angles = numpy.repeat(angles[..., numpy.newaxis], n_radii, axis=1) angles[:, 1::2] += numpy.pi / n_angles x = (radii * numpy.cos(angles)).flatten() y = (radii * numpy.sin(angles)).flatten() z = (numpy.cos(radii) * numpy.cos(3 * angles)).flatten() triang = Tri.Triangulation(x, y) triang.set_mask( numpy.hypot(x[triang.triangles].mean( axis=1), y[triang.triangles].mean(axis=1)) < min_radius) welcomeAxes = self.wavFigure.add_axes([0.13, 0.2, 0.7, 0.7], facecolor='#404040') #welcomeAxes.set_aspect('equal') welcomeAxes.tripcolor(triang, z, shading='flat') # Set some properties welcomeAxes.set_title('Welcome to use Jays-PySPEECH', color='w') welcomeAxes.set_xticks([]) welcomeAxes.set_yticks([]) welcomeAxes.spines['top'].set_visible(False) welcomeAxes.spines['right'].set_visible(False) welcomeAxes.spines['bottom'].set_visible(False) welcomeAxes.spines['left'].set_visible(False) self.wavCanvas.draw()
class PlotFigure(wx.Frame): """Matplotlib wxFrame with animation effect""" def __init__(self): # initialize the super class wx.Frame.__init__(self, None, wx.ID_ANY, title="CPU Usage Monitor", size=(600, 400)) # Matplotlib Figure self.fig = Figure((6, 4), 100) # bind the Figure to the backend specific canvas self.canvas = FigureCanvas(self, wx.ID_ANY, self.fig) # add a subplot self.ax = self.fig.add_subplot(111) # limit the X and Y axes dimensions # we prefer 2 separate functions for clarity self.ax.set_ylim([0, 100]) self.ax.set_xlim([0, POINTS]) # but we want a "frozen" window (defined by y/xlim functions) self.ax.set_autoscale_on(False) # we do not want ticks on X axis self.ax.set_xticks([]) # we want a tick every 10 point on Y (101 is to have 100 too) self.ax.set_yticks(range(0, 101, 10)) # disable autoscale, since we don't want the Axes to adapt # draw a grid (it will be only for Y) self.ax.grid(True) # generates first "empty" plots self.user = [None] * POINTS self.nice = [None] * POINTS self.sys = [None] * POINTS self.idle = [None] * POINTS self.l_user, = self.ax.plot(range(POINTS), self.user, label='User%') self.l_nice, = self.ax.plot(range(POINTS), self.nice, label='Nice%') self.l_sys, = self.ax.plot(range(POINTS), self.sys, label='Sys%') self.l_idle, = self.ax.plot(range(POINTS), self.idle, label='Idle%') # add the legend self.ax.legend(loc='upper center', ncol=4, prop=font_manager.FontProperties(size=10)) # force a draw on the canvas() # trick to show the grid and the legend self.canvas.draw() # save the clean background - everything but the line # is drawn and saved in the pixel buffer background self.bg = self.canvas.copy_from_bbox(self.ax.bbox) # take a snapshot of CPU usage, needed for the update algorithm self.before = self.prepare_cpu_usage() # bind events coming from timer with id = TIMER_ID # to the onTimer callback function wx.EVT_TIMER(self, TIMER_ID, self.onTimer) def prepare_cpu_usage(self): """helper function to return CPU usage info""" # get the CPU times using psutil module t = p.cpu_times() # return only the values we're interested in if hasattr(t, 'nice'): return [t.user, t.nice, t.system, t.idle] else: # special case for Windows, without 'nice' value return [t.user, 0, t.system, t.idle] def get_cpu_usage(self): """Compute CPU usage comparing previous and currentmeasurements""" # take the current CPU usage information now = self.prepare_cpu_usage() # compute deltas between current and previous measurements delta = [now[i] - self.before[i] for i in range(len(now))] # compute the total (needed for percentages calculation) total = sum(delta) # save the current measurement to before object self.before = now # return the percentage of CPU usage for our 4 categories return [(100.0 * dt) / total for dt in delta] def onTimer(self, evt): """callback function for timer events""" # get the CPU usage information tmp = self.get_cpu_usage() # restore the clean background, saved at the beginning self.canvas.restore_region(self.bg) # update the data self.user = self.user[1:] + [tmp[0]] self.nice = self.nice[1:] + [tmp[1]] self.sys = self.sys[1:] + [tmp[2]] self.idle = self.idle[1:] + [tmp[3]] # update the plot self.l_user.set_ydata(self.user) self.l_nice.set_ydata(self.nice) self.l_sys.set_ydata(self.sys) self.l_idle.set_ydata(self.idle) # just draw the "animated" objects self.ax.draw_artist(self.l_user) self.ax.draw_artist(self.l_nice) self.ax.draw_artist(self.l_sys) self.ax.draw_artist(self.l_idle) # "blit" the background with the animated lines self.canvas.blit(self.ax.bbox)
class ScatterPlotWidget(wx.Panel, ManageBusyCursorMixin): def __init__(self, parent, scatt_id, scatt_mgr, transpose, id=wx.ID_ANY): #TODO should not be transpose and scatt_id but x, y wx.Panel.__init__(self, parent, id) # bacause of aui (if floatable it can not take cursor from parent) ManageBusyCursorMixin.__init__(self, window=self) self.parent = parent self.full_extend = None self.mode = None self._createWidgets() self._doLayout() self.scatt_id = scatt_id self.scatt_mgr = scatt_mgr self.cidpress = None self.cidrelease = None self.rend_dt = {} self.transpose = transpose self.inverse = False self.SetSize((200, 100)) self.Layout() self.base_scale = 1.2 self.Bind(wx.EVT_CLOSE, lambda event: self.CleanUp()) self.plotClosed = Signal("ScatterPlotWidget.plotClosed") self.cursorMove = Signal("ScatterPlotWidget.cursorMove") self.contex_menu = ScatterPlotContextMenu(plot=self) self.ciddscroll = None self.canvas.mpl_connect('motion_notify_event', self.Motion) self.canvas.mpl_connect('button_press_event', self.OnPress) self.canvas.mpl_connect('button_release_event', self.OnRelease) self.canvas.mpl_connect('draw_event', self.DrawCallback) self.canvas.mpl_connect('figure_leave_event', self.OnCanvasLeave) def DrawCallback(self, event): self.polygon_drawer.DrawCallback(event) self.axes.draw_artist(self.zoom_rect) def _createWidgets(self): # Create the mpl Figure and FigCanvas objects. # 5x4 inches, 100 dots-per-inch # self.dpi = 100 self.fig = Figure((1.0, 1.0), dpi=self.dpi) self.fig.autolayout = True self.canvas = FigCanvas(self, -1, self.fig) self.axes = self.fig.add_axes([0.0, 0.0, 1, 1]) pol = Polygon(list(zip([0], [0])), animated=True) self.axes.add_patch(pol) self.polygon_drawer = PolygonDrawer(self.axes, pol=pol, empty_pol=True) self.zoom_wheel_coords = None self.zoom_rect_coords = None self.zoom_rect = Polygon(list(zip([0], [0])), facecolor='none') self.zoom_rect.set_visible(False) self.axes.add_patch(self.zoom_rect) def ZoomToExtend(self): if self.full_extend: self.axes.axis(self.full_extend) self.canvas.draw() def SetMode(self, mode): self._deactivateMode() if mode == 'zoom': self.ciddscroll = self.canvas.mpl_connect('scroll_event', self.ZoomWheel) self.mode = 'zoom' elif mode == 'zoom_extend': self.mode = 'zoom_extend' elif mode == 'pan': self.mode = 'pan' elif mode: self.polygon_drawer.SetMode(mode) def SetSelectionPolygonMode(self, activate): self.polygon_drawer.SetSelectionPolygonMode(activate) def _deactivateMode(self): self.mode = None self.polygon_drawer.SetMode(None) if self.ciddscroll: self.canvas.mpl_disconnect(self.ciddscroll) self.zoom_rect.set_visible(False) self._stopCategoryEdit() def GetCoords(self): coords = self.polygon_drawer.GetCoords() if coords is None: return if self.transpose: for c in coords: tmp = c[0] c[0] = c[1] c[1] = tmp return coords def SetEmpty(self): return self.polygon_drawer.SetEmpty() def OnRelease(self, event): if not self.mode == "zoom": return self.zoom_rect.set_visible(False) self.ZoomRectangle(event) self.canvas.draw() def OnPress(self, event): 'on button press we will see if the mouse is over us and store some data' if not event.inaxes: return if self.mode == "zoom_extend": self.ZoomToExtend() if event.xdata and event.ydata: self.zoom_wheel_coords = {'x': event.xdata, 'y': event.ydata} self.zoom_rect_coords = {'x': event.xdata, 'y': event.ydata} else: self.zoom_wheel_coords = None self.zoom_rect_coords = None def _stopCategoryEdit(self): 'disconnect all the stored connection ids' if self.cidpress: self.canvas.mpl_disconnect(self.cidpress) if self.cidrelease: self.canvas.mpl_disconnect(self.cidrelease) #self.canvas.mpl_disconnect(self.cidmotion) def _doLayout(self): self.main_sizer = wx.BoxSizer(wx.VERTICAL) self.main_sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.main_sizer) self.main_sizer.Fit(self) def Plot(self, cats_order, scatts, ellipses, styles): """Redraws the figure """ callafter_list = [] if self.full_extend: cx = self.axes.get_xlim() cy = self.axes.get_ylim() c = cx + cy else: c = None q = Queue() _rendDtMemmapsToFiles(self.rend_dt) p = Process(target=MergeImg, args=(cats_order, scatts, styles, self.rend_dt, q)) p.start() merged_img, self.full_extend, self.rend_dt = q.get() p.join() _rendDtFilesToMemmaps(self.rend_dt) merged_img = np.memmap(filename=merged_img['dt'], shape=merged_img['sh']) #merged_img, self.full_extend = MergeImg(cats_order, scatts, styles, None) self.axes.clear() self.axes.axis('equal') if self.transpose: merged_img = np.transpose(merged_img, (1, 0, 2)) img = imshow(self.axes, merged_img, extent=[int(ceil(x)) for x in self.full_extend], origin='lower', interpolation='nearest', aspect="equal") callafter_list.append([self.axes.draw_artist, [img]]) callafter_list.append([grass.try_remove, [merged_img.filename]]) for cat_id in cats_order: if cat_id == 0: continue if not ellipses.has_key(cat_id): continue e = ellipses[cat_id] if not e: continue colors = styles[cat_id]['color'].split(":") if self.transpose: e['theta'] = 360 - e['theta'] + 90 if e['theta'] >= 360: e['theta'] = abs(360 - e['theta']) e['pos'] = [e['pos'][1], e['pos'][0]] ellip = Ellipse(xy=e['pos'], width=e['width'], height=e['height'], angle=e['theta'], edgecolor="w", linewidth=1.5, facecolor='None') self.axes.add_artist(ellip) callafter_list.append([self.axes.draw_artist, [ellip]]) color = map(lambda v: int(v) / 255.0, styles[cat_id]['color'].split(":")) ellip = Ellipse(xy=e['pos'], width=e['width'], height=e['height'], angle=e['theta'], edgecolor=color, linewidth=1, facecolor='None') self.axes.add_artist(ellip) callafter_list.append([self.axes.draw_artist, [ellip]]) center = Line2D( [e['pos'][0]], [e['pos'][1]], marker='x', markeredgecolor='w', #markerfacecolor=color, markersize=2) self.axes.add_artist(center) callafter_list.append([self.axes.draw_artist, [center]]) callafter_list.append([self.fig.canvas.blit, []]) if c: self.axes.axis(c) wx.CallAfter(lambda: self.CallAfter(callafter_list)) def CallAfter(self, funcs_list): while funcs_list: fcn, args = funcs_list.pop(0) fcn(*args) self.canvas.draw() def CleanUp(self): self.plotClosed.emit(scatt_id=self.scatt_id) self.Destroy() def ZoomWheel(self, event): # get the current x and y limits if not event.inaxes: return # tcaswell # http://stackoverflow.com/questions/11551049/matplotlib-plot-zooming-with-scroll-wheel cur_xlim = self.axes.get_xlim() cur_ylim = self.axes.get_ylim() xdata = event.xdata ydata = event.ydata if event.button == 'up': scale_factor = 1 / self.base_scale elif event.button == 'down': scale_factor = self.base_scale else: scale_factor = 1 extend = (xdata - (xdata - cur_xlim[0]) * scale_factor, xdata + (cur_xlim[1] - xdata) * scale_factor, ydata - (ydata - cur_ylim[0]) * scale_factor, ydata + (cur_ylim[1] - ydata) * scale_factor) self.axes.axis(extend) self.canvas.draw() def ZoomRectangle(self, event): # get the current x and y limits if not self.mode == "zoom": return if event.inaxes is None: return if event.button != 1: return cur_xlim = self.axes.get_xlim() cur_ylim = self.axes.get_ylim() x1, y1 = event.xdata, event.ydata x2 = deepcopy(self.zoom_rect_coords['x']) y2 = deepcopy(self.zoom_rect_coords['y']) if x1 == x2 or y1 == y2: return if x1 > x2: tmp = x1 x1 = x2 x2 = tmp if y1 > y2: tmp = y1 y1 = y2 y2 = tmp self.axes.axis((x1, x2, y1, y2)) #self.axes.set_xlim(x1, x2)#, auto = True) #self.axes.set_ylim(y1, y2)#, auto = True) self.canvas.draw() def Motion(self, event): self.PanMotion(event) self.ZoomRectMotion(event) if event.inaxes is None: return self.cursorMove.emit(x=event.xdata, y=event.ydata, scatt_id=self.scatt_id) def OnCanvasLeave(self, event): self.cursorMove.emit(x=None, y=None, scatt_id=self.scatt_id) def PanMotion(self, event): 'on mouse movement' if not self.mode == "pan": return if event.inaxes is None: return if event.button != 1: return cur_xlim = self.axes.get_xlim() cur_ylim = self.axes.get_ylim() x, y = event.xdata, event.ydata mx = (x - self.zoom_wheel_coords['x']) * 0.6 my = (y - self.zoom_wheel_coords['y']) * 0.6 extend = (cur_xlim[0] - mx, cur_xlim[1] - mx, cur_ylim[0] - my, cur_ylim[1] - my) self.zoom_wheel_coords['x'] = x self.zoom_wheel_coords['y'] = y self.axes.axis(extend) #self.canvas.copy_from_bbox(self.axes.bbox) #self.canvas.restore_region(self.background) self.canvas.draw() def ZoomRectMotion(self, event): if not self.mode == "zoom": return if event.inaxes is None: return if event.button != 1: return x1, y1 = event.xdata, event.ydata self.zoom_rect.set_visible(True) x2 = self.zoom_rect_coords['x'] y2 = self.zoom_rect_coords['y'] self.zoom_rect.xy = ((x1, y1), (x1, y2), (x2, y2), (x2, y1), (x1, y1)) #self.axes.draw_artist(self.zoom_rect) self.canvas.draw()
class WxLineScatterWidget(wx.Panel): axis_width = 20 axis_offset = 1.05 def __init__(self, *args, **kwargs): kwargs['style'] = kwargs.setdefault( 'style', wx.NO_FULL_REPAINT_ON_RESIZE) | wx.NO_FULL_REPAINT_ON_RESIZE wx.Panel.__init__(self, *args, **kwargs) self.id = wx.NewId() self.plot1 = 'none' self.plot2 = 'none' self.plot3 = 'none' self.lineprops1 = wxLineProps({'color': '#990000', 'fill': True}) self.lineprops2 = wxLineProps({'color': '#009900', 'fill': True}) self.lineprops3 = wxLineProps({'color': '#000099', 'fill': True}) self.autoy1 = True self.autoy2 = True self.autoy3 = True self.smooth1 = 1 self.smooth2 = 1 self.smooth3 = 1 self.xaxis = '' self.press = False self.cursor = None self.span = None self.selstart = 0 self.selstop = 0 self.enablecursor = True self.enablespan = True self.cursorcolor = '#FF0000' self.cursorwidth = 1 self.gpxfig = Figure() self.ax1 = self.gpxfig.add_subplot( 1, 1, 1 ) # create a grid of 1 row, 1 col and put a subplot in the first cell of this grid self.gpxfig.subplots_adjust(right=0.9, left=0.06) self.ax2 = self.ax1.twinx() #self.ax2.spines["left"].set_visible(False) self.ax3 = self.ax1.twinx() self.ax3.spines["right"].set_position(("axes", self.axis_offset)) #self.ax3.spines["left"].set_visible(False) # canvas and events self.gpxcanvas = FigureCanvas(self, -1, self.gpxfig) self.gpxcanvas.mpl_connect('scroll_event', self.OnMouseWheel) self.gpxcanvas.mpl_connect('button_press_event', self.OnLeftMouseDown) self.gpxcanvas.mpl_connect('button_release_event', self.OnLeftMouseUp) self.gpxcanvas.mpl_connect('motion_notify_event', self.OnMouseMotion) self.gpxcanvas.mpl_connect('resize_event', self.OnSize) self.gpxcanvas.mpl_connect('figure_enter_event', self.OnMouseEnter) self.gpxcanvas.mpl_connect('figure_leave_event', self.OnMouseLeave) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightMouseDown) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.gpxcanvas, 1, wx.LEFT | wx.TOP | wx.GROW | wx.EXPAND) self.SetSizer(self.sizer) #self.OnSize(None) msgwrap.register(self.OnSigCurChanged, signal="CurChanged") msgwrap.register(self.OnSigSelChanged, signal="SelChanged") msgwrap.register(self.OnSigValChanged, signal="ValChanged") #set background color to pure white #that code does not work on linux... #color = wx.SystemSettings.GetColour(wx.wx.SYS_COLOUR_BTNFACE) color = wx.Colour(255, 255, 255) self.gpxfig.set_facecolor( (color.red / 255.0, color.green / 255.0, color.blue / 255.0)) self.gpxfig.set_edgecolor( (color.red / 255.0, color.green / 255.0, color.blue / 255.0)) self.gpxfig.set_edgecolor((0.0, 0.0, 0.0)) self.gpxcanvas.SetBackgroundColour(color) # create right now the popup menu self.select_menu = wx.Menu() for text in ["Disable selected",\ "Enable selected",\ "Delete selected",\ "Disable non selected",\ "Enable non selected",\ "Delete non selected",\ "Toggle points"]: item = self.select_menu.Append(wx.NewId(), text) self.Bind(wx.EVT_MENU, self.OnPopup, item) def x_to_num(self, value, scaled=True): if self.xaxis == 'time': return dates.date2num(dateutil.parser.parse(value)) else: if scaled: #return float(value)/self.gpx.get_scale(self.xaxis) return float(value) * self.gpx.get_scale(self.xaxis) else: return float(value) def num_to_x(self, value, scaled=True): if self.xaxis == 'time': return dates.num2date(value) else: if scaled: #return value*self.gpx.get_scale(self.xaxis) return value / self.gpx.get_scale(self.xaxis) else: return value def x_max(self): if self.xaxis == 'time': return self.x_to_num( self.gpx[self.xaxis][self.gpx.get_row_count() - 1]) else: return self.x_to_num(np.nanmax(self.gpx[self.xaxis])) def x_min(self): if self.xaxis == 'time': return self.x_to_num(self.gpx[self.xaxis][0]) else: return self.x_to_num(np.nanmin(self.gpx[self.xaxis])) def format_x_axis(self): if self.xaxis == 'time': xlo = self.ax1.get_xlim()[0] xhi = self.ax1.get_xlim()[1] if (xhi - xlo) > 0.003: self.ax1.xaxis.set_major_formatter( dates.DateFormatter("%H:%M")) else: self.ax1.xaxis.set_major_formatter( dates.DateFormatter("%H:%M:%S")) self.ax1.set_xlabel('Time (HH:MM:SS)') else: #self.ax1.set_xlabel('Distance (m)') self.ax1.set_xlabel(self.xaxis + " (" + self.gpx.get_unit(self.xaxis)[0] + ")") #self.ax1.xaxis.set_major_formatter(mpl.ticker.FormatStrFormatter('%.0f') ) self.ax1.xaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) pass def get_axis(self, event, tolerance): bbox = self.ax1.get_window_extent().transformed( self.gpxfig.dpi_scale_trans.inverted()) l = bbox.bounds[0] * self.gpxfig.dpi b = bbox.bounds[1] * self.gpxfig.dpi r = l + bbox.bounds[2] * self.gpxfig.dpi t = b + bbox.bounds[3] * self.gpxfig.dpi #convert screen coordinates to graph coordinates xlo = self.ax1.get_xlim()[0] xhi = self.ax1.get_xlim()[1] event.xdata = (event.x - l) / (r - l) * (xhi - xlo) + xlo if ptinrect(l - tolerance, t, l, b, event.x, event.y): ylo, yhi = self.ax1.get_ylim() event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo return 'left' if ptinrect(r, t, r + tolerance, b, event.x, event.y): ylo, yhi = self.ax2.get_ylim() event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo return 'right' if ptinrect(l, t, r, t + tolerance, event.x, event.y): ylo, yhi = self.ax1.get_ylim() event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo return 'top' if ptinrect(l, b - tolerance, r, b, event.x, event.y): ylo, yhi = self.ax1.get_ylim() event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo return 'bottom' #we need a small adjustment here, but this hack gives good results if ptinrect(r * self.axis_offset * 0.985, t, r * self.axis_offset * 0.985 + tolerance, b, event.x, event.y): ylo, yhi = self.ax3.get_ylim() event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo return "3rd" if ptinrect(l, t, r, b, event.x, event.y): ylo, yhi = self.ax1.get_ylim() event.ydata = (event.y - b) / (t - b) * (yhi - ylo) + ylo return 'main' def update_axis(self, ax, plot, ylo, yhi, yauto, lineprops, smooth): if plot != 'none': ## process data!! N = smooth #data=(1.0)*np.convolve(self.gpx[plot]*self.gpx.scale[plot], np.ones((N,))/N)[(N-1):] data = (1.0) * np.convolve(self.gpx[(plot, True)], np.ones((N, )) / N)[(N - 1):] data[self.gpx['ok'] == False] = np.NAN ##end of data processing #remove fill_between collection for coll in ax.collections: ax.collections.remove(coll) #need to rebuild dates array in case something was deleted self.xvalues = [] for x in self.gpx[self.xaxis]: self.xvalues.append(self.x_to_num(x)) ax.get_lines()[0].set_data(self.xvalues, data) self.format_x_axis() if lineprops['fill']: ax.fill_between(self.xvalues, 0, data, facecolor=lineprops['color'], alpha=0.2) ax.get_lines()[0].set_color(lineprops['color']) ax.get_lines()[0].set_linewidth(lineprops['linewidth']) ax.get_lines()[0].set_marker(lineprops['marker']) ax.get_lines()[0].set_markersize(lineprops['markersize']) ax.set_autoscaley_on(yauto) ##now using legends instead of labels #ax.set_ylabel(plot+" ("+str(self.gpx.get_unit(plot)[0])+")") #ax.yaxis.label.set_color(lineprops['color']) lines = self.line1 + self.line2 + self.line3 labs = [ p for p in [self.plot1, self.plot2, self.plot3] if p != 'none' ] self.ax1.legend( lines, labs, loc='best' ) #,bbox_to_anchor=(0.5, 1.3), ncol=3, fancybox=False, shadow=False) if not yauto: ax.set_ylim(ylo, yhi) else: ax.set_ylim(np.min(self.gpx[plot] * self.gpx.scale[plot]), np.max(self.gpx[plot] * self.gpx.scale[plot])) ax.set_visible(True) for tick in ax.get_yticklabels(): tick.set_color(lineprops['color']) ax.spines["right"].set_edgecolor(lineprops['color']) ax.tick_params(axis='y', colors=lineprops['color']) else: ax.get_lines()[0].set_data(self.xvalues, np.zeros(self.gpx.get_row_count())) ax.set_visible(False) self.cursor.set_color(self.cursorcolor) self.cursor.set_linewidth(self.cursorwidth) self.format_x_axis() self.Draw(False) self.OnSize(None) def AttachGpx(self, data): self.gpx = data self.xvalues = [] self.xaxis = self.gpx.get_header_names()[0] for x in self.gpx[self.xaxis]: self.xvalues.append(self.x_to_num(x)) self.ax1.set_xlabel('') self.line1 = self.ax1.plot(self.xvalues, np.zeros(self.gpx.get_row_count()), picker=5, label='ax1') self.line2 = self.ax2.plot(self.xvalues, np.zeros(self.gpx.get_row_count()), picker=5, label='ax2') self.line3 = self.ax3.plot(self.xvalues, np.zeros(self.gpx.get_row_count()), picker=5, label='ax3') xlo = self.x_to_num(self.gpx[self.xaxis][0]) xhi = self.x_to_num(self.gpx[self.xaxis][self.gpx.get_row_count() - 1]) if xlo != xhi: self.ax1.set_xlim([xlo, xhi]) if self.enablecursor == True: self.cursor = self.ax1.axvline(color='r', animated=True) mid = (self.ax1.get_xlim()[0] + self.ax1.get_xlim()[1]) / 2 self.cursor.set_xdata(mid) #self.cursor.set_color('k') #self.cursor.set_linewidth(4) if self.enablespan == True: self.span = patches.Rectangle( (self.ax1.get_xlim()[0], 0), (self.ax1.get_xlim()[1] - self.ax1.get_xlim()[0]) / 3, 200, color='k', alpha=0.3, animated=True) self.ax1.add_patch(self.span) self.span.set_visible(False) self.SetDefaultPlots() self.OnSize(None) def DetachGpx(self): self.gpx = None self.plot1 = 'none' self.plot2 = 'none' self.plot3 = 'none' self.autoy1 = True self.autoy2 = True self.autoy3 = True self.fill1 = True self.fill2 = True self.fill3 = True self.xaxis = '' self.press = False if self.cursor != None: self.cursor.remove() self.cursor = None if self.span != None: self.span.remove() self.span = None def OnSigSelChanged(self, arg1, arg2, arg3): if arg1 == self.id: return if self.span != None: xlo = self.x_to_num(self.gpx[self.xaxis][arg2]) xhi = self.x_to_num(self.gpx[self.xaxis][arg3]) self.span.set_bounds( xlo, self.ax1.get_ylim()[0], xhi - xlo, self.ax1.get_ylim()[1] - self.ax1.get_ylim()[0]) self.span.set_visible(True) def OnSigValChanged(self, arg1): if arg1 == self.id: return self.update_axis(self.ax1, self.plot1, self.ax1.get_xlim()[0], self.ax1.get_xlim()[1], self.autoy1, self.lineprops1, self.smooth1) self.update_axis(self.ax2, self.plot2, self.ax2.get_xlim()[0], self.ax2.get_xlim()[1], self.autoy2, self.lineprops2, self.smooth2) self.update_axis(self.ax3, self.plot3, self.ax2.get_xlim()[0], self.ax2.get_xlim()[1], self.autoy3, self.lineprops3, self.smooth3) def OnSigCurChanged(self, arg1, arg2): if arg1 == self.id: return if self.gpx != None: xval = self.gpx[self.xaxis][arg2] self.gpxcanvas.restore_region(self.background) if self.cursor != None: self.cursor.set_xdata(self.x_to_num(xval)) self.ax1.draw_artist(self.cursor) if self.span != None and self.span.get_visible(): self.ax1.draw_artist(self.span) self.gpxcanvas.blit() self.UpdateStatusBar(arg2) def SetDefaultPlots(self): self.xaxis = self.gpx.get_header_names()[0] self.plot1 = self.gpx.get_header_names()[1] self.plot2 = 'none' self.plot3 = 'none' self.update_axis(self.ax1, self.plot1, 0, 1, True, self.lineprops1, self.smooth1) self.update_axis(self.ax2, self.plot2, 0, 1, True, self.lineprops2, self.smooth2) self.update_axis(self.ax3, self.plot3, 0, 1, True, self.lineprops3, self.smooth3) def XAxisAllowed(self): l = '' for name in self.gpx.get_header_names(): l += '|' + name return l[1:] def YAxisAllowed(self): l = '' for name in self.gpx.get_header_names(): l += '|' + name return l[1:] def Draw(self, blit): if blit: self.gpxcanvas.restore_region(self.background) else: self.gpxcanvas.draw() self.background = self.gpxcanvas.copy_from_bbox(self.ax1.bbox) if self.span != None and self.span.get_visible(): self.ax1.draw_artist(self.span) if self.cursor != None: self.ax1.draw_artist(self.cursor) self.gpxcanvas.blit() def OnSize(self, event): pixels = self.GetClientSize() if pixels[0] < 20 or pixels[1] < 20: return self.SetSize(pixels) self.gpxcanvas.SetSize(pixels) self.gpxfig.set_size_inches( float(pixels[0]) / self.gpxfig.get_dpi(), float(pixels[1]) / self.gpxfig.get_dpi()) leg = self.ax1.xaxis.get_tightbbox(self.gpxcanvas.get_renderer()) leg1 = self.ax1.yaxis.get_tightbbox(self.gpxcanvas.get_renderer()) leg2 = self.ax2.yaxis.get_tightbbox(self.gpxcanvas.get_renderer()) leg3 = self.ax3.yaxis.get_tightbbox(self.gpxcanvas.get_renderer( )) #leg2 and leg3 are exactly the same!! bottomalign = (leg.height + 5) / pixels[1] leftalign = (leg1.width + 5) / pixels[0] if self.plot2 == 'none' and self.plot3 == 'none': rightalign = (1 - (5.0) / pixels[0]) / self.axis_offset else: rightalign = (1 - (leg2.width + 5) / pixels[0]) / self.axis_offset if pixels[1] > 32: self.gpxfig.subplots_adjust(bottom=bottomalign) if pixels[0] > 32: self.gpxfig.subplots_adjust(left=leftalign, right=rightalign) ##PYTHON3 self.gpxfig.subplots_adjust(right=0.9, left=0.06, bottom=0.2) self.Draw(False) def OnLeftMouseDblClick(self, event): #dble click. Let's get prepared xlo = self.num_to_x(self.ax1.get_xlim()[0], False) xhi = self.num_to_x(self.ax1.get_xlim()[1], False) y1lo = self.ax1.get_ylim()[0] y1hi = self.ax1.get_ylim()[1] y2lo = self.ax2.get_ylim()[0] y2hi = self.ax2.get_ylim()[1] y3lo = self.ax3.get_ylim()[0] y3hi = self.ax3.get_ylim()[1] (dummy,xaxis,xlo,xhi,self.cursorcolor,self.cursorwidth, dummy,self.plot1,y1lo,y1hi,self.autoy1,self.smooth1, self.lineprops1['color'],self.lineprops1['linewidth'],self.lineprops1['marker'],self.lineprops1['markersize'],self.lineprops1['fill'],\ dummy,self.plot2,y2lo,y2hi,self.autoy2,self.smooth2, self.lineprops2['color'],self.lineprops2['linewidth'],self.lineprops2['marker'],self.lineprops2['markersize'],self.lineprops2['fill'],\ dummy,self.plot3,y3lo,y3hi,self.autoy3,self.smooth3, self.lineprops3['color'],self.lineprops3['linewidth'],self.lineprops3['marker'],self.lineprops3['markersize'],self.lineprops3['fill'])=\ WxQuery("Graph Settings",\ [('wxnotebook','X Axis',None,None,None), ('wxcombo','X axis',self.XAxisAllowed(),self.xaxis,'str'), ("wxentry","Start",None,str(xlo),'str'), ("wxentry","End",None,str(xhi),'str'), ('wxcolor','Cursor color',None,self.cursorcolor,'str'), ('wxspin','Cursor width','0|6|1',self.cursorwidth,'int'), ('wxnotebook','Y1Axis',None,None,None), ('wxcombo','Channel 1',self.YAxisAllowed(),self.plot1,'str'), ('wxentry','Bottom',None,y1lo,'float'), ('wxentry','Top',None,y1hi,'float'), ('wxcheck','Auto Scale','-9|-8', self.autoy1,'bool'), #8 ('wxhscale','Smooth','1|12|1|1',self.smooth1,'int'), ('wxcolor','Color',None,self.lineprops1['color'],'str'), ('wxspin','Line width','0|12|1',self.lineprops1['linewidth'],'int'), ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops1['marker'],'str'), ('wxspin','Marker size','0|12|1',self.lineprops1['markersize'],'int'), ('wxcheck','Fill area',None,self.lineprops1['fill'],'bool'), ('wxnotebook','Y2 Axis',None,None,None), ('wxcombo','Channel 2',self.YAxisAllowed(),self.plot2,'str'), ('wxentry','Bottom',None,y2lo,'float'), ('wxentry','Top',None,y2hi,'float'), ('wxcheck','Auto Scale','-20|-19', self.autoy2,'bool'), ('wxhscale','Smooth','1|12|1|1',self.smooth2,'int'), ('wxcolor','Color',None,self.lineprops2['color'],'str'), ('wxspin','Line width','0|12|1',self.lineprops2['linewidth'],'int'), ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops2['marker'],'str'), ('wxspin','Marker size','0|12|1',self.lineprops2['markersize'],'int'), ('wxcheck','Fill area',None,self.lineprops2['fill'],'bool'), ('wxnotebook','Y3 Axis',None,None,None), ('wxcombo','Channel 3',self.YAxisAllowed(),self.plot3,'str'), ('wxentry','Bottom',None,y3lo,'float'), ('wxentry','Top',None,y3hi,'float'), ('wxcheck','Auto Scale','-31|-30', self.autoy3,'bool'), ('wxhscale','Smooth','1|12|1|1',self.smooth3,'int'), ('wxcolor','Color',None,self.lineprops3['color'],'str'), ('wxspin','Line width','0|12|1',self.lineprops3['linewidth'],'int'), ('wxcombo','Marker','.|o|+|x|^|4|s|*|D',self.lineprops3['marker'],'str'), ('wxspin','Marker size','0|12|1',self.lineprops3['markersize'],'int'), ('wxcheck','Fill area',None,self.lineprops3['fill'],'bool') ]) if self.xaxis == xaxis: xlo = max(self.x_to_num(xlo, False), self.x_min()) xhi = min(self.x_to_num(xhi, False), self.x_max()) self.ax1.set_xlim([xlo, xhi]) else: #time units have changed... don't bother and set to full x range self.xaxis = xaxis self.ax1.set_xlim([self.x_min(), self.x_max()]) self.update_axis(self.ax1, self.plot1, y1lo, y1hi, self.autoy1, self.lineprops1, self.smooth1) self.update_axis(self.ax2, self.plot2, y2lo, y2hi, self.autoy2, self.lineprops2, self.smooth2) self.update_axis(self.ax3, self.plot3, y3lo, y3hi, self.autoy3, self.lineprops3, self.smooth3) def OnLeftMouseDown(self, event): where = self.get_axis(event, self.axis_width) #if hasattr(event, 'guiEvent') and int(event.guiEvent.type)==5: #calling direcly the dialog may freeze on unix (linux-osX systems) under wx backend #workaround is to release mouse #see http://stackoverflow.com/questions/16815695/modal-dialog-freezes-the-whole-application #event.guiEvent.GetEventObject().ReleaseMouse() for pick_event if event.button == 1: if event.dblclick: try: event.guiEvent.GetEventObject().ReleaseMouse() except: pass self.OnLeftMouseDblClick(event) return if where == 'bottom': (self.x0, self.y0) = (event.xdata, event.ydata) self.press = True if where == 'main' and self.span != None: self.span.set_visible(True) (self.x0, self.y0) = (event.xdata, event.ydata) self.selstart = self.x0 self.selstop = self.x0 self.span.set_bounds( event.xdata, self.ax1.get_ylim()[0], 0, self.ax1.get_ylim()[1] - self.ax1.get_ylim()[0]) self.press = True elif event.button == 3: if where == 'main': self.OnRightMouseDown(event) def OnLeftMouseUp(self, event): where = self.get_axis(event, self.axis_width) self.press = False if event.button == 1 and self.span != None: if where == 'main': idx1 = np.searchsorted(self.ax1.get_lines()[0].get_data()[0], self.x0) idx2 = np.searchsorted(self.ax1.get_lines()[0].get_data()[0], event.xdata) self.selstart = min(idx1, idx2) self.selstop = max(idx1, idx2) if self.selstart == self.selstop: self.span.set_visible(False) msgwrap.message("SelChanged", arg1=self.id, arg2=self.selstart, arg3=self.selstop) self.press = False def OnRightMouseDown(self, event): #may be necessary in some OSes event.guiEvent.GetEventObject().ReleaseMouse() if self.selstart == self.selstop: self.select_menu.Enable( self.select_menu.FindItem("Disable selected"), False) self.select_menu.Enable( self.select_menu.FindItem("Enable selected"), False) self.select_menu.Enable( self.select_menu.FindItem("Delete selected"), False) else: self.select_menu.Enable( self.select_menu.FindItem("Disable selected"), True) self.select_menu.Enable( self.select_menu.FindItem("Enable selected"), True) self.select_menu.Enable( self.select_menu.FindItem("Delete selected"), True) self.select_menu.Enable(self.select_menu.FindItem("Toggle points"), True) # on some OS (and depending on wxPython/wxWidgets version, calling # wx.PopupMenu will fail unless it is called after matplotlib handler has returned # for some magic reason, we do not need to specify wx.Point(event.x, event.y) in parameterss #self.PopupMenu(self.select_menus) wx.CallAfter(self.PopupMenu, self.select_menu) def OnMouseMotion(self, event): where = self.get_axis(event, self.axis_width) if where == 'bottom' or where == 'right' or where == 'left' or where == '3rd': wx.SetCursor(wx.Cursor(wx.CURSOR_MAGNIFIER)) else: wx.SetCursor(wx.Cursor(wx.CURSOR_ARROW)) if where == 'bottom' and self.press: dx = event.xdata - self.x0 dy = event.ydata - self.y0 self.ax1.set_xlim(self.ax1.get_xlim()[0] - dx, self.ax1.get_xlim()[1] - dx) self.Draw(False) if where == 'main' and self.press: self.span.set_bounds(self.x0,\ self.ax1.get_ylim()[0],\ event.xdata-self.x0,\ self.ax1.get_ylim()[1]-self.ax1.get_ylim()[0]) self.Draw(True) if where == 'main' and self.cursor != None: self.cursor.set_xdata(event.xdata) xval = event.xdata idx = np.searchsorted(self.ax1.get_lines()[0].get_data()[0], xval) while self.gpx['ok'][ idx] == False and idx >= 0: #look for nearest enabled point idx -= 1 idx = clamp(idx, 0, self.gpx.get_row_count() - 1) self.cursor.set_xdata(self.x_to_num(self.gpx[self.xaxis][idx])) msgwrap.message("CurChanged", arg1=self.id, arg2=idx) ##send a message for the status bar self.UpdateStatusBar(idx) self.Draw(True) def OnMouseWheel(self, event): where = self.get_axis(event, self.axis_width) if where == 'bottom': xmax = self.x_max() xmin = self.x_min() xlo, xhi = self.ax1.get_xlim() if event.button == 'down': scale_factor = 1.2 else: scale_factor = 1 / 1.2 nxhi = event.xdata + (scale_factor * (xhi - event.xdata)) nxlo = event.xdata - (scale_factor * (event.xdata - xlo)) nxhi = min(nxhi, xmax) nxlo = max(nxlo, xmin) self.ax1.set_xlim([nxlo, nxhi]) self.format_x_axis() elif where == 'left' or where == 'right' or where == '3rd': if where == 'left': ax = self.ax1 plot = self.plot1 elif where == 'right': ax = self.ax2 plot = self.plot2 elif where == '3rd': ax = self.ax3 plot = self.plot3 ymax = np.max(self.gpx[plot] * self.gpx.scale[plot]) ymin = np.min(self.gpx[plot] * self.gpx.scale[plot]) ylo, yhi = ax.get_ylim() if event.button == 'down': scale_factor = 1.2 else: scale_factor = 1 / 1.2 nyhi = event.ydata + (scale_factor * (yhi - event.ydata)) nylo = event.ydata - (scale_factor * (event.ydata - ylo)) nyhi = min(nyhi, ymax) nylo = max(nylo, ymin) ax.set_ylim([nylo, nyhi]) self.Draw(False) def OnMouseEnter(self, event): self.SetFocus( ) # stupid bug in wxSplitterWindow, mouse wheel is always send to the same panel in wxSplittedWIndow def OnMouseLeave(self, event): wx.SetCursor(wx.Cursor(wx.CURSOR_ARROW)) pass def OnPopup(self, event): item = self.select_menu.FindItemById(event.GetId()) text = item.GetText() if text == "Disable selected": self.gpx['ok'][self.selstart:self.selstop] = False if text == "Enable selected": self.gpx['ok'][self.selstart:self.selstop] = True if text == "Disable non selected": self.gpx['ok'][:self.selstart] = False self.gpx['ok'][self.selstop:] = False if text == "Enable non selected": self.gpx['ok'][:self.selstart] = True self.gpx['ok'][self.selstop:] = True if text == "Delete selected": if wx.MessageDialog(None, "Delete Points...?",\ 'Are you sure you want to delete these points',\ wx.YES_NO | wx.ICON_QUESTION).ShowModal()==wx.ID_YES: for _ in range(self.selstart, self.selstop): self.gpx.drop_row( self.selstart ) #each time we delete, the rest of the array is shifted. so we have to delete always the same index if text == "Delete non selected": if wx.MessageDialog(None, "Delete Points...?",\ 'Are you sure you want to delete these points',\ wx.YES_NO | wx.ICON_QUESTION).ShowModal()==wx.ID_YES: for _ in range(self.selstop, self.gpx.get_row_count()): self.gpx.drop_row( self.selstop ) #delete first end of range, to avoid shifting selstop for _ in range(0, self.selstart): self.gpx.drop_row(0) if text == "Toggle points": self.gpx['ok'] = np.invert(self.gpx['ok']) msgwrap.message("ValChanged", arg1=self.id) self.update_axis(self.ax1, self.plot1, self.ax1.get_ylim()[0], self.ax1.get_ylim()[1], self.autoy1, self.lineprops1, self.smooth1) self.update_axis(self.ax2, self.plot2, self.ax2.get_ylim()[0], self.ax2.get_ylim()[1], self.autoy2, self.lineprops2, self.smooth2) self.update_axis(self.ax3, self.plot3, self.ax3.get_ylim()[0], self.ax3.get_ylim()[1], self.autoy3, self.lineprops3, self.smooth3) def UpdateStatusBar(self, idx): if self.plot1 != "none": msg1=self.plot1+\ " ("+str(self.gpx.get_unit(self.plot1)[0])+"): "\ +str(self.gpx[self.plot1][idx]*self.gpx.scale[self.plot1]) else: msg1 = "" if self.plot2 != "none": msg2=self.plot2+\ " ("+str(self.gpx.get_unit(self.plot2)[0])+"): "\ +str(self.gpx[self.plot2][idx]*self.gpx.scale[self.plot2]) else: msg2 = "" if self.plot3 != "none": msg3=self.plot3+\ " ("+str(self.gpx.get_unit(self.plot3)[0])+"): "\ +str(self.gpx[self.plot3][idx]*self.gpx.scale[self.plot3]) else: msg3 = "" msgwrap.message("StatusChanged",arg1=self.id,\ arg2=self.gpx['time'][idx],\ arg3=msg1,\ arg4=msg2,\ arg5=msg3 )
def __init__(self, *args, **kwargs): kwargs['style'] = kwargs.setdefault( 'style', wx.NO_FULL_REPAINT_ON_RESIZE) | wx.NO_FULL_REPAINT_ON_RESIZE wx.Panel.__init__(self, *args, **kwargs) self.id = wx.NewId() self.plot1 = 'none' self.plot2 = 'none' self.plot3 = 'none' self.lineprops1 = wxLineProps({'color': '#990000', 'fill': True}) self.lineprops2 = wxLineProps({'color': '#009900', 'fill': True}) self.lineprops3 = wxLineProps({'color': '#000099', 'fill': True}) self.autoy1 = True self.autoy2 = True self.autoy3 = True self.smooth1 = 1 self.smooth2 = 1 self.smooth3 = 1 self.xaxis = '' self.press = False self.cursor = None self.span = None self.selstart = 0 self.selstop = 0 self.enablecursor = True self.enablespan = True self.cursorcolor = '#FF0000' self.cursorwidth = 1 self.gpxfig = Figure() self.ax1 = self.gpxfig.add_subplot( 1, 1, 1 ) # create a grid of 1 row, 1 col and put a subplot in the first cell of this grid self.gpxfig.subplots_adjust(right=0.9, left=0.06) self.ax2 = self.ax1.twinx() #self.ax2.spines["left"].set_visible(False) self.ax3 = self.ax1.twinx() self.ax3.spines["right"].set_position(("axes", self.axis_offset)) #self.ax3.spines["left"].set_visible(False) # canvas and events self.gpxcanvas = FigureCanvas(self, -1, self.gpxfig) self.gpxcanvas.mpl_connect('scroll_event', self.OnMouseWheel) self.gpxcanvas.mpl_connect('button_press_event', self.OnLeftMouseDown) self.gpxcanvas.mpl_connect('button_release_event', self.OnLeftMouseUp) self.gpxcanvas.mpl_connect('motion_notify_event', self.OnMouseMotion) self.gpxcanvas.mpl_connect('resize_event', self.OnSize) self.gpxcanvas.mpl_connect('figure_enter_event', self.OnMouseEnter) self.gpxcanvas.mpl_connect('figure_leave_event', self.OnMouseLeave) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightMouseDown) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.gpxcanvas, 1, wx.LEFT | wx.TOP | wx.GROW | wx.EXPAND) self.SetSizer(self.sizer) #self.OnSize(None) msgwrap.register(self.OnSigCurChanged, signal="CurChanged") msgwrap.register(self.OnSigSelChanged, signal="SelChanged") msgwrap.register(self.OnSigValChanged, signal="ValChanged") #set background color to pure white #that code does not work on linux... #color = wx.SystemSettings.GetColour(wx.wx.SYS_COLOUR_BTNFACE) color = wx.Colour(255, 255, 255) self.gpxfig.set_facecolor( (color.red / 255.0, color.green / 255.0, color.blue / 255.0)) self.gpxfig.set_edgecolor( (color.red / 255.0, color.green / 255.0, color.blue / 255.0)) self.gpxfig.set_edgecolor((0.0, 0.0, 0.0)) self.gpxcanvas.SetBackgroundColour(color) # create right now the popup menu self.select_menu = wx.Menu() for text in ["Disable selected",\ "Enable selected",\ "Delete selected",\ "Disable non selected",\ "Enable non selected",\ "Delete non selected",\ "Toggle points"]: item = self.select_menu.Append(wx.NewId(), text) self.Bind(wx.EVT_MENU, self.OnPopup, item)
class GraphFrame(wx.Frame): """ The main frame of the application """ title = 'Demo: dynamic matplotlib graph' def __init__(self): wx.Frame.__init__(self, None, -1, self.title) self.datagen = DataGen() self.data = [self.datagen.next()] self.paused = False self.create_menu() self.create_status_bar() self.create_main_panel() self.redraw_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer) self.redraw_timer.Start(100) def create_menu(self): self.menubar = wx.MenuBar() menu_file = wx.Menu() m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S", "Save plot to file") self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt) menu_file.AppendSeparator() m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit") self.Bind(wx.EVT_MENU, self.on_exit, m_exit) self.menubar.Append(menu_file, "&File") self.SetMenuBar(self.menubar) def create_main_panel(self): self.panel = wx.Panel(self) self.init_plot() self.canvas = FigCanvas(self.panel, -1, self.fig) self.xmin_control = BoundControlBox(self.panel, -1, "X min", 0) self.xmax_control = BoundControlBox(self.panel, -1, "X max", 50) self.ymin_control = BoundControlBox(self.panel, -1, "Y min", 0) self.ymax_control = BoundControlBox(self.panel, -1, "Y max", 100) self.pause_button = wx.Button(self.panel, -1, "Pause") self.Bind(wx.EVT_BUTTON, self.on_pause_button, self.pause_button) self.Bind(wx.EVT_UPDATE_UI, self.on_update_pause_button, self.pause_button) self.cb_grid = wx.CheckBox(self.panel, -1, "Show Grid", style=wx.ALIGN_RIGHT) self.Bind(wx.EVT_CHECKBOX, self.on_cb_grid, self.cb_grid) self.cb_grid.SetValue(True) self.cb_xlab = wx.CheckBox(self.panel, -1, "Show X labels", style=wx.ALIGN_RIGHT) self.Bind(wx.EVT_CHECKBOX, self.on_cb_xlab, self.cb_xlab) self.cb_xlab.SetValue(True) self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) self.hbox1.Add(self.pause_button, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox1.AddSpacer(20) self.hbox1.Add(self.cb_grid, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox1.AddSpacer(10) self.hbox1.Add(self.cb_xlab, border=5, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) self.hbox2.Add(self.xmin_control, border=5, flag=wx.ALL) self.hbox2.Add(self.xmax_control, border=5, flag=wx.ALL) self.hbox2.AddSpacer(24) self.hbox2.Add(self.ymin_control, border=5, flag=wx.ALL) self.hbox2.Add(self.ymax_control, border=5, flag=wx.ALL) self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas, 1, flag=wx.LEFT | wx.TOP | wx.GROW) self.vbox.Add(self.hbox1, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.vbox.Add(self.hbox2, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.panel.SetSizer(self.vbox) self.vbox.Fit(self) def create_status_bar(self): self.statusbar = self.CreateStatusBar() def init_plot(self): self.dpi = 100 self.BUF_LEN = 128 # Length of data buffer self.timestep = 1 # Time between samples self.period = BUF_LEN * timestep # Period of 1 draw cycle self.height = 2000000 # Expected sample value range # X value (time) self.times = numpy.arange(0, period, timestep) self.channels = 5 # Y values self.samples = numpy.zeros([BUF_LEN, channels]) self.lines = [] self.styles = ['r-', 'g-', 'y-', 'm-', 'k-'] # create 5 subplots and set their axes limits self.fig, self.axes = plt.subplots(nrows=self.channels) for i in range(self.channels): (self.lines).extend((self.axes[i]).plot(times, self.samples[:, i], self.styles[i], animated=True)) (self.lines[i]).axes.set_ylim(-self.height, height) (self.lines[i]).axes.set_xlim(-self.timestep, self.period + self.timestep) # capture background of the figure self.backgrounds = [(self.fig).canvas.copy_from_bbox(ax.bbox) for ax in self.axes] # Make a convenient zipped list for simultaneous access items = zip(self.lines, self.axes, self.backgrounds) (self.fig).show() (self.fig).canvas.draw() # Open serial connection self.ser = serial.Serial(3, baudrate=57600, timeout=1) (self.ser).setRTS(True) #? (self.ser).setRTS(False) #? # array to read in 4 bytes at a time self.data = deque() self.t = 0 self.pos = 0 self.tstart = time.time() while t < 2000: # plot 5 channels, up to 4-byte integers (long) while ser.inWaiting() > 4: data.append(bytearray(4)) ser.readinto(data[-1]) if len(data) > channels: for i in range(channels): bytes = data.popleft() # construct y value height = (bytes[0] << 24) + (bytes[1] << 16) + ( bytes[2] << 8) + bytes[3] # convert to signed long if (height >= 0x80000000): height = height - 0x100000000 samples[pos, i] = numpy.long(height) for j, (line, ax, background) in enumerate(items): fig.canvas.restore_region(background) line.set_ydata(samples[:, j]) ax.draw_artist(line) fig.canvas.blit(ax.bbox) pos += 1 if (pos == BUF_LEN): pos = 0 t += 1 print ser.inWaiting() print len(data) ser.close def draw_plot(self): """ Redraws the plot """ # when xmin is on auto, it "follows" xmax to produce a # sliding window effect. therefore, xmin is assigned after # xmax. # if self.xmax_control.is_auto(): xmax = len(self.data) if len(self.data) > 50 else 50 else: xmax = int(self.xmax_control.manual_value()) if self.xmin_control.is_auto(): xmin = xmax - 50 else: xmin = int(self.xmin_control.manual_value()) # for ymin and ymax, find the minimal and maximal values # in the data set and add a mininal margin. # # note that it's easy to change this scheme to the # minimal/maximal value in the current display, and not # the whole data set. # if self.ymin_control.is_auto(): ymin = round(min(self.data), 0) - 1 else: ymin = int(self.ymin_control.manual_value()) if self.ymax_control.is_auto(): ymax = round(max(self.data), 0) + 1 else: ymax = int(self.ymax_control.manual_value()) self.axes.set_xbound(lower=xmin, upper=xmax) self.axes.set_ybound(lower=ymin, upper=ymax) # anecdote: axes.grid assumes b=True if any other flag is # given even if b is set to False. # so just passing the flag into the first statement won't # work. # if self.cb_grid.IsChecked(): self.axes.grid(True, color='gray') else: self.axes.grid(False) # Using setp here is convenient, because get_xticklabels # returns a list over which one needs to explicitly # iterate, and setp already handles this. # pylab.setp(self.axes.get_xticklabels(), visible=self.cb_xlab.IsChecked()) self.plot_data.set_xdata(np.arange(len(self.data))) self.plot_data.set_ydata(np.array(self.data)) self.canvas.draw() def on_pause_button(self, event): self.paused = not self.paused def on_update_pause_button(self, event): label = "Resume" if self.paused else "Pause" self.pause_button.SetLabel(label) def on_cb_grid(self, event): self.draw_plot() def on_cb_xlab(self, event): self.draw_plot() def on_save_plot(self, event): file_choices = "PNG (*.png)|*.png" dlg = wx.FileDialog(self, message="Save plot as...", defaultDir=os.getcwd(), defaultFile="plot.png", wildcard=file_choices, style=wx.SAVE) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.canvas.print_figure(path, dpi=self.dpi) self.flash_status_message("Saved to %s" % path) def on_redraw_timer(self, event): # if paused do not add data, but still redraw the plot # (to respond to scale modifications, grid change, etc.) # if not self.paused: self.data.append(self.datagen.next()) self.draw_plot() def on_exit(self, event): self.Destroy() def flash_status_message(self, msg, flash_len_ms=1500): self.statusbar.SetStatusText(msg) self.timeroff = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_flash_status_off, self.timeroff) self.timeroff.Start(flash_len_ms, oneShot=True) def on_flash_status_off(self, event): self.statusbar.SetStatusText('')
class PlotPanel(wx.Panel): """ The PlotPanel has a Figure and a Canvas. OnSize events simply set a flag, and the actual resizing of the figure is triggered by an Idle event. See: http://www.scipy.org/Matplotlib_figure_in_a_wx_panel """ def __init__(self, parent, dataframes, color=None, dpi=None, **kwargs): # initialize Panel if 'id' not in kwargs.keys(): kwargs['id'] = wx.ID_ANY if 'style' not in kwargs.keys(): kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE wx.Panel.__init__(self, parent, **kwargs) self.parent = parent self.dataframes = dataframes # initialize matplotlib stuff self.figure = Figure(None, dpi) self.figure.autofmt_xdate() self.canvas = FigureCanvasWxAgg(self, -1, self.figure) self.SetColor(color) #self._SetSize((800, 600)) self.draw() self._resizeflag = False self.Bind(wx.EVT_IDLE, self._onIdle) self.Bind(wx.EVT_SIZE, self._onSize) def SetColor(self, rgbtuple=None): """Set figure and canvas colours to be the same.""" if rgbtuple is None: rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get() clr = [c / 255. for c in rgbtuple] self.figure.set_facecolor(clr) self.figure.set_edgecolor(clr) self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple)) def _onSize(self, event): self._resizeflag = True def _onIdle(self, evt): if self._resizeflag: self._resizeflag = False self._SetSize() def _SetSize(self, size=None): if size is None: size = tuple(self.GetClientSize()) self.SetSize(size) self.canvas.SetSize(size) self.figure.set_size_inches( float(size[0]) / self.figure.get_dpi(), float(size[1]) / self.figure.get_dpi()) def draw(self): ax = self.figure.add_subplot(111) for dataframe in self.dataframes: x = dataframe.index for col in dataframe.columns: empty = dataframe[col].count() == 0 y = dataframe[col].values if not empty else np.zeros(x.shape) ax.plot(x, y, label=col) try: self.figure.autofmt_xdate() except: pass ax.legend(loc="best") ax.grid()
class FourierDemoFrame(wx.Frame): def __init__(self, *args, **kwargs): wx.Frame.__init__(self, *args, **kwargs) panel = wx.Panel(self) # create the GUI elements self.createCanvas(panel) self.createSliders(panel) # place them in a sizer for the Layout sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.canvas, 1, wx.EXPAND) sizer.Add(self.frequencySliderGroup.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) sizer.Add(self.amplitudeSliderGroup.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) panel.SetSizer(sizer) def createCanvas(self, parent): self.lines = [] self.figure = Figure() self.canvas = FigureCanvasWxAgg(parent, -1, self.figure) self.canvas.callbacks.connect('button_press_event', self.mouseDown) self.canvas.callbacks.connect('motion_notify_event', self.mouseMotion) self.canvas.callbacks.connect('button_release_event', self.mouseUp) self.state = '' self.mouseInfo = (None, None, None, None) self.f0 = Param(2., minimum=0., maximum=6.) self.A = Param(1., minimum=0.01, maximum=2.) self.createPlots() # Not sure I like having two params attached to the same Knob, # but that is what we have here... it works but feels kludgy - # although maybe it's not too bad since the knob changes both params # at the same time (both f0 and A are affected during a drag) self.f0.attach(self) self.A.attach(self) def createSliders(self, panel): self.frequencySliderGroup = SliderGroup(panel, label='Frequency f0:', param=self.f0) self.amplitudeSliderGroup = SliderGroup(panel, label=' Amplitude a:', param=self.A) def mouseDown(self, evt): if self.lines[0].contains(evt)[0]: self.state = 'frequency' elif self.lines[1].contains(evt)[0]: self.state = 'time' else: self.state = '' self.mouseInfo = (evt.xdata, evt.ydata, max(self.f0.value, .1), self.A.value) def mouseMotion(self, evt): if self.state == '': return x, y = evt.xdata, evt.ydata if x is None: # outside the axes return x0, y0, f0Init, AInit = self.mouseInfo self.A.set(AInit + (AInit * (y - y0) / y0), self) if self.state == 'frequency': self.f0.set(f0Init + (f0Init * (x - x0) / x0)) elif self.state == 'time': if (x - x0) / x0 != -1.: self.f0.set(1. / (1. / f0Init + (1. / f0Init * (x - x0) / x0))) def mouseUp(self, evt): self.state = '' def createPlots(self): # This method creates the subplots, waveforms and labels. # Later, when the waveforms or sliders are dragged, only the # waveform data will be updated (not here, but below in setKnob). if not hasattr(self, 'subplot1'): self.subplot1, self.subplot2 = self.figure.subplots(2) x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value) color = (1., 0., 0.) self.lines += self.subplot1.plot(x1, y1, color=color, linewidth=2) self.lines += self.subplot2.plot(x2, y2, color=color, linewidth=2) # Set some plot attributes self.subplot1.set_title( "Click and drag waveforms to change frequency and amplitude", fontsize=12) self.subplot1.set_ylabel("Frequency Domain Waveform X(f)", fontsize=8) self.subplot1.set_xlabel("frequency f", fontsize=8) self.subplot2.set_ylabel("Time Domain Waveform x(t)", fontsize=8) self.subplot2.set_xlabel("time t", fontsize=8) self.subplot1.set_xlim([-6, 6]) self.subplot1.set_ylim([0, 1]) self.subplot2.set_xlim([-2, 2]) self.subplot2.set_ylim([-2, 2]) self.subplot1.text(0.05, .95, r'$X(f) = \mathcal{F}\{x(t)\}$', verticalalignment='top', transform=self.subplot1.transAxes) self.subplot2.text(0.05, .95, r'$x(t) = a \cdot \cos(2\pi f_0 t) e^{-\pi t^2}$', verticalalignment='top', transform=self.subplot2.transAxes) def compute(self, f0, A): f = np.arange(-6., 6., 0.02) t = np.arange(-2., 2., 0.01) x = A * np.cos(2 * np.pi * f0 * t) * np.exp(-np.pi * t**2) X = A / 2 * \ (np.exp(-np.pi * (f - f0) ** 2) + np.exp(-np.pi * (f + f0) ** 2)) return f, X, t, x def setKnob(self, value): # Note, we ignore value arg here and just go by state of the params x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value) # update the data of the two waveforms self.lines[0].set(xdata=x1, ydata=y1) self.lines[1].set(xdata=x2, ydata=y2) # make the canvas draw its contents again with the new data self.canvas.draw()
class MainFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, title='Image Identifier', size=(500, 500)) # Dummy variables self.points = [] self.xmin = None self.xmax = None self.ymin = None self.ymax = None self.dimensions = None self.outfile_paths = [] self.outfile_xmin = [] self.outfile_ymin = [] self.outfile_xmax = [] self.outfile_ymax = [] # Panels graph_panel = wx.Panel(self) widget_panel = wx.Panel(self) # Plot stuff self.figure = Figure() self.axes = self.figure.add_subplot(111) self.canvas = FigureCanvas(graph_panel, wx.ID_ANY, self.figure) # Button stuff ok_button = wx.Button(widget_panel, id=wx.ID_ANY, label='Ok') cancel_button = wx.Button(widget_panel, id=wx.ID_ANY, label='Select Again') ok_button.Bind(wx.EVT_BUTTON, self.on_ok_button) cancel_button.Bind(wx.EVT_BUTTON, self.on_cancel_button) # Sizers gbs = wx.BoxSizer(wx.HORIZONTAL) gbs.Add(self.canvas, 1, wx.EXPAND) wbs = wx.BoxSizer(wx.HORIZONTAL) wbs.Add(ok_button, -1, wx.EXPAND) wbs.Add(cancel_button, -1, wx.EXPAND) bs = wx.BoxSizer(wx.VERTICAL) bs.Add(widget_panel, 1, wx.EXPAND) bs.Add(graph_panel, 2, wx.EXPAND) graph_panel.SetSizer(gbs) widget_panel.SetSizer(wbs) self.SetSizer(bs) # Call method to show image in plot self.index = 0 self.paths = self.handle_filenames() self.add_picture(self.paths[self.index]) # Connect clicking event self.canvas.mpl_connect('button_press_event', self.pick_point) def add_picture(self, pic_path): self.axes.clear() my_pic = cv2.imread(pic_path, cv2.IMREAD_COLOR) self.dimensions = my_pic.shape self.axes.imshow(my_pic) self.canvas.draw() def handle_filenames(self): cur_dir = os.getcwd() all_paths = os.listdir(cur_dir) paths = [] for pathname in all_paths: if pathname.endswith('.jpg'): paths.append(pathname) return paths def pick_point(self, event): if event.inaxes: x, y = event.xdata, event.ydata self.points.append([x, y]) if len(self.points) == 2: self.set_max_min() self.draw_box() def draw_box(self): self.axes.axvline( self.xmin, ymin=(self.dimensions[0] - self.ymin) / self.dimensions[0], ymax=(self.dimensions[0] - self.ymax) / self.dimensions[0], c='r') self.axes.axhline(self.ymin, xmin=self.xmin / self.dimensions[1], xmax=self.xmax / self.dimensions[1], c='r') self.axes.axvline( self.xmax, ymin=(self.dimensions[0] - self.ymin) / self.dimensions[0], ymax=(self.dimensions[0] - self.ymax) / self.dimensions[0], c='r') self.axes.axhline(self.ymax, xmin=self.xmin / self.dimensions[1], xmax=self.xmax / self.dimensions[1], c='r') self.canvas.draw() def set_max_min(self): x_val = [self.points[0][0], self.points[1][0]] y_val = [self.points[0][1], self.points[1][1]] self.xmin = int(round(min(x_val))) self.xmax = int(round(max(x_val))) self.ymin = int(round(min(y_val))) self.ymax = int(round(max(y_val))) def on_ok_button(self, event): print('Okay') self.outfile_paths.append(self.paths[self.index]) # Pass coordinates and data self.outfile_xmin.append(self.xmin) self.outfile_ymin.append(self.ymin) self.outfile_xmax.append(self.xmax) self.outfile_ymax.append(self.ymax) self.index += 1 if self.index < len(self.paths): # Clear variables and move to next picture self.points = [] self.xmin = None self.xmax = None self.ymin = None self.ymax = None self.add_picture(self.paths[self.index]) else: self.write_outfile() print( 'info.dat has been created in the current working directory.') def on_cancel_button(self, event): self.points = [] self.xmin = None self.xmax = None self.ymin = None self.ymax = None del self.axes.lines[:] self.canvas.draw() def write_outfile(self): outfile = open('info.dat', 'w') for i in range(len(self.outfile_paths)): outfile.write('{} 1 {} {} {} {}\n'.format( "positives/" + self.outfile_paths[i], self.outfile_xmin[i], self.outfile_ymin[i], self.outfile_xmax[i], self.outfile_ymax[i]))
class t_C_MatPlot(My_Control_Class): def __init__(self, *args, **kwargs): My_Control_Class.__init__(self, *args, **kwargs) # ************************************************************* # Create the panel with the plot controls # ************************************************************* self.Panel = wx.Panel(self.Dock) self.CB_Grid = wx.CheckBox(self.Panel, -1, "Grid", pos=(0, 5)) self.CP_Grid = wx.ColourPickerCtrl(self.Panel, -1, pos=(40, 1)) wx.StaticText(self.Panel, -1, "BackGround-", pos=(70, 5)) self.CP_BG = wx.ColourPickerCtrl(self.Panel, -1, pos=(130, 1)) self.CB_Axis = wx.CheckBox(self.Panel, -1, "Axis", pos=(160, 5)) self.CB_Legend = wx.CheckBox(self.Panel, -1, "Legend", pos=(210, 5)) self.CB_Polar = wx.CheckBox(self.Panel, -1, "Low Res", pos=(275, 5)) self.CB_FFT = wx.CheckBox(self.Panel, -1, "FFT", pos=(335, 5)) bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_BUTTON, (16, 16)) self.Button_ClipBoard = wx.BitmapButton(self.Panel, -1, bmp, pos=(375, 0)) self.Button_ClipBoard.SetToolTipString('Copy to ClipBoard') bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_BUTTON, (16, 16)) self.Button_Image = wx.BitmapButton(self.Panel, -1, bmp, pos=(405, 0)) self.Button_Image.SetToolTipString('Save as PNG-image') if self.Test: self.Spin = wx.SpinCtrl(self.Panel, wx.ID_ANY, min=1, max=5, pos=(435, 2), size=(40, 20)) self.Spin.SetToolTipString('Select Demo') # background color of the not used part of the button bar self.Dock.SetBackgroundColour(self.Panel.GetBackgroundColour()) # ************************************************************* # ************************************************************* # ************************************************************* # These parameters must be set before the figure is created # EASIER to set these parameters from rcParams, than from rc, # because you can use deep nested properties #rc ('figure.subplot', 'left' = 0.5) ## not accepted rcParams['figure.subplot.top'] = 0.95 rcParams['figure.subplot.bottom'] = 0.05 rcParams['figure.subplot.left'] = 0.1 rcParams['figure.subplot.right'] = 0.97 self.figure = Figure() self.Canvas = FigureCanvas(self.Dock, -1, self.figure) self.axes = self.figure.add_subplot(111) self.axes_2 = None self.lx = None # ************************************************************* # ************************************************************* # Try to reload the settings, otherwise set defaults # ************************************************************* self.Legends = ('signal 1', 'signal 2') self.SignalsX = [] self.SignalsY = [] self.Pseudo_Color = False if self.Test and self.Ini: print('piep1') self.Ini.Section = 'MatPlot' #line = self.Ini.Read ( 'Pars', '' ) self.Load_Settings(self.Ini) if self.Test: self.MatPlot_Example(self.Spin.GetValue()) else: self.MatPlot_Redraw() # ************************************************************* # ************************************************************* # ************************************************************* Sizer = wx.BoxSizer(wx.VERTICAL) Sizer.Add(self.Canvas, 1, wx.EXPAND) Sizer.Add(self.Panel, 0) self.Dock.SetSizer(Sizer) #Dock.Fit() # We need this for Ubuntu, and even then it works limited self.Dock.Bind(wx.EVT_SIZE, self._OnSize) # ************************************************************* # ************************************************************* # ************************************************************* self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnPolar, self.CP_Grid) self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnSet_CBs, self.CP_BG) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Grid) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Axis) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Legend) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnPolar, self.CB_Polar) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnFFT, self.CB_FFT) self.Button_Image.Bind(wx.EVT_BUTTON, self.MatPlot_OnSaveImage, self.Button_Image) self.Button_ClipBoard.Bind(wx.EVT_BUTTON, self.MatPlot_OnCopyClipBoard, self.Button_ClipBoard) if self.Test: self.Spin.Bind(wx.EVT_SPINCTRL, self.MatPlot_OnSpinEvent, self.Spin) self.Dock.Bind(wx.EVT_CLOSE, self.MatPlot_OnClose) #if not ( self.connect ) : self.Dock.connect = self.Canvas.mpl_connect('motion_notify_event', self.MatPlot_OnMotion) # ************************************************************* # ************************************************************* # We need this for Ubuntu, and even then it works limited # ************************************************************* def _OnSize(self, event): event.Skip() wx.CallAfter(self.MatPlot_Redraw) # ************************************************************* # ************************************************************* def Calculate(self): # input might be one of the following: # 1: <array> # 2: list = [ <array>, [ <signal name>, <signal color>, <linewidth> ] ] # # array might be one of the following: # A: a 1-dimensional array ==> y(x), x=equidistant # B: a 2-dimensional array, with second dimension = 2 ==> y = f(x) # C: a 2-dimensional array, with second dimension >> 6 ==> z = f(x,y) # we can either use signal, which is the input channel that has changed # or use the Bricks input channels, so we can use all of them at once self.SignalsX = [] self.SignalsY = [] self.Legends = [] # for test purposes, we don't have a brick but Test_Inputs try: Inputs = self.Brick.In except: Inputs = self.Test_Inputs for s, IVV in enumerate(Inputs[1:]): if IVV != None: #print 'MatPlot',s,len(IVV) if not ( operator.isSequenceType ( IVV ) ) or \ isinstance ( IVV, ndarray ): IVV = eval('[IVV]') #print 'no sequence' # determine the number of arrays # if exactly 2, special case: x,y pairs NA = 0 for IV in IVV: if isinstance(IV, ndarray): NA += 1 else: break #print 'NA',NA,IVV[0].shape # process all signals self.Pseudo_Color = False if IVV[0].ndim == 2: self.Pseudo_Color = True self.SignalsX.append(IVV[0]) elif NA == 1: L = len(IVV[0]) self.SignalsX.append(linspace(0, L - 1, L)) self.SignalsY.append(IVV[0]) elif NA == 2: self.SignalsX.append(IVV[0]) self.SignalsY.append(IVV[1]) else: self.SignalsX.append(IVV[0]) for i, IV in enumerate(IVV[1:NA]): self.SignalsY.append(IV) # add legends if NA == 1: if (len(IVV) > NA) and (len(IVV[NA]) > 0): self.Legends.append(IVV[NA][0]) else: self.Legends.append('Signal 1') for i, IV in enumerate(IVV[1:NA]): if (len(IVV) > NA) and (len(IVV[NA]) > i): self.Legends.append(IVV[NA][i]) else: self.Legends.append('Signal ' + str(i + 1)) #print 'Legends',self.Legends self.MatPlot_ReCreate_Plot() #print 'MatPlot recreated' # ************************************************************* # ************************************************************* def MatPlot_ReCreate_Plot(self): # BUG, "hold" doesn't work in polar, therefore create a new figure # helps sometimes .... for polar plot ## LUKT NIET MEER rcParams [ 'grid.color' ] = self.Color_2_MatPlot ( self.CP_Grid.GetColour () ) self.figure.clear() self.lx = None if not (self.Pseudo_Color): self.CB_Polar.SetLabel('-Polar') if self.CB_FFT.GetValue(): config = 212 else: config = 111 self.axes = self.figure.add_subplot(config, polar=self.CB_Polar.GetValue()) for i, SX in enumerate(self.SignalsY): self.axes.plot( self.SignalsX[0], self.SignalsY[i], ) if self.CB_FFT.GetValue(): self.axes_2 = self.figure.add_subplot( 211, polar=self.CB_Polar.GetValue()) for i, SX in enumerate(self.SignalsY): self.axes_2.psd( self.SignalsY[i], 512, 1, #detrend = mlab.detrend_linear, #doesn't work #detrend = mlab.detrend_mean, #doesn't work detrend=mlab.detrend_none, #window = mlab.window_none ) #weird scaling window=mlab.window_hanning) # doesn't work: # self.axes_2.xlabel = 'aap' # self.axes_2.axis ( 0, 0, 50, -50) else: self.axes_2 = None else: # Pseudo color self.CB_FFT.Hide() self.CB_Polar.SetLabel('-Low Res') self.axes = self.figure.add_subplot(111) if self.CB_Polar.GetValue(): cmap = cm.get_cmap('jet', 10) # 10 discrete colors else: cmap = cm.jet #cmap = cm.gray # IMPORTANT, setting the size explictly, # prevents rescaling which sometimes occurs when crosshair is drawn s = self.SignalsX[0].shape try: # SignalsX might not be available yet im = self.axes.imshow(self.SignalsX[0], cmap=cmap, extent=(0, s[0], 0, s[1])) #im.set_interpolation ( 'nearest' ) # and there are a lot more !! #im.set_interpolation ( 'bicubic' ) im.set_interpolation('bilinear') self.figure.colorbar(im) except: pass self.axes.hold(True) # needed for measurement cursor if self.axes_2: self.axes_2.hold(True) self.MatPlot_Redraw() # ************************************************************* # ************************************************************* def MatPlot_Redraw(self): color = self.CP_BG.GetColour() color = self.Color_2_MatPlot(color) self.axes.set_axis_bgcolor(color) if self.axes_2: self.axes_2.set_axis_bgcolor(color) self.figure.set_facecolor(color) self.figure.set_edgecolor(color) if self.CB_Axis.GetValue(): self.axes.set_axis_on() if self.axes_2: self.axes_2.set_axis_on() else: self.axes.set_axis_off() if self.axes_2: self.axes_2.set_axis_off() color = self.CP_Grid.GetColour() color = self.Color_2_MatPlot(color) self.axes.grid(self.CB_Grid.GetValue()) if self.axes_2: self.axes_2.grid(self.CB_Grid.GetValue()) # setting the grid color sometimes generates an exception # this seems to happen completely random ???? try: if self.CB_Grid.GetValue(): self.axes.grid(color=color) if self.axes_2: self.axes_2.grid(color=color) except: pass # Polar doesn't support legend (use figlegend) if self.Pseudo_Color or not (self.CB_Polar.GetValue()): if self.CB_Legend.GetValue(): self.axes.legend(self.Legends) else: self.axes.legend_ = None # FFT plot: no legend if self.axes_2: self.axes_2.legend_ = None self.Canvas.draw() # ************************************************************* # create an example image # ************************************************************* def MatPlot_Example(self, Example): self.Test_Inputs = [None] if Example == 1: # Sine x = arange(0.0, 3.0, 0.01) y = sin(2 * pi * x) elif Example == 2: # SPIRAL t = arange(0, 10 * pi, 0.1) x = t * sin(t) y = t * cos(t) elif Example == 3: # CARDIOID t = arange(0, 2 * pi, 0.1) x = (1 + cos(t)) * cos(t) y = (1 + cos(t)) * sin(t) elif Example == 4: # SPIROGRAPH phi = linspace(0, 4, 100) #r=sin(phi*pi) # r = sin(cos(tan(phi))) x = phi y = 20 * r elif Example == 5: # Pseudo Color def _func(x, y): return (1 - x / 2 + x**5 + y**3) * exp(-x**2 - y**2) dx, dy = 0.05, 0.05 x = arange(-3.0, 3.0, dx) y = arange(-3.0, 3.0, dy) X, Y = meshgrid(x, y) self.Test_Inputs.append(_func(X, Y)) if len(self.Test_Inputs) == 1: temp = [] temp.append(x) temp.append(y) self.Test_Inputs.append(temp) self.Calculate() # ************************************************************* # ************************************************************* def MatPlot_OnMotion(self, event): if self.CB_Polar.GetValue() and not (self.Pseudo_Color): return x, y = event.x, event.y # check if within an "axes" but not in a "bar-axes" if event.inaxes and isinstance(event.inaxes, matplotlib.axes.Subplot): x, y = event.xdata, event.ydata if not (self.lx): self.minx, self.maxx = event.inaxes.get_xlim() self.miny, self.maxy = event.inaxes.get_ylim() """ self.lx, = self.axes.plot ( ( self.minx, self.maxx ), ( y, y ), 'k-' ) # the horiz line self.ly, = self.axes.plot ( ( x, x ), ( self.miny, self.maxy ), 'k-' ) # the vert line self.meas_txt = self.axes.text ( 0.02, 0.02, 'x=%1.2f, y=%1.2f'% ( x, y ), transform = self.axes.transAxes ) """ self.lx, = event.inaxes.plot((self.minx, self.maxx), (y, y), 'k-') # the horiz line self.ly, = event.inaxes.plot((x, x), (self.miny, self.maxy), 'k-') # the vert line self.meas_txt = event.inaxes.text( 0.02, 0.02, 'x=%1.2f, y=%1.2f' % (x, y), transform=event.inaxes.transAxes) else: # update the crosshair positions self.lx.set_data((self.minx, self.maxx), (y, y)) self.ly.set_data((x, x), (self.miny, self.maxy)) self.meas_txt.set_text('x=%1.2f, y=%1.2f' % (x, y)) else: # Hide the cross hair if self.lx: self.lx.set_data((x, x), (y, y)) self.ly.set_data((x, x), (y, y)) self.meas_txt.set_text('') self.lx = None self.Canvas.draw() # ************************************************************* # ************************************************************* def MatPlot_OnSet_CBs(self, event): self.MatPlot_Redraw() # ************************************************************* # ************************************************************* def MatPlot_OnPolar(self, event): if self.CB_Polar.GetValue(): self.CB_FFT.Hide() else: self.CB_FFT.Show() self.MatPlot_ReCreate_Plot() # ************************************************************* # ************************************************************* def MatPlot_OnFFT(self, event): if self.CB_FFT.GetValue(): self.CB_Polar.Hide() else: self.CB_Polar.Show() self.MatPlot_ReCreate_Plot() # ************************************************************* # ************************************************************* def MatPlot_OnSpinEvent(self, event): Example = event.GetInt() self.MatPlot_Example(Example) # ************************************************************* # ************************************************************* def MatPlot_OnCopyClipBoard(self, event): #canvas = FigureCanvasWxAgg(...) self.Canvas.Copy_to_Clipboard(event=event) # ************************************************************* # ************************************************************* def MatPlot_OnSaveImage(self, event): file = Ask_File_For_Save(os.getcwd(), FileTypes='*.png', Title='Save Plot as PNG-image') if file: self.figure.savefig(file) # ************************************************************* # Set Grid color of all backgrounds # Doing this gives huges problems, # therefor we accept that in the polar # ************************************************************* """ def OnGridColor ( self, event ) : rcParams [ 'grid.color' ] = self.Color_2_MatPlot ( self.CP_Grid.GetColour () ) # Because we need to reload the resources, # we force it by recreating to the total plot self.Sizer.Remove ( self.Canvas ) self.figure = Figure () self.Canvas = FigureCanvas ( self.Dock, -1, self.figure ) self.lx = None self.Sizer.Prepend ( self.Canvas, 1, wx.EXPAND ) self.Sizer.Layout () self.MatPlot_Example ( self.Spin.GetValue () ) """ # ************************************************************* # MatPlot accepts RGB colors in relative range 0..1, # alpha blend is also not accepted # ************************************************************* def Color_2_MatPlot(self, color): # if already in MatPlot format, just return the same value if isinstance(color, float) or isinstance(color[0], float): return color # else limit to 3 elements in the range 0.0 ... 1.0 kleur = [] for c in color[:3]: kleur.append(c / 255.0) return kleur # ************************************************************* # MatPlot accepts RGB colors in relative range 0..1, # alpha blend is also not accepted # ************************************************************* def MatPlot_2_Color(self, color): # if already in normal format, just return the same value if isinstance(color, wx.Color): return color if isinstance(color, basestring): try: color = float(color) except: return color # named color probably if isinstance(color, float): i = int(color * 255) kleur = [i, i, i] else: kleur = [] if isinstance(color[0], float): for c in color[:3]: kleur.append(int(255 * c)) else: kleur = color[:3] kleur = wx.Color(*kleur) return kleur # ************************************************************* # ************************************************************* def MatPlot_OnClose(self, event): if self.Ini and self.Test: self.Ini.Section = 'MatPlot' self.Ini.Write('Pos', self.Dock.GetPosition()) self.Ini.Write('Size', self.Dock.GetSize()) self.Save_Settings(self.Ini) event.Skip() # ************************************************************* # ************************************************************* def Save_Settings(self, ini, key=None): if ini: line = [] line.append(tuple(self.CP_BG.GetColour())) line.append(tuple(self.CP_Grid.GetColour())) line.append(self.CB_Grid.GetValue()) line.append(self.CB_Axis.GetValue()) line.append(self.CB_Legend.GetValue()) line.append(self.CB_Polar.GetValue()) line.append(self.CB_FFT.GetValue()) if self.Test: line.append(self.Spin.GetValue()) if not (key): key = 'CS_' v3print('MatPlot SAVE', key, '=', line) line = ini.Write(key, line) # ************************************************************* # ************************************************************* def Load_Settings(self, ini, key=None): #print 'llkwp',line if not (key): key = 'CS_' line = ini.Read(key, '') if line: self.CP_BG.SetColour(line[0]) self.CP_Grid.SetColour(line[1]) self.CB_Grid.SetValue(line[2]) self.CB_Axis.SetValue(line[3]) self.CB_Legend.SetValue(line[4]) self.CB_Polar.SetValue(line[5]) self.CB_FFT.SetValue(line[6]) if self.Test: self.Spin.SetValue(line[7]) self.MatPlot_ReCreate_Plot()
def __init__(self, *args, **kwargs): My_Control_Class.__init__(self, *args, **kwargs) # ************************************************************* # Create the panel with the plot controls # ************************************************************* self.Panel = wx.Panel(self.Dock) self.CB_Grid = wx.CheckBox(self.Panel, -1, "Grid", pos=(0, 5)) self.CP_Grid = wx.ColourPickerCtrl(self.Panel, -1, pos=(40, 1)) wx.StaticText(self.Panel, -1, "BackGround-", pos=(70, 5)) self.CP_BG = wx.ColourPickerCtrl(self.Panel, -1, pos=(130, 1)) self.CB_Axis = wx.CheckBox(self.Panel, -1, "Axis", pos=(160, 5)) self.CB_Legend = wx.CheckBox(self.Panel, -1, "Legend", pos=(210, 5)) self.CB_Polar = wx.CheckBox(self.Panel, -1, "Low Res", pos=(275, 5)) self.CB_FFT = wx.CheckBox(self.Panel, -1, "FFT", pos=(335, 5)) bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_BUTTON, (16, 16)) self.Button_ClipBoard = wx.BitmapButton(self.Panel, -1, bmp, pos=(375, 0)) self.Button_ClipBoard.SetToolTipString('Copy to ClipBoard') bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_BUTTON, (16, 16)) self.Button_Image = wx.BitmapButton(self.Panel, -1, bmp, pos=(405, 0)) self.Button_Image.SetToolTipString('Save as PNG-image') if self.Test: self.Spin = wx.SpinCtrl(self.Panel, wx.ID_ANY, min=1, max=5, pos=(435, 2), size=(40, 20)) self.Spin.SetToolTipString('Select Demo') # background color of the not used part of the button bar self.Dock.SetBackgroundColour(self.Panel.GetBackgroundColour()) # ************************************************************* # ************************************************************* # ************************************************************* # These parameters must be set before the figure is created # EASIER to set these parameters from rcParams, than from rc, # because you can use deep nested properties #rc ('figure.subplot', 'left' = 0.5) ## not accepted rcParams['figure.subplot.top'] = 0.95 rcParams['figure.subplot.bottom'] = 0.05 rcParams['figure.subplot.left'] = 0.1 rcParams['figure.subplot.right'] = 0.97 self.figure = Figure() self.Canvas = FigureCanvas(self.Dock, -1, self.figure) self.axes = self.figure.add_subplot(111) self.axes_2 = None self.lx = None # ************************************************************* # ************************************************************* # Try to reload the settings, otherwise set defaults # ************************************************************* self.Legends = ('signal 1', 'signal 2') self.SignalsX = [] self.SignalsY = [] self.Pseudo_Color = False if self.Test and self.Ini: print('piep1') self.Ini.Section = 'MatPlot' #line = self.Ini.Read ( 'Pars', '' ) self.Load_Settings(self.Ini) if self.Test: self.MatPlot_Example(self.Spin.GetValue()) else: self.MatPlot_Redraw() # ************************************************************* # ************************************************************* # ************************************************************* Sizer = wx.BoxSizer(wx.VERTICAL) Sizer.Add(self.Canvas, 1, wx.EXPAND) Sizer.Add(self.Panel, 0) self.Dock.SetSizer(Sizer) #Dock.Fit() # We need this for Ubuntu, and even then it works limited self.Dock.Bind(wx.EVT_SIZE, self._OnSize) # ************************************************************* # ************************************************************* # ************************************************************* self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnPolar, self.CP_Grid) self.Dock.Bind(wx.EVT_COLOURPICKER_CHANGED, self.MatPlot_OnSet_CBs, self.CP_BG) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Grid) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Axis) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnSet_CBs, self.CB_Legend) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnPolar, self.CB_Polar) self.Dock.Bind(wx.EVT_CHECKBOX, self.MatPlot_OnFFT, self.CB_FFT) self.Button_Image.Bind(wx.EVT_BUTTON, self.MatPlot_OnSaveImage, self.Button_Image) self.Button_ClipBoard.Bind(wx.EVT_BUTTON, self.MatPlot_OnCopyClipBoard, self.Button_ClipBoard) if self.Test: self.Spin.Bind(wx.EVT_SPINCTRL, self.MatPlot_OnSpinEvent, self.Spin) self.Dock.Bind(wx.EVT_CLOSE, self.MatPlot_OnClose) #if not ( self.connect ) : self.Dock.connect = self.Canvas.mpl_connect('motion_notify_event', self.MatPlot_OnMotion)
def __init__(self,parent,id,title,dm): wx.Frame.__init__(self, parent, -1, title, size=signifWindowSize) if platform != "darwin": icon = wx.Icon("LogoIcon.ico", wx.BITMAP_TYPE_ICO) self.SetIcon(icon) self.signifNumBins=signifNumBins self.dm = dm self.Bind(wx.EVT_CLOSE,self.OnEnd) self.WindowParent=parent sizer=wx.BoxSizer(wx.VERTICAL) panel = wx.Panel(self) # -------------- Begin of parameter selector sbParam = wx.StaticBox(panel, label="Parameter") sbParamSizer = wx.StaticBoxSizer(sbParam, wx.VERTICAL) sbParamSizer1 = wx.BoxSizer(wx.HORIZONTAL) sbParamSizer2 = wx.BoxSizer(wx.HORIZONTAL) AllBandsOrig = self.dm.GetVisibleBands()[0] AllBands=list(AllBandsOrig) AllBands.remove("Heart rate") bandsRB=[] for band in AllBands: if len(bandsRB)==0: tmp = wx.RadioButton(panel, label=band, style=wx.RB_GROUP) tmp.SetValue(True) else: tmp = wx.RadioButton(panel, label=band) bandsRB.append(tmp) if len(bandsRB)<=6: sbParamSizer1.Add(tmp, wx.EXPAND) else: sbParamSizer2.Add(tmp, wx.EXPAND) sbParamSizer.Add(sbParamSizer1,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) sbParamSizer.Add(sbParamSizer2,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) sizer.Add(sbParamSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) for eachRB in bandsRB: self.Bind(wx.EVT_RADIOBUTTON,self.OnParam,eachRB) self.ActiveParam = AllBands[0] # -------------- End of parameter selector # -------------- Begin of tags selector sbTags = wx.StaticBox(panel, label="Episodes") sbTagsSizer = wx.StaticBoxSizer(sbTags, wx.HORIZONTAL) # tagsRB = [] self.AllTags = self.dm.GetVisibleEpisodes()[0] self.ActiveTagLeft = self.AllTags[0] self.ActiveTagRight = None self.dm.SetSignifPlotParams(self.ActiveTagLeft,self.ActiveTagRight,self.ActiveParam) self.cbComboLeft=wx.ComboBox(panel, choices=self.AllTags, value=self.ActiveTagLeft, style=wx.CB_DROPDOWN|wx.CB_READONLY ) sbTagsSizer.Add(self.cbComboLeft,flag=wx.ALL | wx.EXPAND, border=borderSmall) self.Bind(wx.EVT_COMBOBOX, self.OnComboLeft, id=self.cbComboLeft.GetId()) sbTagsSizer.AddStretchSpacer(prop=1) ChoicesRight = ["Outside "+self.ActiveTagLeft]+self.AllTags ChoicesRight.remove(self.ActiveTagLeft) self.cbComboRight=wx.ComboBox(panel, choices=ChoicesRight, value="Outside "+self.ActiveTagLeft, style=wx.CB_DROPDOWN|wx.CB_READONLY ) sbTagsSizer.Add(self.cbComboRight,flag=wx.ALL | wx.EXPAND, border=borderSmall) self.Bind(wx.EVT_COMBOBOX, self.OnComboRight, id=self.cbComboRight.GetId()) sizer.Add(sbTagsSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) # -------------- End of tags selector # -------------- Begin of figure if ColoredBGPlots: self.fig = matplotlib.figure.Figure((5.0, 4.0),facecolor=SignifBGColor) else: self.fig = matplotlib.figure.Figure((5.0, 4.0)) self.fig.subplots_adjust(left=0.05, bottom=0.18, right=0.98, top=0.92, wspace=0.20, hspace=0.15) self.canvas = FigureCanvas(panel, -1, self.fig) self.axes = self.fig.add_subplot(111) sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) # -------------- End of figure # -------------- Begin of textbox and buttons hbox = wx.BoxSizer(wx.HORIZONTAL) self.textOutput = wx.TextCtrl(panel, id, 'Information', size=(400, 75), style=wx.TE_READONLY|wx.TE_MULTILINE|wx.TE_RICH2) self.textOutput.SetFont(wx.Font(11, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)); hbox.Add(self.textOutput, 1, wx.LEFT | wx.TOP | wx.GROW) endButton = wx.Button(panel, -1, "Close", size=buttonSizeSignif) self.Bind(wx.EVT_BUTTON, self.OnEnd, id=endButton.GetId()) endButton.SetToolTip(wx.ToolTip("Click to close window")) hbox.Add(endButton, 0, border=borderBig, flag=wx.LEFT|wx.ALIGN_BOTTOM) sizer.Add(hbox, 0, flag=wx.EXPAND|wx.ALL, border=borderBig) # -------------- End of textbox and buttons panel.SetSizer(sizer) self.SetMinSize(signifWindowMinSize) # self.sb = self.CreateStatusBar() # self.sb.SetStatusText(self.sbSignifText) # self.canvas.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress) self.Show(True) self.Layout() self.Refresh()
class PlotPanel(BasePanel): """ MatPlotlib 2D plot as a wx.Panel, suitable for embedding in any wx.Frame. This does provide a right-click popup menu for configuration, zooming, saving an image of the figure, and Ctrl-C for copy-image-to-clipboard. For more features, see PlotFrame, which embeds a PlotPanel and also provides, a Menu, StatusBar, and Printing support. """ def __init__(self, parent, size=(700, 450), dpi=150, axisbg=None, facecolor=None, fontsize=9, trace_color_callback=None, output_title='plot', with_data_process=True, theme=None, **kws): self.trace_color_callback = trace_color_callback BasePanel.__init__(self, parent, output_title=output_title, size=size, **kws) self.conf = PlotConfig(panel=self, theme=theme, with_data_process=with_data_process) self.data_range = {} self.win_config = None self.cursor_callback = None self.lasso_callback = None self.cursor_mode = 'zoom' self.parent = parent self.figsize = (size[0]*1.0/dpi, size[1]*1.0/dpi) self.dpi = dpi self.conf.facecolor = ifnotNone(axisbg, self.conf.facecolor) self.conf.facecolor = ifnotNone(facecolor, self.conf.facecolor) # axesmargins : margins in px left/top/right/bottom self.axesmargins = (30, 30, 30, 30) self.BuildPanel() self.conf.user_limits = {} # [None, None, None, None] self.data_range = {} self.conf.zoom_lims = [] self.conf.axes_traces = {} self.use_dates = False self.dates_style = None def plot(self, xdata, ydata, side='left', title=None, xlabel=None, ylabel=None, y2label=None, use_dates=False, dates_style=None, **kws): """ create a new plot of x/y data, clearing any existing plot on the panel """ allaxes = self.fig.get_axes() if len(allaxes) > 1: for ax in allaxes[1:]: if ax in self.data_range: self.data_range.pop(ax) self.fig.delaxes(ax) self.data_range = {} self.conf.zoom_lims = [] self.conf.axes_traces = {} self.clear() axes = self.axes if side == 'right': axes = self.get_right_axes() self.conf.reset_lines() self.conf.yscale = 'linear' self.conf.user_limits[axes] = 4*[None] if xlabel is not None: self.set_xlabel(xlabel, delay_draw=True) if ylabel is not None: self.set_ylabel(ylabel, delay_draw=True) if y2label is not None: self.set_y2label(y2label, delay_draw=True) if title is not None: self.set_title(title, delay_draw=True) self.dates_style = ifnotNone(dates_style, self.dates_style) self.use_dates = ifnotNone(use_dates, self.use_dates) return self.oplot(xdata, ydata, side=side, **kws) def oplot(self, xdata, ydata, side='left', label=None, xlabel=None, ylabel=None, y2label=None, title=None, dy=None, ylog_scale=None, xlog_scale=None, grid=None, xmin=None, xmax=None, ymin=None, ymax=None, color=None, style=None, drawstyle=None, linewidth=2, marker=None, markersize=None, refresh=True, show_legend=None, legend_loc='best', legend_on=True, delay_draw=False, bgcolor=None, framecolor=None, gridcolor=None, labelfontsize=None, titlefontsize=None, legendfontsize=None, fullbox=None, axes_style=None, zorder=None, viewpad=None, theme=None, use_dates=None, dates_style=None, **kws): """ basic plot method, adding to an existing display """ self.cursor_mode = 'zoom' conf = self.conf conf.plot_type = 'lineplot' axes = self.axes if theme is not None: conf.set_theme(theme=theme) if side == 'right': axes = self.get_right_axes() # set y scale to log/linear if ylog_scale is not None: conf.yscale = {False:'linear', True:'log'}[ylog_scale] if xlog_scale is not None: conf.xscale = {False:'linear', True:'log'}[xlog_scale] axes.xaxis.set_major_formatter(FuncFormatter(self.xformatter)) self.dates_style = ifnotNone(dates_style, self.dates_style) self.use_dates = ifnotNone(use_dates, self.use_dates) if isinstance(xdata[0], datetime): self.use_dates = True if self.use_dates: # date handling options to get xdate to mpl dates # 1. xdate are in datetime: convert to mpl dates # 2. xdata are strings: parse with datestr2num # 3. xdata are floats: # a) dates_styles=='dates': use directly # b) else: convert as unix timestamp to mpl dates x0 = xdata[0] dstyle = self.dates_style if dstyle is None: dstyle = '' if isinstance(x0, datetime): xdata = dates.date2num(xdata) elif isinstance(x0, str) or dstyle.lower().startswith('str'): xdata = dates.datestr2num(xdata) elif not dstyle.lower().startswith('dates'): xdata = dates.epoch2num(xdata) linewidth = ifNone(linewidth, 2) conf.viewpad = ifnotNone(viewpad, conf.viewpad) if xlabel is not None: self.set_xlabel(xlabel, delay_draw=delay_draw) if ylabel is not None: self.set_ylabel(ylabel, delay_draw=delay_draw) if y2label is not None: self.set_y2label(y2label, delay_draw=delay_draw) if title is not None: self.set_title(title, delay_draw=delay_draw) if show_legend is not None: conf.set_legend_location(legend_loc, legend_on) conf.show_legend = show_legend conf.show_grid = ifnotNone(grid, conf.show_grid) # set data range for this trace # datarange = [min(xdata), max(xdata), min(ydata), max(ydata)] if axes not in conf.user_limits: conf.user_limits[axes] = [None, None, None, None] conf.user_limits[axes][0] = ifnotNone(xmin, conf.user_limits[axes][0]) conf.user_limits[axes][1] = ifnotNone(xmax, conf.user_limits[axes][1]) conf.user_limits[axes][2] = ifnotNone(ymin, conf.user_limits[axes][2]) conf.user_limits[axes][3] = ifnotNone(ymax, conf.user_limits[axes][3]) if axes == self.axes: axes.yaxis.set_major_formatter(FuncFormatter(self.yformatter)) else: axes.yaxis.set_major_formatter(FuncFormatter(self.y2formatter)) zorder = ifNone(zorder, 5*(conf.ntrace+1)) if axes not in conf.axes_traces: conf.axes_traces[axes] = [] conf.axes_traces[axes].append(conf.ntrace) conf.gridcolor = ifnotNone(gridcolor, conf.gridcolor) conf.facecolor = ifnotNone(bgcolor, conf.facecolor) if framecolor is not None: self.canvas.figure.set_facecolor(framecolor) conf.set_trace_zorder(zorder, delay_draw=True) if color: conf.set_trace_color(color, delay_draw=True) if style: conf.set_trace_style(style, delay_draw=True) if marker: conf.set_trace_marker(marker, delay_draw=True) if linewidth is not None: conf.set_trace_linewidth(linewidth, delay_draw=True) if markersize is not None: conf.set_trace_markersize(markersize, delay_draw=True) if drawstyle is not None: conf.set_trace_drawstyle(drawstyle, delay_draw=True) if dy is None: _lines = axes.plot(xdata, ydata, drawstyle=drawstyle, zorder=zorder) else: _lines = axes.errorbar(xdata, ydata, yerr=dy, zorder=zorder) if axes not in conf.data_save: conf.data_save[axes] = [] conf.data_save[axes].append((xdata, ydata)) if conf.show_grid and axes == self.axes: # I'm sure there's a better way... for i in axes.get_xgridlines() + axes.get_ygridlines(): i.set_color(conf.gridcolor) i.set_zorder(-100) axes.grid(True) else: axes.grid(False) if (self.conf.xscale == 'log' or self.conf.yscale == 'log'): self.set_logscale(xscale=self.conf.xscale, yscale=self.conf.yscale, delay_draw=delay_draw) if label is None: label = 'trace %i' % (conf.ntrace+1) conf.set_trace_label(label, delay_draw=True) needs_relabel = False if labelfontsize is not None: conf.labelfont.set_size(labelfontsize) needs_relabel = True if titlefontsize is not None: conf.titlefont.set_size(titlefontsize) needs_relabel = True if legendfontsize is not None: conf.legendfont.set_size(legendfontsize) needs_relabel = True if conf.ntrace < len(conf.lines): conf.lines[conf.ntrace] = _lines else: conf.init_trace(conf.ntrace, 'black', 'solid') conf.lines.append(_lines) # now set plot limits: if not delay_draw: self.set_viewlimits() if refresh: conf.refresh_trace(conf.ntrace) needs_relabel = True if conf.show_legend and not delay_draw: conf.draw_legend() if needs_relabel and not delay_draw: conf.relabel() # axes style ('box' or 'open') conf.axes_style = 'box' if fullbox is not None and not fullbox: conf.axes_style = 'open' if axes_style in ('open', 'box', 'bottom'): conf.axes_style = axes_style conf.set_axes_style(delay_draw=delay_draw) if not delay_draw: self.draw() self.canvas.Refresh() conf.ntrace = conf.ntrace + 1 return _lines def plot_many(self, datalist, side='left', title=None, xlabel=None, ylabel=None, **kws): """ plot many traces at once, taking a list of (x, y) pairs """ def unpack_tracedata(tdat, **kws): if (isinstance(tdat, dict) and 'xdata' in tdat and 'ydata' in tdat): xdata = tdat.pop('xdata') ydata = tdat.pop('ydata') out = kws out.update(tdat) elif isinstance(tdat, (list, tuple)): out = kws xdata = tdat[0] ydata = tdat[1] return (xdata, ydata, out) opts = dict(side=side, title=title, xlabel=xlabel, ylabel=ylabel, delay_draw=True) opts.update(kws) x0, y0, opts = unpack_tracedata(datalist[0], **opts) self.plot(x0, y0, **opts) for dat in datalist[1:]: x, y, opts = unpack_tracedata(dat, delay_draw=True) self.oplot(x, y, **opts) self.reset_formats() conf = self.conf if conf.show_legend: conf.draw_legend() conf.relabel() self.draw() self.canvas.Refresh() def add_text(self, text, x, y, side='left', size=None, rotation=None, ha='left', va='center', family=None, **kws): """add text at supplied x, y position """ axes = self.axes if side == 'right': axes = self.get_right_axes() dynamic_size = False if size is None: size = self.conf.legendfont.get_size() dynamic_size = True t = axes.text(x, y, text, ha=ha, va=va, size=size, rotation=rotation, family=family, **kws) self.conf.added_texts.append((dynamic_size, t)) self.draw() def add_arrow(self, x1, y1, x2, y2, side='left', shape='full', color='black', width=0.01, head_width=0.03, overhang=0, **kws): """add arrow supplied x, y position""" dx, dy = x2-x1, y2-y1 axes = self.axes if side == 'right': axes = self.get_right_axes() axes.arrow(x1, y1, dx, dy, shape=shape, length_includes_head=True, fc=color, edgecolor=color, width=width, head_width=head_width, overhang=overhang, **kws) self.draw() def scatterplot(self, xdata, ydata, label=None, size=10, color=None, edgecolor=None, selectcolor=None, selectedge=None, xlabel=None, ylabel=None, y2label=None, xmin=None, xmax=None, ymin=None, ymax=None, viewpad=None, title=None, grid=None, callback=None, **kw): if xlabel is not None: self.set_xlabel(xlabel) if ylabel is not None: self.set_ylabel(ylabel) if y2label is not None: self.set_y2label(y2label) if title is not None: self.set_title(title) if grid is not None: self.conf.show_grid = grid if callback is not None: self.lasso_callback = callback self.conf.plot_type = 'scatter' self.cursor_mode = 'lasso' if color is not None: self.conf.scatter_normalcolor = color if edgecolor is not None: self.conf.scatter_normaledge = edgecolor if selectcolor is not None: self.conf.scatter_selectcolor = selectcolor if selectedge is not None: self.conf.scatter_selectedge = selectedge if viewpad is not None: self.conf.viewpad = viewpad axes = self.axes self.conf.user_limits[axes] = [xmin, xmax, ymin, ymax] self.conf.axes_traces = {axes: [0]} self.conf.set_trace_label('scatterplot') # self.conf.set_trace_datarange((min(xdata), max(xdata), # min(ydata), max(ydata))) self.conf.scatter_xdata = xdata self.conf.scatter_ydata = ydata self.axes.scatter(xdata, ydata, c=self.conf.scatter_normalcolor, edgecolors=self.conf.scatter_normaledge) if self.conf.show_grid: for i in axes.get_xgridlines()+axes.get_ygridlines(): i.set_color(self.conf.gridcolor) i.set_zorder(-30) axes.grid(True) else: axes.grid(False) xrange = max(xdata) - min(xdata) yrange = max(ydata) - min(ydata) xmin = min(xdata) - xrange/25.0 xmax = max(xdata) + xrange/25.0 ymin = min(ydata) - yrange/25.0 ymax = max(ydata) + yrange/25.0 axes.set_xlim((xmin, xmax), emit=True) axes.set_ylim((ymin, ymax), emit=True) self.set_viewlimits() self.draw() def lassoHandler(self, vertices): conf = self.conf if self.conf.plot_type == 'scatter': xd, yd = conf.scatter_xdata, conf.scatter_ydata sdat = list(zip(xd, yd)) oldmask = conf.scatter_mask try: self.axes.scatter(xd[where(oldmask)], yd[where(oldmask)], s=conf.scatter_size, c=conf.scatter_normalcolor, edgecolors=conf.scatter_normaledge) except IndexError: self.axes.scatter(xd, yd, s=conf.scatter_size, c=conf.scatter_normalcolor, edgecolors=conf.scatter_normaledge) mask = conf.scatter_mask = inside_poly(vertices, sdat) pts = nonzero(mask)[0] self.axes.scatter(xd[where(mask)], yd[where(mask)], s=conf.scatter_size, c=conf.scatter_selectcolor, edgecolors=conf.scatter_selectedge) else: xdata = self.axes.lines[0].get_xdata() ydata = self.axes.lines[0].get_ydata() sdat = [(x, y) for x, y in zip(xdata, ydata)] mask = inside_poly(vertices,sdat) pts = nonzero(mask)[0] self.lasso = None self.draw() # self.canvas.draw_idle() if (self.lasso_callback is not None and hasattr(self.lasso_callback , '__call__')): self.lasso_callback(data = sdat, selected=pts, mask=mask) def set_xylims(self, limits, axes=None, side='left'): "set user-defined limits and apply them" if axes is None: axes = self.axes if side == 'right': axes = self.get_right_axes() self.conf.user_limits[axes] = list(limits) self.unzoom_all() def set_viewlimits(self): """updates xy limits of a plot based on current data, user defined limits, and any zoom level """ self.reset_formats() self.conf.set_viewlimits() def get_viewlimits(self, axes=None): if axes is None: axes = self.axes xmin, xmax = axes.get_xlim() ymin, ymax = axes.get_ylim() return (xmin, xmax, ymin, ymax) def clear(self): """ clear plot """ for ax in self.fig.get_axes(): ax.cla() self.conf.ntrace = 0 self.conf.xlabel = '' self.conf.ylabel = '' self.conf.y2label = '' self.conf.title = '' self.conf.data_save = {} def reset_config(self): """reset configuration to defaults.""" self.conf.set_defaults() def unzoom(self, event=None, **kws): """ zoom out 1 level, or to full data range """ self.reset_formats() self.conf.unzoom(full=False) def unzoom_all(self, event=None): """ zoom out full data range """ self.reset_formats() self.conf.unzoom(full=True) def process_data(self, event=None, expr=None): if expr in self.conf.data_expressions: self.conf.data_expr = expr self.conf.process_data() self.draw() if expr is None: expr = '' if self.conf.data_deriv: if expr is None: expr = 'y' expr = "deriv(%s)" % expr self.write_message("plotting %s" % expr, panel=0) def toggle_deriv(self, evt=None, value=None): "toggle derivative of data" if value is None: self.conf.data_deriv = not self.conf.data_deriv expr = self.conf.data_expr or '' if self.conf.data_deriv: expr = "deriv(%s)" % expr self.write_message("plotting %s" % expr, panel=0) self.conf.process_data() def set_logscale(self, event=None, xscale='linear', yscale='linear', delay_draw=False): "set log or linear scale for x, y axis" self.conf.set_logscale(xscale=xscale, yscale=yscale, delay_draw=delay_draw) def toggle_legend(self, evt=None, show=None): "toggle legend display" if show is None: show = not self.conf.show_legend self.conf.show_legend = show self.conf.draw_legend() def toggle_grid(self, evt=None, show=None): "toggle grid display" if show is None: show = not self.conf.show_grid self.conf.enable_grid(show) def configure(self, event=None): """show configuration frame""" if self.win_config is not None: try: self.win_config.Raise() except: self.win_config = None if self.win_config is None: self.win_config = PlotConfigFrame(parent=self, config=self.conf, trace_color_callback=self.trace_color_callback) self.win_config.Raise() #### ## create GUI #### def BuildPanel(self): """ builds basic GUI panel and popup menu""" self.fig = Figure(self.figsize, dpi=self.dpi) # 1 axes for now self.gridspec = GridSpec(1,1) self.axes = self.fig.add_subplot(self.gridspec[0], facecolor=self.conf.facecolor) self.canvas = FigureCanvas(self, -1, self.fig) self.canvas.SetClientSize((self.figsize[0]*self.dpi, self.figsize[1]*self.dpi)) self.canvas.SetMinSize((100, 100)) self.printer.canvas = self.canvas self.set_bg(self.conf.framecolor) self.conf.canvas = self.canvas self.canvas.SetCursor(wxCursor(wx.CURSOR_CROSS)) self.canvas.mpl_connect("pick_event", self.__onPickEvent) # overwrite ScalarFormatter from ticker.py here: self.axes.xaxis.set_major_formatter(FuncFormatter(self.xformatter)) self.axes.yaxis.set_major_formatter(FuncFormatter(self.yformatter)) # This way of adding to sizer allows resizing sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.canvas, 2, wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND, 0) # self.SetAutoLayout(True) self.autoset_margins() self.SetSizer(sizer) self.SetSize(self.GetBestVirtualSize()) canvas_draw = self.canvas.draw def draw(*args, **kws): self.autoset_margins() canvas_draw(*args, **kws) self.canvas.draw = draw self.addCanvasEvents() def BuildPopup(self): # build pop-up menu for right-click display self.popup_menu = popup = wx.Menu() MenuItem(self, popup, 'Configure', '', self.configure) MenuItem(self, popup, 'Save Image', '', self.save_figure) popup.AppendSeparator() MenuItem(self, popup, 'Undo Zoom/Pan', '', self.unzoom) MenuItem(self, popup, 'Zoom all the way out', '', self.unzoom_all) popup.AppendSeparator() MenuItem(self, popup, 'Zoom X and Y', '', partial(self.onZoomStyle, style='both x and y'), kind=wx.ITEM_RADIO, checked=True) MenuItem(self, popup, 'Zoom X Only', '', partial(self.onZoomStyle, style='x only'), kind=wx.ITEM_RADIO) MenuItem(self, popup, 'Zoom Y Only', '', partial(self.onZoomStyle, style='y only'), kind=wx.ITEM_RADIO) def onZoomStyle(self, event=None, style='both x and y'): self.conf.zoom_style = style def _updateCanvasDraw(self): """ Overload of the draw function that update axes position before each draw""" fn = self.canvas.draw def draw2(*a,**k): self._updateGridSpec() return fn(*a,**k) self.canvas.draw = draw2 def get_default_margins(self): """get default margins""" trans = self.fig.transFigure.inverted().transform # Static margins l, t, r, b = self.axesmargins (l, b), (r, t) = trans(((l, b), (r, t))) # Extent dl, dt, dr, db = 0, 0, 0, 0 for i, ax in enumerate(self.fig.get_axes()): (x0, y0),(x1, y1) = ax.get_position().get_points() try: (ox0, oy0), (ox1, oy1) = ax.get_tightbbox(self.canvas.get_renderer()).get_points() (ox0, oy0), (ox1, oy1) = trans(((ox0 ,oy0),(ox1 ,oy1))) dl = min(0.2, max(dl, (x0 - ox0))) dt = min(0.2, max(dt, (oy1 - y1))) dr = min(0.2, max(dr, (ox1 - x1))) db = min(0.2, max(db, (y0 - oy0))) except: pass return (l + dl, t + dt, r + dr, b + db) def autoset_margins(self): """auto-set margins left, bottom, right, top according to the specified margins (in pixels) and axes extent (taking into account labels, title, axis) """ if not self.conf.auto_margins: return # coordinates in px -> [0,1] in figure coordinates trans = self.fig.transFigure.inverted().transform # Static margins if not self.use_dates: self.conf.margins = l, t, r, b = self.get_default_margins() self.gridspec.update(left=l, top=1-t, right=1-r, bottom=b) # Axes positions update for ax in self.fig.get_axes(): try: ax.update_params() except ValueError: pass ax.set_position(ax.figbox) def draw(self): self.canvas.draw() def update_line(self, trace, xdata, ydata, side='left', draw=False, update_limits=True): """ update a single trace, for faster redraw """ x = self.conf.get_mpl_line(trace) x.set_data(xdata, ydata) # datarange = [xdata.min(), xdata.max(), ydata.min(), ydata.max()] # self.conf.set_trace_datarange(datarange, trace=trace) axes = self.axes if side == 'right': axes = self.get_right_axes() if update_limits: self.set_viewlimits() if draw: self.draw() def get_figure(self): return self.fig def __onPickEvent(self, event=None): """pick events""" legline = event.artist trace = self.conf.legend_map.get(legline, None) visible = True if trace is not None and self.conf.hidewith_legend: line, legline, legtext = trace visible = not line.get_visible() line.set_visible(visible) if visible: legline.set_zorder(10.00) legline.set_alpha(1.00) legtext.set_zorder(10.00) legtext.set_alpha(1.00) else: legline.set_alpha(0.50) legtext.set_alpha(0.50) #### ## GUI events #### def report_leftdown(self, event=None): if event is None: return ex, ey = event.x, event.y msg = '' try: x, y = self.axes.transData.inverted().transform((ex, ey)) except: x, y = event.xdata, event.ydata if x is not None and y is not None: msg = "X,Y= %g, %g" % (x, y) if len(self.fig.get_axes()) > 1: ax2 = self.fig.get_axes()[1] try: x2, y2 = ax2.transData.inverted().transform((ex, ey)) msg = "X,Y,Y2= %g, %g, %g" % (x, y, y2) except: pass nsbar = getattr(self, 'nstatusbar', 1) self.write_message(msg, panel=max(0, nsbar - 2)) if (self.cursor_callback is not None and hasattr(self.cursor_callback , '__call__')): self.cursor_callback(x=event.xdata, y=event.ydata)
class myFrame(wx.Frame): def __init__(self): self.para_0 = {'SEQ': 'ON', 'SEQ_N': 200, 'polarity': 'negative'} #self.dos_0 = dso.Dso(self.para_0) super().__init__(None, -1, title='PALS', size=(1200, 800)) # self.para_0['C1_TRLV'] = -0.1 self.para_0['C2_TRLV'] = -0.1 self.dos_0 = dso.Dso(self.para_0) # self.e_rg = { 'c1': [0., 100.], 'c2': [0., 100.], 'c1_amp': [0., 5.], 'c2_amp': [0., 5.] } self.lt_start_l = 0. self.lt_start_r = 300. self.start_fraction = 0.15 self.lt_stop_l = 0. self.lt_stop_r = 300. self.stop_fraction = 0.2 self.cps = 0. self.lt_bins = 100 self.lt_l = -10.0 self.lt_r = 10.0 self.total_counts = 0 self.counts_set = 1000000 self.note1 = wx.Notebook(self) #建立page self.scorePanel = wx.Panel(self.note1) self.scorePanel_lt = wx.Panel(self.note1) self.note1.AddPage(self.scorePanel, "Energy") self.note1.AddPage(self.scorePanel_lt, "LifeTime") #能量显示窗口 self.e_gridsizer = wx.GridBagSizer(2, 2) self.scorePanel.SetSizer(self.e_gridsizer) # self.box1 = wx.ListBox(self.scorePanel,size=(800, 500)) # self.drawHistF = Figure(figsize=(8, 5), dpi=100) # self.drawHistCanvas = FigureCanvas(self.box1, -1, self.drawHistF) # self.drawHistCanvas.draw() self.box1 = wx.ListBox(self.scorePanel, size=(800, 500)) self.e_gridsizer.Add(self.box1, pos=(0, 0), flag=wx.EXPAND) self.box2 = wx.Panel(self.scorePanel) self.e_gridsizer.Add(self.box2, pos=(0, 1), flag=wx.EXPAND) self.box3 = wx.Panel(self.scorePanel) self.e_gridsizer.Add(self.box3, span=(1, 2), pos=(1, 0), flag=wx.EXPAND) self.scorePanel.Fit() self.drawHistF = Figure(figsize=(8, 5), dpi=100) self.drawHistCanvas = FigureCanvas(self.box1, -1, self.drawHistF) self.drawHistCanvas.draw() #右侧区域 # self.box2 = wx.Panel(self.scorePanel, pos=(810, 0), size=(370, 500)) # self.but1 = wx.Button(self.box2, 0, 'start', pos=(10, 10), size=(100, 50)) # self.but2 = wx.Button(self.box2, 0, 'stop', pos=(120, 10), size=(100, 50)) # self.but3 = wx.Button(self.box2, 0, 'clear', pos=(230, 10), size=(100, 50)) # self.but1.Bind(wx.EVT_BUTTON, self.start_but) # self.but2.Bind(wx.EVT_BUTTON, self.stop_but) # self.but3.Bind(wx.EVT_BUTTON, self.energy_clear) self.eb2_gridsizer = wx.GridBagSizer(8, 3) self.box2.SetSizer(self.eb2_gridsizer) self.but1 = wx.Button(self.box2, -1, 'start') self.but2 = wx.Button(self.box2, -1, 'stop') self.but3 = wx.Button(self.box2, -1, 'clear') self.but1.Bind(wx.EVT_BUTTON, self.start_but) self.but2.Bind(wx.EVT_BUTTON, self.stop_but) self.but3.Bind(wx.EVT_BUTTON, self.energy_clear) self.eb2_gridsizer.Add(self.but1, pos=(0, 0), flag=wx.EXPAND) self.eb2_gridsizer.Add(self.but2, pos=(0, 1), flag=wx.EXPAND) self.eb2_gridsizer.Add(self.but3, pos=(0, 2), flag=wx.EXPAND) # 下方区域 self.eb3_gridsizer = wx.GridBagSizer(1, 4) self.box3.SetSizer(self.eb3_gridsizer) self.eb3_c1_panel = wx.Panel(self.box3) self.eb3_gridsizer.Add(self.eb3_c1_panel, pos=(0, 0), flag=wx.EXPAND) self.eb3_c2_panel = wx.Panel(self.box3) self.eb3_gridsizer.Add(self.eb3_c2_panel, pos=(0, 1), flag=wx.EXPAND) # energy_c1_set self.eb3c1_gridsizer = wx.GridBagSizer(6, 4) self.eb3_c1_panel.SetSizer(self.eb3c1_gridsizer) self.eb3c1_title = wx.StaticText(self.eb3_c1_panel, -1, label='channel 1', style=wx.ALIGN_CENTER) self.font1 = wx.Font(15, wx.ROMAN, wx.NORMAL, wx.NORMAL) self.eb3c1_title.SetFont(self.font1) self.eb3c1_gridsizer.Add(self.eb3c1_title, span=(1, 4), pos=(0, 0), flag=wx.EXPAND) # self.eb3c1_trlv = wx.TextCtrl(self.eb3_c1_panel, -1, str(self.para_0['C1_TRLV']), style=wx.TE_CENTER) self.eb3c1_gridsizer.Add(self.eb3c1_trlv, span=(1, 2), pos=(1, 1), flag=wx.EXPAND) self.eb3c1_but1 = wx.Button(self.eb3_c1_panel, -1, 'Set') self.eb3c1_gridsizer.Add(self.eb3c1_but1, span=(1, 1), pos=(1, 3), flag=wx.EXPAND) self.eb3c1_but1.Bind(wx.EVT_BUTTON, self.e_c1_set_trlv) self.eb3c1_trlv_text = wx.StaticText(self.eb3_c1_panel, -1, 'c1_trlv', style=wx.ALIGN_CENTER) self.eb3c1_trlv_text.SetFont(self.font1) self.eb3c1_gridsizer.Add(self.eb3c1_trlv_text, span=(1, 1), pos=(1, 0), flag=wx.EXPAND) # self.eb3c1_erg_l_text = wx.StaticText(self.eb3_c1_panel, -1, 'energy_l', style=wx.ALIGN_CENTER) self.eb3c1_erg_l_text.SetFont(self.font1) self.eb3c1_gridsizer.Add(self.eb3c1_erg_l_text, span=(1, 1), pos=(2, 0), flag=wx.EXPAND) self.eb3c1_erg_l = wx.TextCtrl(self.eb3_c1_panel, -1, str(self.e_rg['c1'][0]), style=wx.TE_CENTER) self.eb3c1_gridsizer.Add(self.eb3c1_erg_l, span=(1, 1), pos=(2, 1), flag=wx.EXPAND) self.eb3c1_erg_r_text = wx.StaticText(self.eb3_c1_panel, -1, 'energy_r', style=wx.ALIGN_CENTER) self.eb3c1_erg_r_text.SetFont(self.font1) self.eb3c1_gridsizer.Add(self.eb3c1_erg_r_text, span=(1, 1), pos=(2, 2), flag=wx.EXPAND) self.eb3c1_erg_r = wx.TextCtrl(self.eb3_c1_panel, -1, str(self.e_rg['c1'][1]), style=wx.TE_CENTER) self.eb3c1_gridsizer.Add(self.eb3c1_erg_r, span=(1, 1), pos=(2, 3), flag=wx.EXPAND) self.eb3c1_amp_l_text = wx.StaticText(self.eb3_c1_panel, -1, 'amp_l', style=wx.ALIGN_CENTER) self.eb3c1_amp_l_text.SetFont(self.font1) self.eb3c1_gridsizer.Add(self.eb3c1_amp_l_text, span=(1, 1), pos=(3, 0), flag=wx.EXPAND) self.eb3c1_amp_l = wx.TextCtrl(self.eb3_c1_panel, -1, str(self.e_rg['c1_amp'][0]), style=wx.TE_CENTER) self.eb3c1_gridsizer.Add(self.eb3c1_amp_l, span=(1, 1), pos=(3, 1), flag=wx.EXPAND) self.eb3c1_amp_r_text = wx.StaticText(self.eb3_c1_panel, -1, 'amp_r', style=wx.ALIGN_CENTER) self.eb3c1_amp_r_text.SetFont(self.font1) self.eb3c1_gridsizer.Add(self.eb3c1_amp_r_text, span=(1, 1), pos=(3, 2), flag=wx.EXPAND) self.eb3c1_amp_r = wx.TextCtrl(self.eb3_c1_panel, -1, str(self.e_rg['c1_amp'][1]), style=wx.TE_CENTER) self.eb3c1_gridsizer.Add(self.eb3c1_amp_r, span=(1, 1), pos=(3, 3), flag=wx.EXPAND) self.eb3c1_but2 = wx.Button(self.eb3_c1_panel, -1, 'Set') self.eb3c1_gridsizer.Add(self.eb3c1_but2, span=(1, 4), pos=(4, 0), flag=wx.EXPAND) self.eb3c1_but2.Bind(wx.EVT_BUTTON, self.e_c1_set_range) # energy_c2_set self.eb3c2_gridsizer = wx.GridBagSizer(6, 4) self.eb3_c2_panel.SetSizer(self.eb3c2_gridsizer) self.eb3c2_title = wx.StaticText(self.eb3_c2_panel, -1, label='channel 1', style=wx.ALIGN_CENTER) self.eb3c2_title.SetFont(self.font1) self.eb3c2_gridsizer.Add(self.eb3c2_title, span=(1, 4), pos=(0, 0), flag=wx.EXPAND) # self.eb3c2_trlv = wx.TextCtrl(self.eb3_c2_panel, -1, str(self.para_0['C2_TRLV']), style=wx.TE_CENTER) self.eb3c2_gridsizer.Add(self.eb3c2_trlv, span=(1, 2), pos=(1, 1), flag=wx.EXPAND) self.eb3c2_but1 = wx.Button(self.eb3_c2_panel, -1, 'Set') self.eb3c2_gridsizer.Add(self.eb3c2_but1, span=(1, 1), pos=(1, 3), flag=wx.EXPAND) self.eb3c2_but1.Bind(wx.EVT_BUTTON, self.e_c2_set_trlv) self.eb3c2_trlv_text = wx.StaticText(self.eb3_c2_panel, -1, 'c2_trlv', style=wx.ALIGN_CENTER) self.eb3c2_trlv_text.SetFont(self.font1) self.eb3c2_gridsizer.Add(self.eb3c2_trlv_text, span=(1, 1), pos=(1, 0), flag=wx.EXPAND) # self.eb3c2_erg_l_text = wx.StaticText(self.eb3_c2_panel, -1, 'energy_l', style=wx.ALIGN_CENTER) self.eb3c2_erg_l_text.SetFont(self.font1) self.eb3c2_gridsizer.Add(self.eb3c2_erg_l_text, span=(1, 1), pos=(2, 0), flag=wx.EXPAND) self.eb3c2_erg_l = wx.TextCtrl(self.eb3_c2_panel, -1, str(self.e_rg['c2'][0]), style=wx.TE_CENTER) self.eb3c2_gridsizer.Add(self.eb3c2_erg_l, span=(1, 1), pos=(2, 1), flag=wx.EXPAND) self.eb3c2_erg_r_text = wx.StaticText(self.eb3_c2_panel, -1, 'energy_r', style=wx.ALIGN_CENTER) self.eb3c2_erg_r_text.SetFont(self.font1) self.eb3c2_gridsizer.Add(self.eb3c2_erg_r_text, span=(1, 1), pos=(2, 2), flag=wx.EXPAND) self.eb3c2_erg_r = wx.TextCtrl(self.eb3_c2_panel, -1, str(self.e_rg['c2'][1]), style=wx.TE_CENTER) self.eb3c2_gridsizer.Add(self.eb3c2_erg_r, span=(1, 1), pos=(2, 3), flag=wx.EXPAND) self.eb3c2_amp_l_text = wx.StaticText(self.eb3_c2_panel, -1, 'amp_l', style=wx.ALIGN_CENTER) self.eb3c2_amp_l_text.SetFont(self.font1) self.eb3c2_gridsizer.Add(self.eb3c2_amp_l_text, span=(1, 1), pos=(3, 0), flag=wx.EXPAND) self.eb3c2_amp_l = wx.TextCtrl(self.eb3_c2_panel, -1, str(self.e_rg['c2_amp'][0]), style=wx.TE_CENTER) self.eb3c2_gridsizer.Add(self.eb3c2_amp_l, span=(1, 1), pos=(3, 1), flag=wx.EXPAND) self.eb3c2_amp_r_text = wx.StaticText(self.eb3_c2_panel, -1, 'amp_r', style=wx.ALIGN_CENTER) self.eb3c2_amp_r_text.SetFont(self.font1) self.eb3c2_gridsizer.Add(self.eb3c2_amp_r_text, span=(1, 1), pos=(3, 2), flag=wx.EXPAND) self.eb3c2_amp_r = wx.TextCtrl(self.eb3_c2_panel, -1, str(self.e_rg['c2_amp'][1]), style=wx.TE_CENTER) self.eb3c2_gridsizer.Add(self.eb3c2_amp_r, span=(1, 1), pos=(3, 3), flag=wx.EXPAND) self.eb3c2_but2 = wx.Button(self.eb3_c2_panel, -1, 'Set') self.eb3c2_gridsizer.Add(self.eb3c2_but2, span=(1, 4), pos=(4, 0), flag=wx.EXPAND) self.eb3c2_but2.Bind(wx.EVT_BUTTON, self.e_c2_set_range) # self.e_panel3_c2 = wx.Panel(self.scorePanel) # self.p3c2_gridsizer = wx.GridBagSizer(5, 4) # self.buttest3 = wx.Button(self.e_panel3_c2, 0, 'test') # self.buttest4 = wx.Button(self.e_panel3_c2, 0, 'test0') # self.p3c2_gridsizer.Add(self.buttest3, span=(1, 4), pos=(0, 0), flag=wx.EXPAND) # self.p3c2_gridsizer.Add(self.buttest4, pos=(4, 2), flag=wx.EXPAND) # self.e_panel3_c2.SetSizer(self.p3c2_gridsizer) # self.e_panel3_c2.Fit() # lt_page self.lt_gridsizer = wx.GridBagSizer(2, 2) self.scorePanel_lt.SetSizer(self.lt_gridsizer) # self.lt_box1 = wx.ListBox(self.scorePanel_lt,size=(800, 500)) # self.drawHistF = Figure(figsize=(8, 5), dpi=100) # self.drawHistCanvas = FigureCanvas(self.lt_box1, -1, self.drawHistF) # self.drawHistCanvas.draw() self.lt_box1 = wx.ListBox(self.scorePanel_lt, size=(800, 500)) self.lt_gridsizer.Add(self.lt_box1, pos=(0, 0), flag=wx.EXPAND) self.lt_box2 = wx.Panel(self.scorePanel_lt) self.lt_gridsizer.Add(self.lt_box2, pos=(0, 1), flag=wx.EXPAND) self.lt_box3 = wx.Panel(self.scorePanel_lt) self.lt_gridsizer.Add(self.lt_box3, span=(1, 2), pos=(1, 0), flag=wx.EXPAND) self.scorePanel_lt.Fit() self.drawHistF_lt = Figure(figsize=(8, 5), dpi=100) self.drawHistCanvas_lt = FigureCanvas(self.lt_box1, -1, self.drawHistF_lt) self.drawHistCanvas_lt.draw() # lt右侧区域 # self.lt_box2 = wx.Panel(self.scorePanel, pos=(810, 0), size=(370, 500)) # self.lt_but1 = wx.Button(self.lt_box2, 0, 'start', pos=(10, 10), size=(100, 50)) # self.lt_but2 = wx.Button(self.lt_box2, 0, 'stop', pos=(120, 10), size=(100, 50)) # self.lt_but3 = wx.Button(self.lt_box2, 0, 'clear', pos=(230, 10), size=(100, 50)) # self.lt_but1.Bind(wx.EVT_BUTTON, self.start_but) # self.lt_but2.Bind(wx.EVT_BUTTON, self.stop_but) # self.lt_but3.Bind(wx.EVT_BUTTON, self.energy_clear) self.ltb2_gridsizer = wx.GridBagSizer(8, 3) self.lt_box2.SetSizer(self.ltb2_gridsizer) self.lt_but1 = wx.Button(self.lt_box2, -1, 'start') self.lt_but2 = wx.Button(self.lt_box2, -1, 'stop') self.lt_but3 = wx.Button(self.lt_box2, -1, 'clear') self.lt_but1.Bind(wx.EVT_BUTTON, self.lt_start_but) self.lt_but2.Bind(wx.EVT_BUTTON, self.lt_stop_but) self.lt_but3.Bind(wx.EVT_BUTTON, self.lt_clear) self.lt_cps_stext = wx.StaticText(self.lt_box2, -1, 'cps', style=wx.ALIGN_CENTER) self.lt_cps_stext.SetFont(self.font1) self.lt_cps_text = wx.TextCtrl(self.lt_box2, -1, str(self.cps), style=wx.TE_CENTER) self.lt_counts_stext = wx.StaticText(self.lt_box2, -1, 'counts', style=wx.ALIGN_CENTER) self.lt_counts_stext.SetFont(self.font1) self.lt_counts_text = wx.TextCtrl(self.lt_box2, -1, str(self.total_counts), style=wx.TE_CENTER) self.lt_but_save = wx.Button(self.lt_box2, -1, 'save') self.lt_but_save.Bind(wx.EVT_BUTTON, self.save_file) self.ltb2_gridsizer.Add(self.lt_but1, pos=(0, 0), flag=wx.EXPAND) self.ltb2_gridsizer.Add(self.lt_but2, pos=(0, 1), flag=wx.EXPAND) self.ltb2_gridsizer.Add(self.lt_but3, pos=(0, 2), flag=wx.EXPAND) self.ltb2_gridsizer.Add(self.lt_cps_stext, pos=(1, 0), flag=wx.EXPAND) self.ltb2_gridsizer.Add(self.lt_cps_text, pos=(1, 1), flag=wx.EXPAND) self.ltb2_gridsizer.Add(self.lt_counts_stext, pos=(2, 0), flag=wx.EXPAND) self.ltb2_gridsizer.Add(self.lt_counts_text, pos=(2, 1), flag=wx.EXPAND) self.ltb2_gridsizer.Add(self.lt_but_save, pos=(3, 0), flag=wx.EXPAND) self.lt_box2.Fit() # 下方区域 self.ltb3_gridsizer = wx.GridBagSizer(1, 4) self.lt_box3.SetSizer(self.ltb3_gridsizer) self.ltb3_c1_panel = wx.Panel(self.lt_box3) self.ltb3_gridsizer.Add(self.ltb3_c1_panel, pos=(0, 0), flag=wx.EXPAND) self.ltb3_c2_panel = wx.Panel(self.lt_box3) self.ltb3_gridsizer.Add(self.ltb3_c2_panel, pos=(0, 1), flag=wx.EXPAND) # lt_c1_set self.ltb3c1_gridsizer = wx.GridBagSizer(7, 4) self.ltb3_c1_panel.SetSizer(self.ltb3c1_gridsizer) self.ltb3c1_title = wx.StaticText(self.ltb3_c1_panel, -1, label='start_channel', style=wx.ALIGN_CENTER) self.ltb3c1_title.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_title, span=(1, 5), pos=(0, 0), flag=wx.EXPAND) self.ltb3c1_startdown_text = wx.StaticText(self.ltb3_c1_panel, -1, 'down', style=wx.ALIGN_CENTER) self.ltb3c1_startdown_text.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_startdown_text, span=(1, 1), pos=(1, 0), flag=wx.EXPAND) self.ltb3c1_startdown = wx.TextCtrl(self.ltb3_c1_panel, -1, str(self.lt_start_l), style=wx.TE_CENTER) self.ltb3c1_gridsizer.Add(self.ltb3c1_startdown, span=(1, 1), pos=(1, 1), flag=wx.EXPAND) self.ltb3c1_startup_text = wx.StaticText(self.ltb3_c1_panel, -1, 'up', style=wx.ALIGN_CENTER) self.ltb3c1_startup_text.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_startup_text, span=(1, 1), pos=(1, 2), flag=wx.EXPAND) self.ltb3c1_startup = wx.TextCtrl(self.ltb3_c1_panel, -1, str(self.lt_start_r), style=wx.TE_CENTER) self.ltb3c1_gridsizer.Add(self.ltb3c1_startup, span=(1, 1), pos=(1, 3), flag=wx.EXPAND) self.ltb3c1_startfrac_text = wx.StaticText(self.ltb3_c1_panel, -1, 'fraction', style=wx.ALIGN_CENTER) self.ltb3c1_startfrac_text.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_startfrac_text, span=(1, 2), pos=(2, 0), flag=wx.EXPAND) self.ltb3c1_startfrac = wx.TextCtrl(self.ltb3_c1_panel, -1, str(self.start_fraction), style=wx.TE_CENTER) self.ltb3c1_gridsizer.Add(self.ltb3c1_startfrac, span=(1, 2), pos=(2, 2), flag=wx.EXPAND) self.ltb3c1_title = wx.StaticText(self.ltb3_c1_panel, -1, label='stop_channel', style=wx.ALIGN_CENTER) self.ltb3c1_title.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_title, span=(1, 5), pos=(3, 0), flag=wx.EXPAND) self.ltb3c1_stopdown_text = wx.StaticText(self.ltb3_c1_panel, -1, 'down', style=wx.ALIGN_CENTER) self.ltb3c1_stopdown_text.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_stopdown_text, span=(1, 1), pos=(4, 0), flag=wx.EXPAND) self.ltb3c1_stopdown = wx.TextCtrl(self.ltb3_c1_panel, -1, str(self.lt_stop_l), style=wx.TE_CENTER) self.ltb3c1_gridsizer.Add(self.ltb3c1_stopdown, span=(1, 1), pos=(4, 1), flag=wx.EXPAND) self.ltb3c1_stopup_text = wx.StaticText(self.ltb3_c1_panel, -1, 'up', style=wx.ALIGN_CENTER) self.ltb3c1_stopup_text.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_stopup_text, span=(1, 1), pos=(4, 2), flag=wx.EXPAND) self.ltb3c1_stopup = wx.TextCtrl(self.ltb3_c1_panel, -1, str(self.lt_stop_r), style=wx.TE_CENTER) self.ltb3c1_gridsizer.Add(self.ltb3c1_stopup, span=(1, 1), pos=(4, 3), flag=wx.EXPAND) self.ltb3c1_stopfrac_text = wx.StaticText(self.ltb3_c1_panel, -1, 'fraction', style=wx.ALIGN_CENTER) self.ltb3c1_stopfrac_text.SetFont(self.font1) self.ltb3c1_gridsizer.Add(self.ltb3c1_stopfrac_text, span=(1, 2), pos=(5, 0), flag=wx.EXPAND) self.ltb3c1_stopfrac = wx.TextCtrl(self.ltb3_c1_panel, -1, str(self.stop_fraction), style=wx.TE_CENTER) self.ltb3c1_gridsizer.Add(self.ltb3c1_stopfrac, span=(1, 2), pos=(5, 2), flag=wx.EXPAND) self.ltb3c1_but1 = wx.Button(self.ltb3_c1_panel, -1, 'set', size=(200, 30)) self.ltb3c1_but1.Bind(wx.EVT_BUTTON, self.lt_ch_set) self.ltb3c1_gridsizer.Add(self.ltb3c1_but1, span=(1, 2), pos=(6, 1), flag=wx.EXPAND) # lt_box3_c2 self.ltb3c2_gridsizer = wx.GridBagSizer(7, 4) self.ltb3_c2_panel.SetSizer(self.ltb3c2_gridsizer) self.ltb3c2_title = wx.StaticText(self.ltb3_c2_panel, -1, label='lifetime_spectrum', style=wx.ALIGN_CENTER) self.ltb3c2_title.SetFont(self.font1) self.ltb3c2_gridsizer.Add(self.ltb3c2_title, span=(1, 5), pos=(0, 0), flag=wx.EXPAND) self.ltb3c2_sp_left_text = wx.StaticText(self.ltb3_c2_panel, -1, 'sp_left', style=wx.ALIGN_CENTER) self.ltb3c2_sp_left_text.SetFont(self.font1) self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_left_text, span=(1, 1), pos=(1, 0), flag=wx.EXPAND) self.ltb3c2_sp_left = wx.TextCtrl(self.ltb3_c2_panel, -1, str(self.lt_l), style=wx.TE_CENTER) self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_left, span=(1, 1), pos=(1, 1), flag=wx.EXPAND) self.ltb3c2_sp_right_text = wx.StaticText(self.ltb3_c2_panel, -1, 'sp_right', style=wx.ALIGN_CENTER) self.ltb3c2_sp_right_text.SetFont(self.font1) self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_right_text, span=(1, 1), pos=(1, 2), flag=wx.EXPAND) self.ltb3c2_sp_right = wx.TextCtrl(self.ltb3_c2_panel, -1, str(self.lt_r), style=wx.TE_CENTER) self.ltb3c2_gridsizer.Add(self.ltb3c2_sp_right, span=(1, 1), pos=(1, 3), flag=wx.EXPAND) self.ltb3c2_bins_text = wx.StaticText(self.ltb3_c2_panel, -1, 'bins', style=wx.ALIGN_CENTER) self.ltb3c2_bins_text.SetFont(self.font1) self.ltb3c2_gridsizer.Add(self.ltb3c2_bins_text, span=(1, 2), pos=(2, 0), flag=wx.EXPAND) self.ltb3c2_bins = wx.TextCtrl(self.ltb3_c2_panel, -1, str(self.lt_bins), style=wx.TE_CENTER) self.ltb3c2_gridsizer.Add(self.ltb3c2_bins, span=(1, 2), pos=(2, 2), flag=wx.EXPAND) self.ltb3c2_counts_text = wx.StaticText(self.ltb3_c2_panel, -1, 'counts', style=wx.ALIGN_CENTER) self.ltb3c2_counts_text.SetFont(self.font1) self.ltb3c2_gridsizer.Add(self.ltb3c2_counts_text, span=(1, 2), pos=(3, 0), flag=wx.EXPAND) self.ltb3c2_counts = wx.TextCtrl(self.ltb3_c2_panel, -1, str(self.counts_set), style=wx.TE_CENTER) self.ltb3c2_gridsizer.Add(self.ltb3c2_counts, span=(1, 2), pos=(3, 2), flag=wx.EXPAND) self.ltb3c2_but1 = wx.Button(self.ltb3_c2_panel, -1, 'set', size=(200, 30)) self.ltb3c2_but1.Bind(wx.EVT_BUTTON, self.lt_sp_set) self.ltb3c2_gridsizer.Add(self.ltb3c2_but1, span=(1, 2), pos=(4, 1), flag=wx.EXPAND) # 参数 self.m = 3.0 self.energy_c1 = [] self.amp_c1 = [] self.energy_c2 = [] self.amp_c2 = [] self.lifetime = [] self.wave0 = [] self.wave1 = [] self.lt_spe = [] self.e_start_but = 0 self.lt_start_but_switch = 0 def start_but(self, event): if self.e_start_but == 0: self.dos_0.open() self.run_loop() self.e_start_but = 1 def stop_but(self, event): self.dos_0.close() self.e_start_but = 0 def energy_clear(self, event): e_c_box = wx.MessageDialog(None, u"是否真的要清除显示能谱?", u"请确认", style=wx.OK | wx.CANCEL) if e_c_box.ShowModal() == wx.ID_OK: self.energy_c1 = [] self.amp_c1 = [] self.energy_c2 = [] self.amp_c2 = [] self.drawHistF.clf() self.drawHistCanvas.draw() def lt_start_but(self, event): if self.e_start_but == 0: self.dos_0.open() self.run_loop_lt() self.e_start_but = 1 def lt_stop_but(self, event): self.dos_0.close() self.e_start_but = 0 def lt_clear(self, event): e_c_box = wx.MessageDialog(None, u"是否真的要清除显示寿命谱?", u"请确认", style=wx.OK | wx.CANCEL) if e_c_box.ShowModal() == wx.ID_OK: self.lifetime = [] self.drawHistF_lt.clf() self.drawHistCanvas_lt.draw() self.total_counts = 0 def e_c1_set_trlv(self, event): str0 = self.eb3c1_trlv.GetValue() self.para_0['C1_TRLV'] = float(str0) self.dos_0.setDSO('C1:TRLV ' + str(self.para_0['C1_TRLV'])) def e_c1_set_range(self, event): str0 = float(self.eb3c1_erg_l.GetValue()) str1 = float(self.eb3c1_erg_r.GetValue()) str2 = float(self.eb3c1_amp_l.GetValue()) str3 = float(self.eb3c1_amp_r.GetValue()) if str0 >= str1 or str2 >= str3: e_c_box = wx.MessageBox("能谱范围左侧应小于右侧", "Error") else: self.e_rg['c1'][0] = str0 self.e_rg['c1'][1] = str1 self.e_rg['c1_amp'][0] = str2 self.e_rg['c1_amp'][1] = str3 def e_c2_set_trlv(self, event): str0 = self.eb3c2_trlv.GetValue() self.para_0['C2_TRLV'] = float(str0) self.dos_0.setDSO('C2:TRLV ' + str(self.para_0['C2_TRLV'])) def e_c2_set_range(self, event): str0 = float(self.eb3c2_erg_l.GetValue()) str1 = float(self.eb3c2_erg_r.GetValue()) str2 = float(self.eb3c2_amp_l.GetValue()) str3 = float(self.eb3c2_amp_r.GetValue()) if str0 >= str1 or str2 >= str3: e_c_box = wx.MessageBox("能谱范围左侧应小于右侧", "Error") else: self.e_rg['c2'][0] = str0 self.e_rg['c2'][1] = str1 self.e_rg['c2_amp'][0] = str2 self.e_rg['c2_amp'][1] = str3 def lt_ch_set(self, event): str0 = float(self.ltb3c1_startdown.GetValue()) str1 = float(self.ltb3c1_startup.GetValue()) str2 = float(self.ltb3c1_stopdown.GetValue()) str3 = float(self.ltb3c1_stopup.GetValue()) str4 = float(self.ltb3c1_startfrac.GetValue()) str5 = float(self.ltb3c1_stopfrac.GetValue()) if str0 >= str1 or str2 >= str3 or str4 >= 1 or str4 <= 0 or str5 >= 1 or str5 <= 0: e_c_box = wx.MessageBox("下阈应小于上阈", "Error") else: self.lt_start_l = str0 self.lt_start_r = str1 self.lt_stop_l = str2 self.lt_stop_r = str3 self.start_fraction = str4 self.stop_fraction = str5 def lt_sp_set(self, event): str0 = float(self.ltb3c2_sp_left.GetValue()) str1 = float(self.ltb3c2_sp_right.GetValue()) str2 = int(self.ltb3c2_bins.GetValue()) str3 = int(self.ltb3c2_counts.GetValue()) if str0 >= str1 or str2 <= 0 or str3 <= 0: e_c_box = wx.MessageBox("下阈应小于上阈", "Error") else: self.lt_l = str0 self.lt_r = str1 self.lt_bins = str2 self.counts_set = str3 def run_loop(self): self.th1 = threading.Thread(target=self.loop_energy_test) self.th1.start() def run_loop_lt(self): self.th2 = threading.Thread(target=self.loop_lifetime_test) self.th2.start() def loop_test(self): while self.dos_0.isOpen(): self.drawHistF.clf() self.a = self.drawHistF.add_subplot(111) self.t = np.arange(0.0, self.m, 0.01) self.s = np.sin(2 * np.pi * self.t) self.a.plot(self.t, self.s) self.a.semilogy() self.a.set_xlim((-1.5, 10.3)) self.a.set_xlabel('asd') # drawHistCanvas = FigureCanvas(box1, -1, drawHistF) self.drawHistCanvas.draw() if self.m > 10.0: self.m = self.m - 7 self.m = self.m + 0.1 time.sleep(0.01) def loop_energy_test(self): self.c_num = 0 while self.dos_0.isOpen(): waveform0 = self.dos_0.get_wave() if operator.eq(self.wave0, waveform0['c1'][1]) == False: if self.para_0['SEQ'] == 'ON': for i in range(0, self.para_0['SEQ_N']): #c1 t1 = tools.Wavetools(waveform0['c1'][0][i], waveform0['c1'][1][i], 800) e_1 = t1.get_energy(0.2) amp_1 = t1.get_amplitude() self.energy_c1.append(e_1) self.amp_c1.append(amp_1) #c2 t2 = tools.Wavetools(waveform0['c2'][0][i], waveform0['c2'][1][i], 800) e_2 = t2.get_energy(0.2) amp_2 = t2.get_amplitude() self.energy_c2.append(e_2) self.amp_c2.append(amp_2) self.c_num = self.c_num + 1 else: #c1 t1 = tools.Wavetools(waveform0['c1'][0], waveform0['c1'][1]) e_1 = t1.get_energy(0.2) amp_1 = t1.get_amplitude() self.energy_c1.append(e_1) self.amp_c1.append(amp_1) #c2 t2 = tools.Wavetools(waveform0['c2'][0][i], waveform0['c2'][1][i]) e_2 = t2.get_energy(0.2) amp_2 = t2.get_amplitude() self.energy_c2.append(e_2) self.amp_c2.append(amp_2) self.c_num = self.c_num + 1 if self.c_num % 100 == 0: self.drawHistF.clf() #c1 self.a = self.drawHistF.add_subplot(221) self.h_energy_c1 = self.a.hist(self.energy_c1, 150, range=(self.e_rg['c1'][0], self.e_rg['c1'][1])) #self.a.set_xlabel('energy') self.b = self.drawHistF.add_subplot(222) self.h_amp_c1 = self.b.hist(self.amp_c1, 150, range=(self.e_rg['c1_amp'][0], self.e_rg['c1_amp'][1])) #self.b.set_xlabel('amp') #c2 self.a_c2 = self.drawHistF.add_subplot(223) self.h_energy_c2 = self.a_c2.hist( self.energy_c2, 150, range=(self.e_rg['c2'][0], self.e_rg['c2'][1])) self.a_c2.set_xlabel('energy') self.b_c2 = self.drawHistF.add_subplot(224) self.h_amp_c2 = self.b_c2.hist( self.amp_c2, 150, range=(self.e_rg['c2_amp'][0], self.e_rg['c2_amp'][1])) self.b_c2.set_xlabel('amp') #self.a.semilogy() self.drawHistCanvas.draw() self.wave0 = waveform0['c1'][1] def loop_lifetime_test(self): self.c_num_1 = 0 t_01 = time.time() while self.dos_0.isOpen(): c_num_2 = 0 waveform0 = self.dos_0.get_wave() if operator.eq(self.wave1, waveform0['c1'][1]) == False: if self.para_0['SEQ'] == 'ON': for i in range(0, self.para_0['SEQ_N']): # c1 t1 = tools.Wavetools(waveform0['c1'][0][i], waveform0['c1'][1][i]) e_1 = t1.get_energy(0.2) amp_1 = t1.get_amplitude() # c2 t2 = tools.Wavetools(waveform0['c2'][0][i], waveform0['c2'][1][i]) e_2 = t2.get_energy(0.2) amp_2 = t2.get_amplitude() self.c_num_1 = self.c_num_1 + 1 if e_1 > self.lt_start_l and e_1 < self.lt_start_r \ and e_2 > self.lt_stop_l and e_2 < self.lt_stop_r : # t_start = t1.get_time_cfd_poln(self.start_fraction, 4, 0.4) # t_stop = t2.get_time_cfd_poln(self.stop_fraction, 4, 0.4) t_start = t1.get_time_cfd_linear( self.start_fraction) t_stop = t2.get_time_cfd_linear(self.stop_fraction) self.lifetime.append(t_stop - t_start) #print(t_stop - t_start) c_num_2 = c_num_2 + 1 self.total_counts = self.total_counts + 1 else: # c1 t1 = tools.Wavetools(waveform0['c1'][0], waveform0['c1'][1]) e_1 = t1.get_energy(0.2) amp_1 = t1.get_amplitude() # c2 t2 = tools.Wavetools(waveform0['c2'][0], waveform0['c2'][1]) e_2 = t2.get_energy(0.2) amp_2 = t2.get_amplitude() self.c_num_1 = self.c_num_1 + 1 if e_1 > self.lt_start_l and e_1 < self.lt_start_r and e_2 > self.lt_stop_l \ and e_2 < self.lt_stop_r: # t_start = t1.get_time_cfd_poln(self.start_fraction, 4, 0.4) # t_stop = t2.get_time_cfd_poln(self.stop_fraction, 4, 0.4) t_start = t1.get_time_cfd_linear(self.start_fraction) t_stop = t2.get_time_cfd_linear(self.stop_fraction) self.lifetime.append(t_stop - t_start) c_num_2 = c_num_2 + 1 self.total_counts = self.total_counts + 1 if self.c_num_1 % 500 == 0: self.drawHistF_lt.clf() self.a_lt = self.drawHistF_lt.add_subplot(111) self.h_lifetime = self.a_lt.hist(self.lifetime, self.lt_bins, range=(self.lt_l, self.lt_r)) self.a_lt.semilogy() self.drawHistCanvas_lt.draw() t_02 = time.time() self.cps = c_num_2 / (t_02 - t_01) self.lt_cps_text.SetValue(str(int(self.cps))) self.lt_counts_text.SetValue(str(self.total_counts)) t_01 = time.time() self.wave1 = waveform0['c1'][1] if self.total_counts > self.counts_set: break def save_file(self, event): ''' 保存文件内容 与菜单中的保存选项绑定 ''' self.dir_name = '' fd = wx.FileDialog(self, '把文件保存到何处', self.dir_name, 'out1.txt', 'TEXT file(*.txt)|*.txt', wx.FD_SAVE) if fd.ShowModal() == wx.ID_OK: self.file_name = fd.GetFilename() self.dir_name = fd.GetDirectory() try: with open(os.path.join(self.dir_name, self.file_name), 'w', encoding='utf-8') as f: text = plt.hist(self.lifetime, self.lt_bins, range=(self.lt_l, self.lt_r)) f.write('bin_width: ' + str((self.lt_r - self.lt_l) / self.lt_bins) + '\n') for i in range(0, len(text[0])): f.write(str(int(text[0][i])) + '\n') save_msg = wx.MessageDialog(self, '文件已保存', '提示') except FileNotFoundError: save_msg = wx.MessageDialog(self, '保存失败,无效的保存路径', '提示') else: save_msg = wx.MessageDialog(self, '未选择保存路径', '错误') save_msg.ShowModal() save_msg.Destroy()
class SignificanceWindow(wx.Frame): """Window for significance analysis""" sbSignifText=" Keys: 'i'/'m' increase/lower no. of bins, '0' resets, 's' saves plot" def __init__(self,parent,id,title,dm): wx.Frame.__init__(self, parent, -1, title, size=signifWindowSize) if platform != "darwin": icon = wx.Icon("LogoIcon.ico", wx.BITMAP_TYPE_ICO) self.SetIcon(icon) self.signifNumBins=signifNumBins self.dm = dm self.Bind(wx.EVT_CLOSE,self.OnEnd) self.WindowParent=parent sizer=wx.BoxSizer(wx.VERTICAL) panel = wx.Panel(self) # -------------- Begin of parameter selector sbParam = wx.StaticBox(panel, label="Parameter") sbParamSizer = wx.StaticBoxSizer(sbParam, wx.VERTICAL) sbParamSizer1 = wx.BoxSizer(wx.HORIZONTAL) sbParamSizer2 = wx.BoxSizer(wx.HORIZONTAL) AllBandsOrig = self.dm.GetVisibleBands()[0] AllBands=list(AllBandsOrig) AllBands.remove("Heart rate") bandsRB=[] for band in AllBands: if len(bandsRB)==0: tmp = wx.RadioButton(panel, label=band, style=wx.RB_GROUP) tmp.SetValue(True) else: tmp = wx.RadioButton(panel, label=band) bandsRB.append(tmp) if len(bandsRB)<=6: sbParamSizer1.Add(tmp, wx.EXPAND) else: sbParamSizer2.Add(tmp, wx.EXPAND) sbParamSizer.Add(sbParamSizer1,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) sbParamSizer.Add(sbParamSizer2,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) sizer.Add(sbParamSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) for eachRB in bandsRB: self.Bind(wx.EVT_RADIOBUTTON,self.OnParam,eachRB) self.ActiveParam = AllBands[0] # -------------- End of parameter selector # -------------- Begin of tags selector sbTags = wx.StaticBox(panel, label="Episodes") sbTagsSizer = wx.StaticBoxSizer(sbTags, wx.HORIZONTAL) # tagsRB = [] self.AllTags = self.dm.GetVisibleEpisodes()[0] self.ActiveTagLeft = self.AllTags[0] self.ActiveTagRight = None self.dm.SetSignifPlotParams(self.ActiveTagLeft,self.ActiveTagRight,self.ActiveParam) self.cbComboLeft=wx.ComboBox(panel, choices=self.AllTags, value=self.ActiveTagLeft, style=wx.CB_DROPDOWN|wx.CB_READONLY ) sbTagsSizer.Add(self.cbComboLeft,flag=wx.ALL | wx.EXPAND, border=borderSmall) self.Bind(wx.EVT_COMBOBOX, self.OnComboLeft, id=self.cbComboLeft.GetId()) sbTagsSizer.AddStretchSpacer(prop=1) ChoicesRight = ["Outside "+self.ActiveTagLeft]+self.AllTags ChoicesRight.remove(self.ActiveTagLeft) self.cbComboRight=wx.ComboBox(panel, choices=ChoicesRight, value="Outside "+self.ActiveTagLeft, style=wx.CB_DROPDOWN|wx.CB_READONLY ) sbTagsSizer.Add(self.cbComboRight,flag=wx.ALL | wx.EXPAND, border=borderSmall) self.Bind(wx.EVT_COMBOBOX, self.OnComboRight, id=self.cbComboRight.GetId()) sizer.Add(sbTagsSizer,flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT,border=borderBig) # -------------- End of tags selector # -------------- Begin of figure if ColoredBGPlots: self.fig = matplotlib.figure.Figure((5.0, 4.0),facecolor=SignifBGColor) else: self.fig = matplotlib.figure.Figure((5.0, 4.0)) self.fig.subplots_adjust(left=0.05, bottom=0.18, right=0.98, top=0.92, wspace=0.20, hspace=0.15) self.canvas = FigureCanvas(panel, -1, self.fig) self.axes = self.fig.add_subplot(111) sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) # -------------- End of figure # -------------- Begin of textbox and buttons hbox = wx.BoxSizer(wx.HORIZONTAL) self.textOutput = wx.TextCtrl(panel, id, 'Information', size=(400, 75), style=wx.TE_READONLY|wx.TE_MULTILINE|wx.TE_RICH2) self.textOutput.SetFont(wx.Font(11, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)); hbox.Add(self.textOutput, 1, wx.LEFT | wx.TOP | wx.GROW) endButton = wx.Button(panel, -1, "Close", size=buttonSizeSignif) self.Bind(wx.EVT_BUTTON, self.OnEnd, id=endButton.GetId()) endButton.SetToolTip(wx.ToolTip("Click to close window")) hbox.Add(endButton, 0, border=borderBig, flag=wx.LEFT|wx.ALIGN_BOTTOM) sizer.Add(hbox, 0, flag=wx.EXPAND|wx.ALL, border=borderBig) # -------------- End of textbox and buttons panel.SetSizer(sizer) self.SetMinSize(signifWindowMinSize) # self.sb = self.CreateStatusBar() # self.sb.SetStatusText(self.sbSignifText) # self.canvas.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress) self.Show(True) self.Layout() self.Refresh() def ErrorWindow(self,messageStr,captionStr="ERROR"): """Generic error window""" dial = wx.MessageDialog(self, caption=captionStr, message=messageStr, style=wx.OK | wx.ICON_ERROR) result = dial.ShowModal() dial.Destroy() self.canvas.SetFocus() def OnEnd(self,event): self.WindowParent.OnSignifEnded() self.Destroy() def OnParam(self,event): (ATL,ATR,AP) = self.dm.GetSignifPlotParams() self.ActiveParam = event.GetEventObject().GetLabel() self.dm.SetSignifPlotParams(ATL,ATR,self.ActiveParam) self.Refresh() def OnComboLeft(self,event): (ATL,ATR,AP) = self.dm.GetSignifPlotParams() self.ActiveTagLeft = self.cbComboLeft.GetValue() self.cbComboRight.Clear() ChoicesRight = ["Outside "+self.ActiveTagLeft]+self.AllTags ChoicesRight.remove(self.ActiveTagLeft) for item in ChoicesRight: self.cbComboRight.Append(item) self.cbComboRight.SetValue("Outside "+self.ActiveTagLeft) self.ActiveTagRight = None self.dm.SetSignifPlotParams(self.ActiveTagLeft,self.ActiveTagRight,AP) self.Refresh() def OnComboRight(self,event): (ATL,ATR,AP) = self.dm.GetSignifPlotParams() self.ActiveTagRight = self.cbComboRight.GetValue() if self.ActiveTagRight[0:7] == "Outside": self.ActiveTagRight=None self.dm.SetSignifPlotParams(ATL,self.ActiveTagRight,AP) self.Refresh() def Refresh(self): valuesLeft,valuesRight = self.dm.CreatePlotSignifEmbedded(self.fig) numValuesLeft=len(valuesLeft) numValuesRight=len(valuesRight) cad = "" if self.ActiveTagRight: cad = cad + "%s: %s (%d points) vs. %s (%d points)\n" % (self.ActiveParam, self.ActiveTagLeft, numValuesLeft, self.ActiveTagRight, numValuesRight) else: cad = cad + "%s: %s - inside (%d points) vs. outside (%d points)\n" % (self.ActiveParam, self.ActiveTagLeft, numValuesLeft, numValuesRight) if (numValuesLeft>signifNumMinValues) and (numValuesRight>signifNumMinValues): if self.ActiveTagRight: cad=cad+ u"%s: %g\u00b1%g, %s: %g\u00b1%g\n" % (self.ActiveTagLeft,np.mean(valuesLeft),np.std(valuesLeft,ddof=1),self.ActiveTagRight,np.mean(valuesRight),np.std(valuesRight,ddof=1)) else: cad=cad+ u"Inside: %g\u00b1%g, Outside: %g\u00b1%g\n" % (np.mean(valuesLeft),np.std(valuesLeft,ddof=1),np.mean(valuesRight),np.std(valuesRight,ddof=1)) # from scipy.stats import normaltest # z,pval = normaltest(valuesLeft) # if(pval < 0.055): # print self.ActiveTagLeft, "- not normal distribution" # else: # print self.ActiveTagLeft, "- Ok!" # z,pval = normaltest(valuesRight) # if(pval < 0.055): # print self.ActiveTagRight, "- not normal distribution" # else: # print self.ActiveTagRight, "- Ok!" from scipy.stats import ks_2samp pvalue = ks_2samp(valuesLeft,valuesRight)[1] cad=cad+ "KS test: " if pvalue<signifPMaxValue: cad=cad+ "significative differences found!!" cad=cad+" (p-value=%g < %g)" % (pvalue, signifPMaxValue) else: cad=cad+ "significative differences not found" cad=cad+" (p-value=%g >= %g)" % (pvalue, signifPMaxValue) # else: cad=cad+"Not enough data: minimum no. of points is "+str(signifNumMinValues) # self.textOutput.SetValue(cad) self.canvas.draw()
class TopPanel(BasePanel): def __init__(self, parent): BasePanel.__init__(self, parent=parent) self.parent = parent self.img_filename = None self.input_phil = None self.sparams = None self.coord_filename = None self.mtz_filename = None self.stol_filename = None self.ref_img_filename = None self.dblclick = False self.project_folder = ct.InputCtrl(self, label='Project Folder: ', label_size=(150, -1), label_style='bold', value=os.path.abspath(os.curdir), buttons=True) self.project_title = ct.InputCtrl(self, label='Description', label_size=(150, -1), label_style='normal') self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE | wx.SP_3DSASH | wx.SP_NOBORDER) self.file_panel = wx.Panel(self.splitter, size=(-1, 200)) self.file_sizer = wx.BoxSizer(wx.VERTICAL) self.file_panel.SetSizer(self.file_sizer) self.preview_panel = wx.Panel(self.splitter, size=(-1, 500)) self.preview_sizer = wx.BoxSizer(wx.VERTICAL) self.preview_panel.SetSizer(self.preview_sizer) self.splitter.SplitHorizontally(self.file_panel, self.preview_panel, 200) self.input = FileListCtrl(self.file_panel) self.file_sizer.Add(self.input, 1, flag=wx.ALL | wx.EXPAND, border=10) # Image preview box w/ options prev_box = wx.GridBagSizer(5, 15) # self.opt_knb_start = ct.KnobCtrl(self.preview_panel, # label='start', # label_size=(40, -1), # spin_ctr_size=(50, -1), # knob_size=(120, 120), # values_start=0, # values_end=360, # values_step=1, # value=0) # # self.opt_knb_end = ct.KnobCtrl(self.preview_panel, # label='end', # label_size=(40, -1), # spin_ctr_size=(50, -1), # knob_size=(120, 120), # values_start=0, # values_end=360, # values_step=1, # value=360) self.opt_spc_start = ct.SpinCtrl(self.preview_panel, label='start:', label_size=(50, -1), ctrl_size=(60, -1), ctrl_value='0', ctrl_max=360, ctrl_min=0, ctrl_step=0.1, ctrl_digits=1) self.opt_spc_end = ct.SpinCtrl(self.preview_panel, label='finish:', label_size=(50, -1), ctrl_size=(60, -1), ctrl_value='360', ctrl_max=360, ctrl_min=0, ctrl_step=0.1, ctrl_digits=1) self.opt_spc_osc = ct.SpinCtrl(self.preview_panel, label='step:', label_size=(50, -1), ctrl_size=(60, -1), ctrl_value='1.0', ctrl_max=360, ctrl_min=0, ctrl_step=0.1, ctrl_digits=2) self.opt_btn_prev = wx.Button(self.preview_panel, label='PREVIEW IMAGE') self.opt_chk_bkg = wx.CheckBox(self.preview_panel, label='Add Background') self.opt_chk_bkg.SetValue(True) self.opt_chk_noise = wx.CheckBox(self.preview_panel, label='Add Noise') self.opt_chk_noise.SetValue(True) self.opt_chk_rand = wx.CheckBox(self.preview_panel, label='Randomize Orientation') self.opt_chk_rand.SetValue(True) self.opt_spc_scale = ct.SpinCtrl(self.preview_panel, label='Crystal size (um): ', label_size=(120, -1), ctrl_size=(100, -1), ctrl_min = 1, ctrl_max = 1000, ctrl_step = 1, ctrl_value = 30) self.img_figure = Figure(figsize=(3, 3)) self.img_axes = self.img_figure.add_subplot(111) self.img_axes.set_frame_on(False) self.img_axes.axis('off') self.img_axes.set_aspect('equal') self.img_figure.patch.set_visible(False) self.img_canvas = FigureCanvas(self.preview_panel, -1, self.img_figure) prev_box.Add(self.opt_spc_start, pos=(0, 0)) prev_box.Add(self.opt_spc_end, pos=(0, 1)) prev_box.Add(self.opt_spc_osc, pos=(1, 0)) prev_box.Add(self.opt_chk_bkg, flag=wx.EXPAND, pos=(4, 0), span=(1, 2)) prev_box.Add(self.opt_chk_noise, flag=wx.EXPAND, pos=(5, 0), span=(1, 2)) prev_box.Add(self.opt_chk_rand, flag=wx.EXPAND, pos=(6, 0), span=(1, 2)) prev_box.Add(self.opt_spc_scale, flag=wx.EXPAND, pos=(7, 0), span=(1, 2)) prev_box.Add(self.opt_btn_prev, flag=wx.EXPAND, pos=(8,0), span=(1, 2)) prev_box.Add(self.img_canvas, pos=(0, 2), span=(9, 1), flag=wx.EXPAND) prev_box.AddGrowableCol(2) prev_box.AddGrowableRow(8) self.preview_sizer.Add(prev_box, 1, flag=wx.EXPAND | wx.ALL, border=10) self.main_sizer.Add(self.project_title, flag=wx.EXPAND | wx.ALL, border=10) self.main_sizer.Add(self.project_folder, flag=wx.EXPAND | wx.ALL, border=10) self.main_sizer.Add(self.splitter, 1, flag=wx.EXPAND) # Button bindings self.Bind(wx.EVT_BUTTON, self.onRunPreview, self.opt_btn_prev) # Thread bindings self.Bind(thr.EVT_NBDONE, self.onFinishedSimThread) # Image bindings xid = self.img_canvas.mpl_connect('button_press_event', self.on_button_press) xid = self.img_canvas.mpl_connect('button_release_event', self.on_button_release) def onRunPreview(self, e): e.Skip() def generate_phil(self): coord_path = None FCalc_path = None bkg_path = None img_path = None # Grab inputs (if any) from file list control idxs = self.input.ctr.GetItemCount() inputs = [self.input.ctr.GetItemData(i) for i in range(idxs)] for idx in range(idxs): item = self.input.ctr.GetItemData(idx) item_type_sel = item.type_selection item_type = item.type.type.GetString(item_type_sel) if item_type == 'coordinates': coord_path = item.path elif item_type == 'structure factors': FCalc_path = item.path elif item_type == 'background': bkg_path = item.path elif item_type == 'raw image file': img_path = item.path simtbx_phil_string = '\n'.join([ 'description = {}'.format(noneset(self.project_title.ctr.GetValue())), 'output = {}'.format(noneset(self.project_folder.ctr.GetValue())), 'reference_coordinates = {}'.format(coord_path), 'reference_FCalc = {}'.format(FCalc_path), 'reference_image = {}'.format(img_path), 'radial_average_background = {}'.format(bkg_path), 'dataset', '{', ' start_phi = {}'.format(str(self.opt_spc_start.ctr.GetValue())), ' finish_phi = {}'.format(str(self.opt_spc_end.ctr.GetValue())), ' oscillation = {}'.format(str(self.opt_spc_osc.ctr.GetValue())), ' }' ]) self.input_phil = ip.parse(simtbx_phil_string) def run_simulator(self, init=None): pass def run_preview(self): img_filename = 'test_image.{}'.format(self.sparams.image_format) self.img_filename = os.path.join(self.sparams.output, img_filename) self.start_timer = time.time() self.sim = thr.nanoBraggThread(self, params=self.sparams, add_background=self.opt_chk_bkg.GetValue(), add_noise=self.opt_chk_noise.GetValue(), randomize=self.opt_chk_rand.GetValue(), pixel_scale=self.opt_spc_scale.ctr.GetValue(), preview=True) self.sim.start() def onFinishedSimThread(self, e): pixels = e.GetValue() self.display_image(pixels=pixels) print('TOTAL TIME = ', time.time() - self.start_timer) def display_image(self, pixels=None): if pixels is None: pixels = np.random.randint(low=0, high=1500000, size=(2576, 2576)) else: pixels = pixels.as_numpy_array() clim = (pixels.min(), np.percentile(pixels, 99)) self.img_axes.imshow(pixels, #interpolation='nearest', cmap='gray_r', clim=clim) self.img_figure.subplots_adjust(left=0, bottom=0, right=1, top=1) self.preview_panel.Layout() print('DEBUG: AVERAGE PIXEL VALUE = ', np.mean(pixels)) print('DONE!') def on_button_press(self, e): if e.button == 1 and e.dblclick: self.dblclick = True else: self.dblclick = False def on_button_release(self, e): if e.button == 1 and self.dblclick: self.view_image() def view_image(self): viewer = thr.ImageViewerThread(self, file_string=self.img_filename) viewer.start()
def __init__(self, parent): BasePanel.__init__(self, parent=parent) self.parent = parent self.img_filename = None self.input_phil = None self.sparams = None self.coord_filename = None self.mtz_filename = None self.stol_filename = None self.ref_img_filename = None self.dblclick = False self.project_folder = ct.InputCtrl(self, label='Project Folder: ', label_size=(150, -1), label_style='bold', value=os.path.abspath(os.curdir), buttons=True) self.project_title = ct.InputCtrl(self, label='Description', label_size=(150, -1), label_style='normal') self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE | wx.SP_3DSASH | wx.SP_NOBORDER) self.file_panel = wx.Panel(self.splitter, size=(-1, 200)) self.file_sizer = wx.BoxSizer(wx.VERTICAL) self.file_panel.SetSizer(self.file_sizer) self.preview_panel = wx.Panel(self.splitter, size=(-1, 500)) self.preview_sizer = wx.BoxSizer(wx.VERTICAL) self.preview_panel.SetSizer(self.preview_sizer) self.splitter.SplitHorizontally(self.file_panel, self.preview_panel, 200) self.input = FileListCtrl(self.file_panel) self.file_sizer.Add(self.input, 1, flag=wx.ALL | wx.EXPAND, border=10) # Image preview box w/ options prev_box = wx.GridBagSizer(5, 15) # self.opt_knb_start = ct.KnobCtrl(self.preview_panel, # label='start', # label_size=(40, -1), # spin_ctr_size=(50, -1), # knob_size=(120, 120), # values_start=0, # values_end=360, # values_step=1, # value=0) # # self.opt_knb_end = ct.KnobCtrl(self.preview_panel, # label='end', # label_size=(40, -1), # spin_ctr_size=(50, -1), # knob_size=(120, 120), # values_start=0, # values_end=360, # values_step=1, # value=360) self.opt_spc_start = ct.SpinCtrl(self.preview_panel, label='start:', label_size=(50, -1), ctrl_size=(60, -1), ctrl_value='0', ctrl_max=360, ctrl_min=0, ctrl_step=0.1, ctrl_digits=1) self.opt_spc_end = ct.SpinCtrl(self.preview_panel, label='finish:', label_size=(50, -1), ctrl_size=(60, -1), ctrl_value='360', ctrl_max=360, ctrl_min=0, ctrl_step=0.1, ctrl_digits=1) self.opt_spc_osc = ct.SpinCtrl(self.preview_panel, label='step:', label_size=(50, -1), ctrl_size=(60, -1), ctrl_value='1.0', ctrl_max=360, ctrl_min=0, ctrl_step=0.1, ctrl_digits=2) self.opt_btn_prev = wx.Button(self.preview_panel, label='PREVIEW IMAGE') self.opt_chk_bkg = wx.CheckBox(self.preview_panel, label='Add Background') self.opt_chk_bkg.SetValue(True) self.opt_chk_noise = wx.CheckBox(self.preview_panel, label='Add Noise') self.opt_chk_noise.SetValue(True) self.opt_chk_rand = wx.CheckBox(self.preview_panel, label='Randomize Orientation') self.opt_chk_rand.SetValue(True) self.opt_spc_scale = ct.SpinCtrl(self.preview_panel, label='Crystal size (um): ', label_size=(120, -1), ctrl_size=(100, -1), ctrl_min = 1, ctrl_max = 1000, ctrl_step = 1, ctrl_value = 30) self.img_figure = Figure(figsize=(3, 3)) self.img_axes = self.img_figure.add_subplot(111) self.img_axes.set_frame_on(False) self.img_axes.axis('off') self.img_axes.set_aspect('equal') self.img_figure.patch.set_visible(False) self.img_canvas = FigureCanvas(self.preview_panel, -1, self.img_figure) prev_box.Add(self.opt_spc_start, pos=(0, 0)) prev_box.Add(self.opt_spc_end, pos=(0, 1)) prev_box.Add(self.opt_spc_osc, pos=(1, 0)) prev_box.Add(self.opt_chk_bkg, flag=wx.EXPAND, pos=(4, 0), span=(1, 2)) prev_box.Add(self.opt_chk_noise, flag=wx.EXPAND, pos=(5, 0), span=(1, 2)) prev_box.Add(self.opt_chk_rand, flag=wx.EXPAND, pos=(6, 0), span=(1, 2)) prev_box.Add(self.opt_spc_scale, flag=wx.EXPAND, pos=(7, 0), span=(1, 2)) prev_box.Add(self.opt_btn_prev, flag=wx.EXPAND, pos=(8,0), span=(1, 2)) prev_box.Add(self.img_canvas, pos=(0, 2), span=(9, 1), flag=wx.EXPAND) prev_box.AddGrowableCol(2) prev_box.AddGrowableRow(8) self.preview_sizer.Add(prev_box, 1, flag=wx.EXPAND | wx.ALL, border=10) self.main_sizer.Add(self.project_title, flag=wx.EXPAND | wx.ALL, border=10) self.main_sizer.Add(self.project_folder, flag=wx.EXPAND | wx.ALL, border=10) self.main_sizer.Add(self.splitter, 1, flag=wx.EXPAND) # Button bindings self.Bind(wx.EVT_BUTTON, self.onRunPreview, self.opt_btn_prev) # Thread bindings self.Bind(thr.EVT_NBDONE, self.onFinishedSimThread) # Image bindings xid = self.img_canvas.mpl_connect('button_press_event', self.on_button_press) xid = self.img_canvas.mpl_connect('button_release_event', self.on_button_release)
def __init__(self, parent, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.FRAME_FLOAT_ON_PARENT): global graphFrame_enabled global mplImported global mpl_version self.legendFix = False if not graphFrame_enabled: pyfalog.warning( "Matplotlib is not enabled. Skipping initialization.") return try: cache_dir = mpl._get_cachedir() except: cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib")) cache_file = os.path.join(cache_dir, 'fontList.cache') if os.access(cache_dir, os.W_OK | os.X_OK) and os.path.isfile(cache_file): # remove matplotlib font cache, see #234 os.remove(cache_file) if not mplImported: mpl.use('wxagg') graphFrame_enabled = True if int(mpl.__version__[0]) < 1: pyfalog.warning( "pyfa: Found matplotlib version {} - activating OVER9000 workarounds" .format(mpl.__version__)) pyfalog.warning( "pyfa: Recommended minimum matplotlib version is 1.0.0") self.legendFix = True mplImported = True wx.Frame.__init__(self, parent, title="pyfa: Graph Generator", style=style, size=(520, 390)) i = wx.Icon(BitmapLoader.getBitmap("graphs_small", "gui")) self.SetIcon(i) self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.CreateStatusBar() self.mainSizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.mainSizer) sFit = Fit.getInstance() fit = sFit.getFit(self.mainFrame.getActiveFit()) self.fits = [fit] if fit is not None else [] self.fitList = FitList(self) self.fitList.SetMinSize((270, -1)) self.fitList.fitList.update(self.fits) self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0) self.mainSizer.Add(self.graphSelection, 0, wx.EXPAND) self.figure = Figure(figsize=(4, 3)) rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get() clr = [c / 255. for c in rgbtuple] self.figure.set_facecolor(clr) self.figure.set_edgecolor(clr) self.canvas = Canvas(self, -1, self.figure) self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple)) self.subplot = self.figure.add_subplot(111) self.subplot.grid(True) self.mainSizer.Add(self.canvas, 1, wx.EXPAND) self.mainSizer.Add( wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL), 0, wx.EXPAND) self.gridPanel = wx.Panel(self) self.mainSizer.Add(self.gridPanel, 0, wx.EXPAND) dummyBox = wx.BoxSizer(wx.VERTICAL) self.gridPanel.SetSizer(dummyBox) self.gridSizer = wx.FlexGridSizer(0, 4, 0, 0) self.gridSizer.AddGrowableCol(1) dummyBox.Add(self.gridSizer, 0, wx.EXPAND) for view in Graph.views: view = view() self.graphSelection.Append(view.name, view) self.graphSelection.SetSelection(0) self.fields = {} self.select(0) self.sl1 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) self.mainSizer.Add(self.sl1, 0, wx.EXPAND) self.mainSizer.Add(self.fitList, 0, wx.EXPAND) self.fitList.fitList.Bind(wx.EVT_LEFT_DCLICK, self.removeItem) self.mainFrame.Bind(GE.FIT_CHANGED, self.draw) self.Bind(wx.EVT_CLOSE, self.close) self.Fit() self.SetMinSize(self.GetSize())
class ControlFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(640, 500)) self.initdone = 0 self.create_menu() #------------------------------------------- ##### Create Sizers and Panels: ##### #------------------------------------------- mainbox = wx.BoxSizer(wx.VERTICAL) perfbox = wx.BoxSizer(wx.HORIZONTAL) rightbox = wx.BoxSizer(wx.VERTICAL) firstbox = wx.BoxSizer(wx.HORIZONTAL) flagpanel = wx.Panel(self, -1, size=(500, 110)) envpanel = wx.Panel(self, -1, size=(230, 120)) speedpanel = wx.Panel(self, -1, size=(230, 100)) energypanel = wx.Panel(self, -1, size=(230, 90)) # panel colors: #envpanel.SetBackgroundColour('green') #speedpanel.SetBackgroundColour('yellow') #flagpanel.SetBackgroundColour('blue') #energypanel.SetBackgroundColour('magenta') #------------------------------------------- ##### Set Timer: ##### #------------------------------------------- self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnUpdate, self.timer) fatfont = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD) title = wx.StaticText(self, 1, 'Control Panel') title.SetFont(fatfont) line = wx.StaticLine(self, -1, (10, 10), (560, 1)) #line3 = wx.StaticLine(self, -1,(10,10),(560,1)) mainbox.Add((0, 20), 0) mainbox.Add(title, 0, wx.ALIGN_CENTER, 20) mainbox.Add(line, 0, wx.ALIGN_CENTER | wx.ALL, 10) #------------------------------------------- ##### Fill Panels: ##### #------------------------------------------- #self.fill_flagpanel(flagpanel) #self.fill_envpanel(envpanel) #self.fill_speedpanel(speedpanel) #self.fill_energypanel(energypanel) ##### Add to sizers: ##### perfbox.Add(speedpanel) rightbox.Add(envpanel) rightbox.Add(energypanel) firstbox.Add(flagpanel, 0, wx.ALIGN_CENTER) firstbox.Add(rightbox, 0, wx.ALIGN_CENTER) #mainbox.Add(firstbox,0,wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT, 15) #mainbox.Add(line3,0,wx.ALIGN_CENTER | wx.TOP ,5) #----------------------------------------------------------- ##### Create Plots: #----------------------------------------------------------- self.speeddata = [0] self.pos_longitude = [] self.pos_latitude = [] self.wyp_longitude = [0.0] self.wyp_latitude = [0.0] self.logtime = [0] self.plot_count = 0 #self.create_speed_plot() self.create_wyp_plot() #perfbox.Add(self.speed_panel, 1, wx.TOP | wx.LEFT | wx.GROW, 10) #mainbox.Add(perfbox, 0, wx.ALIGN_CENTER | wx.ALL , 20) mainbox.Add(self.canvas, 1, wx.CENTER) self.SetSizer(mainbox) def fill_energypanel(self, energypanel): energybox = wx.StaticBox(energypanel, -1, 'Energy Management', (5, 5), size=(220, 60)) wx.StaticText(energypanel, -1, 'Voltage:', pos=(20, 30)) self.voltage = wx.TextCtrl(energypanel, 46, 'DEFAULT', pos=(110, 26), size=(60, -1)) wx.StaticText(energypanel, -1, 'Volts', pos=(175, 30)) def fill_envpanel(self, envpanel): envbox = wx.StaticBox(envpanel, -1, 'Environment', (5, 5), size=(220, 95)) wx.StaticText(envpanel, -1, 'Wind Speed:', pos=(20, 30)) self.wind_speed = wx.TextCtrl(envpanel, 44, 'DEFAULT', pos=(110, 26), size=(60, -1)) wx.StaticText(envpanel, -1, 'knots', pos=(175, 30)) wx.StaticText(envpanel, -1, 'Direction:', pos=(20, 60)) self.wind_direction = wx.TextCtrl(envpanel, 45, 'DEFAULT', pos=(110, 56), size=(60, -1)) wx.StaticText(envpanel, -1, 'degree', pos=(175, 60)) def fill_speedpanel(self, speedpanel): speedbox = wx.StaticBox(speedpanel, -1, 'Performance', (5, 5), size=(220, 200)) wx.StaticText(speedpanel, -1, 'Speed:', pos=(20, 30)) self.speed = wx.TextCtrl(speedpanel, 41, 'DEFAULT', pos=(100, 26), size=(60, -1)) wx.StaticText(speedpanel, -1, 'knots', pos=(170, 30)) wx.StaticText(speedpanel, -1, 'desired HD:', pos=(20, 60)) self.des_heading = wx.TextCtrl(speedpanel, 42, 'DEFAULT', pos=(100, 56), size=(60, -1)) wx.StaticText(speedpanel, -1, 'degree', pos=(170, 60)) wx.StaticText(speedpanel, -1, 'current HD:', pos=(20, 90)) self.cur_heading = wx.TextCtrl(speedpanel, 43, 'DEFAULT', pos=(100, 86), size=(60, -1)) wx.StaticText(speedpanel, -1, 'degree', pos=(170, 90)) wx.StaticLine(speedpanel, -1, (20, 130), (180, 1)) wx.StaticText(speedpanel, -1, 'Drift:', pos=(20, 140)) self.drift = wx.TextCtrl(speedpanel, 48, 'DEFAULT', pos=(100, 136), size=(60, -1)) wx.StaticText(speedpanel, -1, 'knots', pos=(170, 140)) wx.StaticText(speedpanel, -1, 'Roll:', pos=(20, 170)) self.roll = wx.TextCtrl(speedpanel, 49, 'DEFAULT', pos=(100, 166), size=(60, -1)) wx.StaticText(speedpanel, -1, 'degree', pos=(170, 170)) def fill_flagpanel(self, flagpanel): statbox = wx.StaticBox(flagpanel, -1, 'Boat Controller Information', (5, 5), size=(390, 160)) self.joystick = wx.CheckBox(flagpanel, 35, 'Joystick', pos=(20, 30)) self.sailor = wx.CheckBox(flagpanel, 36, 'Sailor', pos=(100, 30)) self.autonomous = wx.CheckBox(flagpanel, 37, 'Fully Autonomous', pos=(180, 30)) self.txtsailingmode = wx.StaticText(flagpanel, -1, 'Sailing Mode:', pos=(20, 70)) #self.txtsailingmode.SetForegroundColour('white') self.sailMode = wx.TextCtrl(flagpanel, 40, 'DEFAULT', pos=(150, 66), size=(200, -1)) smallline = wx.StaticLine(flagpanel, -1, (20, 100), (350, 1)) wx.StaticText(flagpanel, -1, 'RudderState Right:', pos=(20, 110)) wx.StaticText(flagpanel, -1, 'RudderState Left:', pos=(20, 135)) self.rudderright = wx.TextCtrl(flagpanel, 60, 'DFLT', pos=(150, 105), size=(80, -1)) self.rudderleft = wx.TextCtrl(flagpanel, 61, 'DFLT', pos=(150, 130), size=(80, -1)) wx.StaticText(flagpanel, -1, 'degree', pos=(260, 110)) wx.StaticText(flagpanel, -1, 'degree', pos=(260, 135)) #statbox.SetForegroundColour('white') #flagpanel.SetBackgroundColour('black') #self.joystick.SetForegroundColour('white') #self.sailor.SetForegroundColour('white') #self.autonomous.SetForegroundColour('white') def create_wyp_plot(self): self.wypfigure = Figure((6.0, 3.5), dpi=110, facecolor='w') self.wypfigure.subplots_adjust(top=0.93, bottom=0.04, left=0.06, right=0.95, wspace=None, hspace=None) self.wypplot = self.wypfigure.add_subplot(111) #, aspect = 'equal') pylab.setp(self.wypplot.get_xticklabels(), fontsize=6) pylab.setp(self.wypplot.get_yticklabels(), fontsize=6) self.wypplot.set_title('navigated path', size=8) self.plot_posdata = self.wypplot.plot( array(self.pos_longitude), array(self.pos_latitude), linewidth=1, color=(1, 0, 0), label='AVALON', )[0] self.plot_wypdata = self.wypplot.plot( array(self.wyp_longitude), array(self.wyp_latitude), linewidth=1, color=(0, 0, 1), label='calculated', )[0] myprop = matplotlib.font_manager.FontProperties(size=10) self.wypplot.legend(loc=4, shadow=True, prop=myprop) self.wypplot.set_axis_bgcolor('white') self.canvas = FigureCanvas(self, -1, self.wypfigure) def create_speed_plot(self): self.speed_panel = wx.Panel(self) self.dpi = 100 self.fig = Figure((3.8, 1.95), dpi=self.dpi, facecolor='w') self.fig.subplots_adjust(top=0.95, right=0.97, bottom=0.07) self.speedplot = self.fig.add_subplot(111) self.speedplot.set_axis_bgcolor('black') #self.speedplot.set_title('AVALON Speed History', size=10) self.speedplot.set_ylabel('[knots]', size=8) pylab.setp(self.speedplot.get_xticklabels(), fontsize=8) pylab.setp(self.speedplot.get_yticklabels(), fontsize=8) # plot the data as a line series, and save the reference # to the plotted line series # self.plot_data = self.speedplot.plot( self.speeddata, linewidth=1, color=(1, 1, 0), )[0] self.speed_canvas = FigureCanvas(self.speed_panel, -1, self.fig) def UpdatePosPlot(self): # --------------------------------------- # redraws the position plot: # --------------------------------------- #delta_long = max(max(self.pos_longitude),max(self.wyp_longitude)) - min(min(self.pos_longitude), min(self.wyp_longitude)) #long_m = 0.5*(max(max(self.pos_longitude), max(self.wyp_longitude)) + min(min(self.pos_longitude), min(self.wyp_longitude))) #delta_lat = max(max(self.pos_latitude), max(self.wyp_latitude)) - min(min(self.pos_latitude), min(self.wyp_latitude)) #lat_m = 0.5*(max(max(self.pos_latitude), max(self.wyp_latitude)) + min(min(self.pos_latitude), min(self.wyp_latitude))) delta_long = max(self.pos_longitude) - min(self.pos_longitude) long_m = 0.5 * (max(self.pos_longitude)) + min(self.pos_longitude) delta_lat = max(self.pos_latitude) - min(self.pos_latitude) lat_m = 0.5 * (max(self.pos_latitude)) + min(self.pos_latitude) delta_long_calc = 6.0 / 3.5 * delta_lat delta_lat_calc = 3.5 / 6.0 * delta_long # --- set axes boundaries --- if delta_lat_calc > delta_lat: xmax = (long_m + 0.5 * delta_long + 0.0005) xmin = (long_m - 0.5 * delta_long - 0.0005) ymax = (lat_m + 0.5 * delta_lat_calc + 0.0005) ymin = (lat_m - 0.5 * delta_lat_calc - 0.0005) elif delta_long_calc > delta_long: xmax = (long_m + 0.5 * delta_long_calc + 0.0005) xmin = (long_m - 0.5 * delta_long_calc - 0.0005) ymax = (lat_m + 0.5 * delta_lat + 0.0005) ymin = (lat_m - 0.5 * delta_lat - 0.0005) else: # --- not 1:1 ratio --- xmax = max(self.pos_longitude) + 0.0005 xmin = min(self.pos_longitude) - 0.0005 ymax = max(self.pos_latitude) + 0.0005 ymin = min(self.pos_latitude) - 0.0005 #print long_m #self.wypplot.set_xbound(lower=xmin, upper=xmax) #self.wypplot.set_ybound(lower=ymin, upper=ymax) self.wypplot.set_xbound(lower=-150, upper=150) self.wypplot.set_ybound(lower=-300, upper=0) #grid on: self.wypplot.grid(True, color='gray') self.plot_posdata.set_xdata(array(self.pos_longitude)) self.plot_posdata.set_ydata(array(self.pos_latitude)) #self.plot_wypdata.set_xdata(array(self.wyp_longitude)) #self.plot_wypdata.set_ydata(array(self.wyp_latitude)) self.canvas.draw() def UpdateSpeedPlot(self): """ Redraws the plot """ # define the range of the axes xmax = self.logtime[30] if len(self.logtime) > 30 else 60 xmin = self.logtime[0] ymin = round(min(self.speeddata), 0) - 1 ymax = round(max(self.speeddata), 0) + 1 self.speedplot.set_xbound(lower=xmin, upper=xmax) self.speedplot.set_ybound(lower=ymin, upper=ymax) ## grid on: self.speedplot.grid(True, color='gray') pylab.setp(self.speedplot.get_xticklabels(), visible=True) self.plot_data.set_xdata(array(self.logtime)) self.plot_data.set_ydata(array(self.speeddata)) self.speed_canvas.draw() def create_menu(self): menubar = wx.MenuBar() file = wx.Menu() file.Append(101, '&Open', 'not working momentarely') file.AppendSeparator() quit = wx.MenuItem(file, 102, '&Quit\tCtrl+Q', 'Quit the Application') file.AppendItem(quit) menudata = wx.Menu() menudata.Append(301, '&Initialize\tCtrl+I', 'Initialize Store-Data') menudata.Append(302, '&Start\tCtrl+S', 'Start reading Data') menudata.Append(303, '&Stop\tCtrl+E', 'Stop reading Data') menudata.Append(304, '&Plot WYP\tCtrl+W', 'fill wyps to vector') menuplot = wx.Menu() menuplot.Append(401, '&Clear Plot\tCtrl+C', 'Clear the Navigation plot') menubar.Append(file, '&File') menubar.Append(menudata, '&Data') menubar.Append(menuplot, '&Plot') self.SetMenuBar(menubar) self.Bind(wx.EVT_MENU, self.OnQuit, id=102) self.Bind(wx.EVT_MENU, self.OnInitData, id=301) self.Bind(wx.EVT_MENU, self.OnStartStop, id=302) self.Bind(wx.EVT_MENU, self.OnStartStop, id=303) self.Bind(wx.EVT_MENU, self.OnWypFill, id=304) self.Bind(wx.EVT_MENU, self.OnClearPlot, id=401) self.Centre() def OnClearPlot(self, event): # clear the data-arrays: del self.pos_longitude[:] del self.pos_latitude[:] del self.wyp_longitude[:] del self.wyp_latitude[:] self.wyp_latitude[0] self.wyp_longitude[0] msg = wx.MessageDialog(None, 'Plot data cleared!', 'Info', wx.OK) msg.ShowModal() def OnInitData(self, event): #----------------------------------------------------------- # initialize Store connection and define variables #----------------------------------------------------------- store = ddxInterface.ddxStore() self.IMUData = store.variable("imu") #self.FLAGData = store.variable("flags") #self.WINDData = store.variable("cleanwind") #self.DHData = store.variable("desiredheading") self.WypData = store.variable("wypData") self.DESTData = store.variable("destData") #self.RDRData = store.variable("rudderstateright") #self.RDLData = store.variable("rudderstateleft") #flag: self.initdone = 1 def OnUpdate(self, event): ###read DDX variables and write to GUI: #### self.IMUData.read() #self.FLAGData.read() #self.WINDData.read() #self.DHData.read() self.DESTData.read() #self.RDRData.read() #self.RDLData.read() ###sailing mode: #### #mode = { # 1: 'IDLE', # 2: 'DOCK', # 3: 'NORMAL SAILING', # 4: 'TACK', # 5: 'JIBE', # 6: 'UPWIND', # 7: 'DOWNWIND', # 8: 'MAX ENERGY SAVING', # 9: 'HEADING CHANGE', # 0: 'ERROR', # #}[8] # }[int(self.FLAGData.state)] # #self.sailMode.SetValue(mode) ####radio buttons: #### #joystick_bool = {1: False, 2: True, 0: False}[int(self.FLAGData.man_in_charge)] #sailor_bool = {1: True, 2: False, 0: False}[int(self.FLAGData.man_in_charge)] #autonomous_bool = {0: False, 1: True}[int(self.FLAGData.autonom_navigation)] ##print self.FLAGData.man_in_charge ##joystick_bool = {1: False, 2: True}[1] ##sailor_bool = {1: True, 2: False}[1] ##autonomous_bool = {0: False, 1: True}[1] #self.joystick.SetValue(joystick_bool) #self.sailor.SetValue(sailor_bool) #self.autonomous.SetValue(autonomous_bool) ##self.rudderright.SetValue(' %1.3f') % (float(self.RDRData.degrees_rudder)) #self.rudderright.SetValue(str(float(self.RDRData.degrees_rudder))) #self.rudderleft.SetValue(str(float(self.RDLData.degrees_rudder))) # ##### performance information: #### ##self.speed.SetValue(str(6.34)) ##self.des_heading.SetValue(str(130)) ##self.cur_heading.SetValue(str(120)) ##self.drift.SetValue(str(0.1)) ##self.roll.SetValue(str(16)) #self.speed.SetValue(str(float(self.IMUData.speed))) #self.des_heading.SetValue(str(float(self.DHData.heading))) #self.cur_heading.SetValue(str(float(self.IMUData.attitude.yaw))) #self.drift.SetValue(str(float(self.IMUData.velocity.y))) #self.roll.SetValue(str(float(self.IMUData.attitude.roll))) ##### environment information: #### #self.wind_speed.SetValue(str(float(self.WINDData.speed_long))) #self.wind_direction.SetValue(str(float(self.WINDData.global_direction_real_long))) ##### energy panel information: #### #self.voltage.SetValue('--') # ------------------------------------------------------------------------------ # plots: # ------------------------------------------------------------------------------ #sp_length = len(self.logtime) #self.logtime.append((self.logtime[sp_length-1])+2) #self.speeddata.append(float(self.IMUData.speed)) #if sp_length > 30: # self.logtime.pop(0) # self.speeddata.pop(0) #self.UpdateSpeedPlot() # ---- position decoding (every 10 seconds)------ if self.plot_count > 1: self.plot_count = 0 #pos_x = float (EARTH_RAD * (math.pi/180) # *(float(self.IMUData.position.latitude) - float(self.DESTData.latitude))) #pos_y = float (EARTH_RAD # *math.cos((float(self.DESTData.latitude) * math.pi/180.0))*(math.pi/180.0) # *(float(self.IMUData.position.longitude) - float(self.DESTData.longitude))) pos_x = float( EARTH_RAD * (math.pi / 180) * (float(47.29853) - float(self.IMUData.position.latitude))) pos_y = float( EARTH_RAD * math.cos( (float(47.29853) * math.pi / 180.0)) * (math.pi / 180.0) * (float(8.566133) - float(self.IMUData.position.longitude))) self.pos_longitude.append( pos_y) #(float(self.IMUData.position.longitude)) self.pos_latitude.append( pos_x) #(float(self.IMUData.position.latitude)) print pos_x print pos_y #if len(self.pos_longitude) > 60: # self.pos_longitude.pop(0) # self.pos_latitude.pop(0) self.UpdatePosPlot() self.plot_count += 1 #print self.plot_count ###debug: print 'updated control panel' def OnWypFill(self, event): self.WypData.read() del self.wyp_longitude[:] del self.wyp_latitude[:] for i in range(0, 18): self.wyp_longitude.append(float(self.WypData.Data[i].y)) self.wyp_latitude.append(float(self.WypData.Data[i].x)) print self.wyp_longitude print self.wyp_latitude if int(self.WypData.Data[i].wyp_type) == 1: # --- stop --- break self.UpdatePosPlot() print self.wyp_longitude print 'Wyp Data filled' def OnStartStop(self, event): if self.initdone == 0: msg = wx.MessageDialog( None, 'Store not initialized. Please press Ctrl-I', 'Error', wx.OK | wx.ICON_EXCLAMATION) msg.ShowModal() return if self.timer.IsRunning(): self.timer.Stop() #self.startBtn.SetLabel("Restart") #self.fileHandle.close() print "timer stopped" else: print "starting timer" self.timer.Start(2000) #os.remove('position.txt') #self.fileHandle = open('position.txt','a') #self.startBtn.SetLabel("Stop") def OnQuit(self, event): self.Destroy()