class CanvasPanel(wx.Panel): """ This panel holds the actual chart. It is recreated everytime with a new Chart as input. """ def __init__(self, parent, chart): wx.Panel.__init__(self, parent) self.SetBackgroundColour(wx.NamedColour("WHITE")) if chart is not None: self.figure, self.axes = chart.fig, chart.ax else: self.figure = Figure( ) #WE NEED TO INITIALIZE OTHERWISE IT CAN BREAK 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.add_toolbar() self.SetSizer(self.sizer) self.Fit() 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()
class VolumePanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) # initialize matplotlib stuff self.figure = Figure() self.canvas = FigureCanvas(self, -1, self.figure) self.ax = self.figure.add_subplot(111) #print "Top Applications ..." self.timeControlPanel = TimeControlPanel(self) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.timeControlPanel, 0, wx.LEFT | wx.TOP | wx.GROW) self.sizer.Add(self.canvas, 0, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.Fit() self.SetSize(panel_size) 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) # update the axes menu on the toolbar self.toolbar.update()
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.SetSizerAndFit(self.sizer) self.add_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()
class PlotFigure(wxFrame): def __init__(self): wxFrame.__init__(self, None, -1, "Test embedded wxFigure") self.fig = Figure((5,4), 75) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) self.toolbar = Toolbar(self.canvas) self.toolbar.Realize() # On Windows, default frame size behaviour is incorrect # you don't need this under Linux tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wxSize(fw, th)) # Create a figure manager to manage things # Now put all into a sizer sizer = wxBoxSizer(wxVERTICAL) # This way of adding to sizer allows resizing sizer.Add(self.canvas, 1, wxLEFT|wxTOP|wxGROW) # Best to allow the toolbar to resize! sizer.Add(self.toolbar, 0, wxGROW) self.SetSizer(sizer) self.Fit() EVT_TIMER(self, TIMER_ID, self.onTimer) def init_plot_data(self): # jdh you can add a subplot directly from the fig rather than # the fig manager a = self.fig.add_subplot(111) self.x = numerix.arange(120.0)*2*numerix.pi/120.0 self.x.resize((100,120)) self.y = numerix.arange(100.0)*2*numerix.pi/100.0 self.y.resize((120,100)) self.y = numerix.transpose(self.y) z = numerix.sin(self.x) + numerix.cos(self.y) self.im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest') def GetToolBar(self): # You will need to override GetToolBar if you are using an # unmanaged toolbar in your frame return self.toolbar def onTimer(self, evt): self.x += numerix.pi/15 self.y += numerix.pi/20 z = numerix.sin(self.x) + numerix.cos(self.y) self.im.set_array(z) self.canvas.draw() #self.canvas.gui_repaint() # jdh wxagg_draw calls this already def onEraseBackground(self, evt): # this is supposed to prevent redraw flicker on some X servers... pass
class CanvasFrame(wx.Frame): def __init__(self, parent): wx.Frame.__init__(self, parent, -1, 'CanvasFrame', size=(550, 350)) #main_sizer = wx.BoxSizer(wx.VERTICAL) #self.conf_panel = ConfPanel(self) #main_sizer.Add(self.conf_panel, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5) self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) self.cmap = plt.cm.hot self.ndivs = (1000, 1000) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.toolbar = MyNavigationToolbar(self) self.toolbar.Realize() # On Windows platform, default window size is incorrect, so set toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # 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.toolbar.SetSize(wx.Size(fw, th)) sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) # Update the axes menu on the toolbar self.toolbar.update() self.SetSizerAndFit(sizer) # Compute fractal and show picture. self.imshow_fractal() def imshow_fractal(self, extent=None): xvals, yvals, data = mandelbrot(extent=extent, ndivs=self.ndivs) if extent is None: extent = (xvals[0], xvals[-1], yvals[0], yvals[-1]) self.axes.imshow(np.log(data), cmap=plt.cm.hot, origin="lower", extent=extent) # Save values self.xvals, self.yvals, self.data = xvals, yvals, data
class CanvasFrame(Frame): def __init__(self): Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(NamedColor("WHITE")) self.figure = Figure() self.canvas = FigureCanvas(self, -1, self.figure) self.ax = self.figure.add_subplot(111) self.sizer = BoxSizer(VERTICAL) self.sizer.Add(self.canvas, 1, LEFT | TOP | GROW) self.SetSizer(self.sizer) self.Fit() self.add_toolbar() # comment this out for no toolbar self.plot_map() def add_toolbar(self): self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() if Platform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(Size(fw, th)) self.sizer.Add(self.toolbar, 0, LEFT | EXPAND) # update the axes menu on the toolbar self.toolbar.update() def plot_map(self): map = Basemap(ax=self.ax) map.drawcoastlines() map.drawcountries() map.drawmapboundary() map.fillcontinents(color='coral', lake_color='aqua') map.drawmapboundary(fill_color='aqua') self.figure.canvas.draw()
class PlotFigure(Frame): def __init__(self): Frame.__init__(self, None, -1, "Dynamic Data Display - WX") self.fig = Figure((5, 4), 100) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() # On Windows, default frame size behaviour is incorrect # you don't need this under Linux tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(Size(fw, th)) # Create a figure manager to manage things # Now put all into a sizer sizer = BoxSizer(VERTICAL) # This way of adding to sizer allows resizing sizer.Add(self.canvas, 1, LEFT | TOP | GROW) # Best to allow the toolbar to resize! sizer.Add(self.toolbar, 0, GROW) self.SetSizer(sizer) self.Fit() EVT_TIMER(self, TIMER_ID, self.onTimer) def init_plot_data(self): self.ax1 = self.fig.add_axes([0.15, 0.15, 0.8, 0.8]) self.ax1.grid(True) self.ax1.set_xlabel('Frame Number') self.ax1.set_ylabel('Cells detected') def GetToolBar(self): # You will need to override GetToolBar if you are using an # unmanaged toolbar in your frame return self.toolbar def onTimer(self, evt): data = np.loadtxt(options.filename, delimiter='\t') self.ax1.bar(data[:, 0], data[:, 1], width=0.7, bottom=0) self.ax1.set_xlim([data[0, 0] - 1, data[-1, 0] + 1]) self.ax1.set_ylim([data[:, 1].min() * 0.9, data[:, 1].max() * 1.1]) self.canvas.draw() def onEraseBackground(self, evt): # this is supposed to prevent redraw flicker on some X servers... pass
class Plots_Panel(wx.Panel): """ Panel to hold matplotlib figure. There are three plots inside a grid, big one for temperature vs. deformation and smaller ones for time vs. deformation and time vs. temperature. """ #--------------------------------------------------------------------------# def __init__(self, parent): wx.Panel.__init__(self, parent) self.init_plots() #make figure self.PlotsCanvas = FigCanvas(self, wx.ID_ANY, self.fig) self.toolbar = NavigationToolbar(self.PlotsCanvas) self.toolbar.Realize() #correct toolbar size tw, th = self.toolbar.GetSizeTuple() fw, fh = self.PlotsCanvas.GetSizeTuple() # Sizers sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.PlotsCanvas, 1, wx.EXPAND | wx.GROW) sizer.Add(self.toolbar, 0, wx.BOTTOM | wx.GROW) self.toolbar.SetSize(wx.Size(fw, th)) self.toolbar.update() self.SetSizerAndFit(sizer) #--------------------------------------------------------------------------# def init_plots(self): self.fig = Figure((-1, 7.5)) self.fig.subplots_adjust(left=0.05, wspace=.3, hspace=3) #sub plot spacing gs = matplotlib.gridspec.GridSpec(8, 3) self.ax1 = self.fig.add_subplot(gs[:, 0:2]) self.ax2 = self.fig.add_subplot(gs[0:4, 2]) self.ax3 = self.fig.add_subplot(gs[4:8, 2]) self.ax1.set_xlabel(u'Temperatura ($^\circ$C)') self.ax1.set_ylabel(u'Deformación (mm)') self.ax2.set_xlabel(u'Tiempo (s)') self.ax2.set_ylabel(u'Deformación (mm)') self.ax3.set_xlabel(u'Tiempo (s)') self.ax3.set_ylabel(u'Temperatura ($^\circ$C)')
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(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 wx.EVT_PAINT(self, self.OnPaint) self.toolbar = MyNavigationToolbar(self.canvas, True) self.toolbar.Realize() if wx.Platform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top print "Using max workaround!" self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wx.Size(fw, th)) 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 PlotFigure(wxFrame): def __init__(self): wxFrame.__init__(self, None, -1, "Test embedded wxFigure") self.fig = Figure((9, 8), 75) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) self.toolbar = NavigationToolbar2WxAgg(self.canvas) self.toolbar.Realize() self.figmgr = FigureManager(self.canvas, 1, self) tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wxSize(fw, th)) sizer = wxBoxSizer(wxVERTICAL) # This way of adding to sizer allows resizing sizer.Add(self.canvas, 1, wxLEFT | wxTOP | wxGROW) sizer.Add(self.toolbar, 0, wxGROW) self.SetSizer(sizer) self.Fit() self.plot3d() def plot3d(self): # sample taken from http://www.scipy.org/Cookbook/Matplotlib/mplot3D ax3d = matplotlib.axes3d.Axes3D(self.fig) plt = self.fig.axes.append(ax3d) delta = nx.pi / 199.0 u = nx.arange(0, 2 * nx.pi + (delta * 2), delta * 2) v = nx.arange(0, nx.pi + delta, delta) x = nx.outerproduct(nx.cos(u), nx.sin(v)) y = nx.outerproduct(nx.sin(u), nx.sin(v)) z = nx.outerproduct(nx.ones(nx.size(u)), nx.cos(v)) print x.shape, y.shape, z.shape #ax3d.plot_wireframe(x,y,z) surf = ax3d.plot_surface(x, y, z) surf.set_array(matplotlib.mlab.linspace(0, 1.0, len(v))) ax3d.set_xlabel('X') ax3d.set_ylabel('Y') ax3d.set_zlabel('Z') self.fig.savefig('globe')
class PlotFigure(Frame): def __init__(self): Frame.__init__(self, None, -1, "Test embedded wxFigure") self.fig = Figure((9,8), 75) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) self.toolbar = NavigationToolbar2WxAgg(self.canvas) self.toolbar.Realize() self.figmgr = FigureManager(self.canvas, 1, self) tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(Size(fw, th)) sizer = BoxSizer(VERTICAL) # This way of adding to sizer allows resizing sizer.Add(self.canvas, 1, LEFT|TOP|GROW) sizer.Add(self.toolbar, 0, GROW) self.SetSizer(sizer) self.Fit() self.plot3d() def plot3d(self): # sample taken from http://www.scipy.org/Cookbook/Matplotlib/mplot3D ax3d = matplotlib.axes3d.Axes3D(self.fig) plt = self.fig.axes.append(ax3d) delta = npy.pi / 199.0 u = npy.arange(0, 2*npy.pi+(delta*2), delta*2) v = npy.arange(0, npy.pi+delta, delta) x = npy.cos(u)[:,npy.newaxis] * npy.sin(v)[npy.newaxis,:] y = npy.sin(u)[:,npy.newaxis] * npy.sin(v)[npy.newaxis,:] z = npy.ones_like(u)[:,npy.newaxis] * npy.cos(v)[npy.newaxis,:] # (there is probably a better way to calculate z) print x.shape, y.shape, z.shape #ax3d.plot_wireframe(x,y,z) surf = ax3d.plot_surface(x, y, z) surf.set_array(matplotlib.mlab.linspace(0, 1.0, len(v))) ax3d.set_xlabel('X') ax3d.set_ylabel('Y') ax3d.set_zlabel('Z')
class icCanvasPanel(wx.Panel): def __init__(self, parent, id=-1, pos=(-1, -1), size=(-1, -1)): wx.Panel.__init__(self, parent, id, pos, size) self.count = 0 self.SetBackgroundColour(wx.NamedColor('WHITE')) self.figure = Figure() # --- dd = 10 # --- Plot2 matplotlib.rcParams['timezone'] = 'US/Pacific' tz = timezone('US/Pacific') date1 = datetime.datetime(2000, 3, 2, 10, tzinfo=tz) date2 = datetime.datetime(2000, 3, 2, 15, tzinfo=tz) delta = datetime.timedelta(minutes=5) dates = drange(date1, date2, delta) self.axes1 = self.figure.add_subplot(111) yy = pylab.arrayrange(len(dates) * 1.0) majorTick = HourLocator(range(0, 25, 1), tz=tz) ysq = [y * y / dd for y in yy] line = self.axes1.plot_date(dates, ysq, tz=tz) self.axes1.xaxis.set_major_locator(majorTick) self.axes1.set_xlabel('Time (s)') self.axes1.set_ylabel('Price 2 ($)') # self.canvas = FigureCanvas(self, -1, self.figure) self.canvas.mpl_connect('motion_notify_event', self.mouse_move) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) # --- Add Toolbar self.toolbar = Toolbar(self.canvas) self.toolbar.Realize() # On Windows, default frame size behaviour is incorrect # you don't need this under Linux tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wx.Size(fw, th)) # Create a figure manager to manage things self.figmgr = FigureManager(self.canvas, 1, self) self.sizer.Add(self.toolbar, 0, wx.EXPAND) self.toolbar.update() self.statusBar = wx.StatusBar(self, -1) self.statusBar.SetFieldsCount(1) self.sizer.Add(self.statusBar, 0, wx.EXPAND) self.Fit() # --- Обработчики событий self.Bind(wx.EVT_PAINT, self.OnPaint) def GetToolBar(self): """ You will need to override GetToolBar if you are using an unmanaged toolbar in your frame. """ return self.toolbar def mouse_move(self, event): self.draw_cursor(event) def add_toolbar(self): self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() 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) # update the axes menu on the toolbar self.toolbar.update() def OnButton(self, evt): """ """ dd = 20 t = arange(0.0, 3.0, 1.0 / dd) s = [10 + y * y / dd + self.count for y in xrange(0, 3 * dd)] self.count += 5 self.axes.lines.pop(0) line, = self.axes.plot(t, s, 'r:d') line.set_markersize(5) self.Refresh() evt.Skip() def OnPaint(self, event): self.erase_cursor() try: del self.lastInfo except AttributeError: pass self.canvas.draw() event.Skip() def draw_cursor(self, event): """ event is a MplEvent. Draw a cursor over the axes. """ if event.inaxes is None: self.erase_cursor() try: del self.lastInfo except AttributeError: pass return canvas = self.canvas figheight = canvas.figure.bbox.height() ax = event.inaxes left, bottom, width, height = ax.bbox.get_bounds() bottom = figheight - bottom top = bottom - height right = left + width x, y = event.x, event.y y = figheight - y dc = wx.ClientDC(canvas) dc.SetLogicalFunction(wx.XOR) wbrush = wx.Brush(wx.Colour(255, 255, 255), wx.TRANSPARENT) wpen = wx.Pen(wx.Colour(200, 200, 200), 1, wx.SOLID) dc.SetBrush(wbrush) dc.SetPen(wpen) dc.ResetBoundingBox() dc.BeginDrawing() x, y, left, right, bottom, top = [ int(val) for val in x, y, left, right, bottom, top ] self.erase_cursor() line1 = (x, bottom, x, top) line2 = (left, y, right, y) self.lastInfo = line1, line2, ax, dc dc.DrawLine(*line1) # draw new dc.DrawLine(*line2) # draw new dc.EndDrawing() time, price = event.xdata, event.ydata self.statusBar.SetStatusText('Time=%f Price=%f' % (time, price), 0) def erase_cursor(self): try: lastline1, lastline2, lastax, lastdc = self.lastInfo except AttributeError: pass else: lastdc.DrawLine(*lastline1) # erase old lastdc.DrawLine(*lastline2) # erase old
class MegaPlotWindow(PlotWindow): """Specialized four-panel PlotWindow for displaying A, B, and C scans of a three-dimensional dataset""" def __init__(self, parent, data_file): self.parent = parent self.data_file = data_file self.controller = MegaPlotWindowController(self, data_file) module_logger.info("Successfully initialized MegaPlotWindow.") self.load_data() @property def axes(self): """Returns a tuple of all the view's axes""" return (self.ascan_axes, self.hbscan_axes, self.vbscan_axes, self.cscan_axes) def init_ui(self): """Creates the PlotWindow UI""" parent_x, parent_y = self.parent.GetPositionTuple() parent_w, parent_h = self.parent.GetSize() self.SetPosition((parent_x + parent_w + ui_defaults.widget_margin, ui_defaults.widget_margin)) self.main_panel = wx.Panel(self) self.main_panel_sizer = wx.BoxSizer(wx.VERTICAL) self.sizer = wx.BoxSizer(wx.VERTICAL) # Controls for specifying (x,y,z) position in 3D dataset self.ctrl_panel = wx.Panel(self.main_panel) self.ctrl_sizer = wx.BoxSizer(wx.HORIZONTAL) info_lbl = wx.StaticText(self.ctrl_panel, wx.ID_ANY, u"Coordinates In Data:", wx.DefaultPosition, wx.DefaultSize) self.ctrl_sizer.Add(info_lbl, ui_defaults.lbl_pct, ui_defaults.lblsizer_flags, ui_defaults.widget_margin) xpos_lbl = wx.StaticText(self.ctrl_panel, wx.ID_ANY, u"X Position", wx.DefaultPosition, wx.DefaultSize) self.ctrl_sizer.Add(xpos_lbl, ui_defaults.lbl_pct, ui_defaults.lblsizer_flags, ui_defaults.widget_margin) self.xpos_sc = wx.SpinCtrl(self.ctrl_panel, wx.ID_ANY, value="", min=0, max=self.controller.data.shape[1] - 1) self.Bind(wx.EVT_SPINCTRL, self.controller.on_xy_change, self.xpos_sc) self.ctrl_sizer.Add(self.xpos_sc, ui_defaults.ctrl_pct, ui_defaults.sizer_flags, ui_defaults.widget_margin) ypos_lbl = wx.StaticText(self.ctrl_panel, wx.ID_ANY, u"Y Position", wx.DefaultPosition, wx.DefaultSize) self.ctrl_sizer.Add(ypos_lbl, ui_defaults.lbl_pct, ui_defaults.lblsizer_flags, ui_defaults.widget_margin) self.ypos_sc = wx.SpinCtrl(self.ctrl_panel, wx.ID_ANY, value="", min=0, max=self.controller.data.shape[0] - 1) self.Bind(wx.EVT_SPINCTRL, self.controller.on_xy_change, self.ypos_sc) self.ctrl_sizer.Add(self.ypos_sc, ui_defaults.ctrl_pct, ui_defaults.sizer_flags, ui_defaults.widget_margin) self.slice_cb = wx.CheckBox(self.ctrl_panel, wx.ID_ANY, "Plot Z Index As C Scan", style=wx.ALIGN_RIGHT) self.slice_cb.SetToolTipString( u"Use the specified index in Z as the C Scan plot data") self.slice_cb.SetValue(True) self.ctrl_sizer.Add(self.slice_cb, ui_defaults.lbl_pct, ui_defaults.sizer_flags, ui_defaults.widget_margin) self.slice_sc = wx.SpinCtrl(self.ctrl_panel, wx.ID_ANY, value="", min=0, max=self.controller.data.shape[2] - 1) self.Bind(wx.EVT_SPINCTRL, self.controller.on_sliceidx_change, self.slice_sc) slice_lbl = wx.StaticText(self.ctrl_panel, wx.ID_ANY, u"Slice Index", wx.DefaultPosition, wx.DefaultSize) self.ctrl_sizer.Add(slice_lbl, ui_defaults.lbl_pct, ui_defaults.lblsizer_flags, ui_defaults.widget_margin) self.ctrl_sizer.Add(self.slice_sc, ui_defaults.ctrl_pct, ui_defaults.sizer_flags, ui_defaults.widget_margin) self.ctrl_panel.SetSizerAndFit(self.ctrl_sizer) self.main_panel_sizer.Add(self.ctrl_panel, ui_defaults.lbl_pct, ui_defaults.sizer_flags, ui_defaults.widget_margin) self.figure = Figure() self.canvas = FigureCanvas(self.main_panel, wx.ID_ANY, self.figure) self.ascan_axes = self.figure.add_subplot(221) self.vbscan_axes = self.figure.add_subplot(222) self.hbscan_axes = self.figure.add_subplot(223) self.cscan_axes = self.figure.add_subplot(224) self.cscan_cursor = Cursor(self.cscan_axes, useblit=True, color="#4F6581", alpha=0.5) self.figure.canvas.mpl_connect("button_press_event", self.controller.on_click) self.main_panel_sizer.Add(self.canvas, 1, ui_defaults.sizer_flags, 0) self.navtools_cb = wx.CheckBox(self.main_panel, wx.ID_ANY, "Use Plot Navigation Tools") self.navtools_cb.SetValue(self.controller.get_navtools_config()) self.navtools_cb.SetToolTipString("Check to use pan/zoom tools") self.Bind(wx.EVT_CHECKBOX, self.controller.on_check_navtools, self.navtools_cb) self.main_panel_sizer.Add(self.navtools_cb, ui_defaults.lbl_pct, ui_defaults.sizer_flags, ui_defaults.widget_margin) self.add_toolbar() self.SetIcon(self.parent.GetIcon()) self.main_panel.SetSizerAndFit(self.main_panel_sizer) self.sizer.Add(self.main_panel, 1, ui_defaults.sizer_flags, 0) self.SetSizerAndFit(self.sizer) def add_toolbar(self): """Creates the matplotlib toolbar (zoom, pan/scroll, etc.) for the plot""" 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.main_panel_sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND, 0) self.toolbar.update() self.toggle_toolbar() def toggle_toolbar(self): """Enables / disables the navigation toolbar and sets cursors accordingly.""" if self.navtools_enabled(): self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) else: self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_CROSS)) self.toolbar.Enable(self.navtools_enabled()) self.controller.set_navtools_config(self.navtools_enabled()) def init_plot_menu(self): """Creates the Plot menu""" self.plot_mnu = wx.Menu() self.labels_mnu = wx.Menu() # Titles and Labels plottitle_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set Plot Title", help="Set Plot Title") self.Bind(wx.EVT_MENU, self.controller.on_set_plottitle, id=plottitle_mnui.GetId()) self.labels_mnu.AppendItem(plottitle_mnui) xlbl_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set X Axis Label", help="Set X Axis Label") self.Bind(wx.EVT_MENU, self.controller.on_set_xlabel, id=xlbl_mnui.GetId()) self.labels_mnu.AppendItem(xlbl_mnui) ylbl_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set Y Axis Label", help="Set Y Axis Label") self.Bind(wx.EVT_MENU, self.controller.on_set_ylabel, id=ylbl_mnui.GetId()) self.labels_mnu.AppendItem(ylbl_mnui) cbarlbl_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text='Set Colorbar Label', help='Set Colorbar Label') self.Bind(wx.EVT_MENU, self.controller.on_set_cbarlbl, id=cbarlbl_mnui.GetId()) self.labels_mnu.AppendItem(cbarlbl_mnui) self.plot_mnu.AppendMenu(wx.ID_ANY, "Title And Labels", self.labels_mnu) self.colormaps_mnu = wx.Menu() # Colormaps self.preview_cmaps_mnui = wx.MenuItem( self.colormaps_mnu, wx.ID_ANY, text='Preview Colormaps', help='Preview available colormaps') self.Bind(wx.EVT_MENU, self.controller.on_preview_cmaps, id=self.preview_cmaps_mnui.GetId()) self.colormaps_mnu.AppendItem(self.preview_cmaps_mnui) self.select_cmap_mnui = wx.MenuItem(self.colormaps_mnu, wx.ID_ANY, text='Select Colormap...', help='Selects colormap') self.Bind(wx.EVT_MENU, self.controller.on_select_cmap, id=self.select_cmap_mnui.GetId()) self.colormaps_mnu.AppendItem(self.select_cmap_mnui) self.create_cmap_mnui = wx.MenuItem(self.colormaps_mnu, wx.ID_ANY, text='Create Colormap...', help='Create or edit a colormap') self.colormaps_mnu.AppendItem(self.create_cmap_mnui) self.Bind(wx.EVT_MENU, self.controller.on_create_cmap, id=self.create_cmap_mnui.GetId()) self.plot_mnu.AppendMenu(wx.ID_ANY, "Colormaps", self.colormaps_mnu) self.show_colorbar_mnui = wx.MenuItem( self.plot_mnu, wx.ID_ANY, text="Show Colorbar", help="Show color scale in image plot", kind=wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.controller.on_toggle_colorbar, id=self.show_colorbar_mnui.GetId()) self.plot_mnu.AppendItem(self.show_colorbar_mnui) self.show_colorbar_mnui.Check(self.controller.get_colorbar_config()) self.plot_conventional_bscans_mnui = wx.MenuItem( self.plot_mnu, wx.ID_ANY, text="Plot Conventional B-scans", help="Plot conventional 2D B-scans", kind=wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.controller.on_change_bscans, id=self.plot_conventional_bscans_mnui.GetId()) self.plot_mnu.AppendItem(self.plot_conventional_bscans_mnui) self.plot_conventional_bscans_mnui.Check( self.controller.conventional_bscans) gridtoggle_mnui = wx.MenuItem(self.plot_mnu, wx.ID_ANY, text="Toggle Grid", help="Turns grid on or off") self.plot_mnu.AppendItem(gridtoggle_mnui) self.Bind(wx.EVT_MENU, self.controller.on_toggle_grid, id=gridtoggle_mnui.GetId()) self.menubar.Append(self.plot_mnu, "&Plot") def init_specific_ops_menu(self): """Creates any plot-specific Operations menu items""" self.setcscan_mnui = wx.MenuItem( self.ops_mnu, wx.ID_ANY, text="Define C Scan", help="Specify function to generate C Scan") self.Bind(wx.EVT_MENU, self.controller.on_define_cscan, id=self.setcscan_mnui.GetId()) self.ops_mnu.AppendItem(self.setcscan_mnui) self.rect_mnu = wx.Menu() # Rectification operations self.fullrect_mnui = wx.MenuItem(self.rect_mnu, wx.ID_ANY, text="Full", help="Full Rectification") self.Bind(wx.EVT_MENU, self.controller.on_rectify, id=self.fullrect_mnui.GetId()) self.rect_mnu.AppendItem(self.fullrect_mnui) self.ops_mnu.AppendMenu(wx.ID_ANY, 'Rectify', self.rect_mnu) self.gate_mnu = wx.Menu() # Gates operations for gate in self.controller.gates: gate_name = self.controller.gates[gate][0] gate_desc = "Applies a {0} gate function to the data".format( gate_name) gate_mnui = wx.MenuItem(self.gate_mnu, id=gate, text=gate_name, help=gate_desc) self.gate_mnu.AppendItem(gate_mnui) self.Bind(wx.EVT_MENU, self.controller.on_apply_gate, id=gate_mnui.GetId()) self.ops_mnu.AppendMenu(wx.ID_ANY, 'Gates', self.gate_mnu) def navtools_enabled(self): """Returns True if plot navigation bar is enabled""" return self.navtools_cb.IsChecked() @property def plot_conventional_bscans(self): """True if the Bscan plots should be conventional 2D imgplots vs. the original Megaplot 1D""" return self.plot_conventional_bscans_mnui.IsChecked() @plot_conventional_bscans.setter def plot_conventional_bscans(self, on=True): """Sets the use of conventional Bscans or the original 1D Megaplot Bscans""" self.plot_conventional_bscans_mnui.Check(on) @property def plot_linear_bscans(self): """True if the Bscan plots should be the original 1D Megaplot plots""" return not self.plot_conventional_bscans
class PlotWindow(wx.Frame): """Basic wxPython UI element for displaying matplotlib plots""" def __init__(self, parent, data_file): self.parent = parent self.data_file = data_file self.controller = PlotWindowController(self, data_file) module_logger.info("Successfully initialized PlotWindow.") self.load_data() def has_data(self): """Returns True if data is not None""" return self.controller.data is not None def load_data(self): """Loads the data set and plots""" exception_queue = Queue.Queue() data_thd = workerthread.WorkerThread(exception_queue=exception_queue, target=self.controller.load_data) data_thd.start() while True: data_thd.join(0.125) if not data_thd.is_alive(): try: exc_type, exc = exception_queue.get(block=False) err_str = str(exc) if len(err_str) == 0: err_str = exc_type.__name__ module_logger.error( "Unable to load data: {0}".format(err_str)) err_msg = "An error occurred while loading data:\n{0}".format( err_str) if len(err_msg) > 150: # Truncate lengthy error messages err_msg = ''.join([err_msg[:150], "\n(continued)"]) err_dlg = wx.MessageDialog(self.parent, message=err_msg, caption="Unable To Load Data", style=wx.ICON_ERROR) err_dlg.ShowModal() except Queue.Empty: pass break wx.GetApp().Yield(True) if self.has_data(): self.title = 'Plot - {0}'.format(os.path.basename(self.data_file)) wx.Frame.__init__(self, id=wx.ID_ANY, parent=self.parent, title=self.title) self.init_menu() self.init_ui() self.controller.plot(self.controller.data) def init_ui(self): """Creates the PlotWindow UI""" parent_x, parent_y = self.parent.GetPositionTuple() parent_w, parent_h = self.parent.GetSize() self.SetPosition((parent_x + parent_w + ui_defaults.widget_margin, ui_defaults.widget_margin)) self.sizer = wx.BoxSizer(wx.VERTICAL) self.figure = Figure(figsize=(5, 4)) self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure) self.axes = self.figure.add_subplot(111, picker=True) self.axes.grid(True) #self.cursor = Cursor(self.axes, useblit=True, color='green', alpha=0.5, linestyle='--', # linewidth=2) self.sizer.Add(self.canvas, 1, ui_defaults.sizer_flags, 0) self.add_toolbar() self.SetIcon(self.parent.GetIcon()) self.SetSizerAndFit(self.sizer) def add_toolbar(self): """Creates the matplotlib toolbar (zoom, pan/scroll, etc.) for the plot""" 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, 0) self.toolbar.update() def init_menu(self): """Creates the main menu""" self.menubar = wx.MenuBar() self.init_file_menu() self.init_plot_menu() self.init_ops_menu() self.init_tools_menu() self.init_help_menu() self.SetMenuBar(self.menubar) def init_file_menu(self): """Creates the File menu""" self.file_mnu = wx.Menu() savedata_mnui = wx.MenuItem(self.file_mnu, wx.ID_ANY, text="Save Current Data", help="Save current data to disk") self.Bind(wx.EVT_MENU, self.controller.on_save_data, id=savedata_mnui.GetId()) self.file_mnu.AppendItem(savedata_mnui) close_mnui = wx.MenuItem(self.file_mnu, wx.ID_ANY, text="Close Window", help="Close the plot window") self.Bind(wx.EVT_MENU, self.controller.on_close, id=close_mnui.GetId()) self.file_mnu.AppendItem(close_mnui) self.menubar.Append(self.file_mnu, "&File") def init_plot_menu(self): """Creates the Plot menu""" self.plot_mnu = wx.Menu() self.labels_mnu = wx.Menu() # Titles and Labels plottitle_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set Plot Title", help="Set Plot Title") self.Bind(wx.EVT_MENU, self.controller.on_set_plottitle, id=plottitle_mnui.GetId()) self.labels_mnu.AppendItem(plottitle_mnui) xlbl_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set X Axis Label", help="Set X Axis Label") self.Bind(wx.EVT_MENU, self.controller.on_set_xlabel, id=xlbl_mnui.GetId()) self.labels_mnu.AppendItem(xlbl_mnui) ylbl_mnui = wx.MenuItem(self.labels_mnu, wx.ID_ANY, text="Set Y Axis Label", help="Set Y Axis Label") self.Bind(wx.EVT_MENU, self.controller.on_set_ylabel, id=ylbl_mnui.GetId()) self.labels_mnu.AppendItem(ylbl_mnui) self.plot_mnu.AppendMenu(wx.ID_ANY, 'Title And Labels', self.labels_mnu) gridtoggle_mnui = wx.MenuItem(self.plot_mnu, wx.ID_ANY, text="Toggle Grid", help="Turns grid on or off") self.plot_mnu.AppendItem(gridtoggle_mnui) self.Bind(wx.EVT_MENU, self.controller.on_toggle_grid, id=gridtoggle_mnui.GetId()) self.menubar.Append(self.plot_mnu, "&Plot") def init_ops_menu(self): """Creates the Operations menu""" self.ops_mnu = wx.Menu() self.revert_mnui = wx.MenuItem(self.ops_mnu, wx.ID_ANY, text='Revert To Original', help='Revert to original data set') self.Bind(wx.EVT_MENU, self.controller.on_revert, id=self.revert_mnui.GetId()) self.ops_mnu.AppendItem(self.revert_mnui) self.init_specific_ops_menu() self.menubar.Append(self.ops_mnu, '&Operations') def init_specific_ops_menu(self): """Creates any plot-specific Operations menu items""" self.rect_mnu = wx.Menu() # Rectification operations self.fullrect_mnui = wx.MenuItem(self.rect_mnu, wx.ID_ANY, text="Full", help="Full Rectification") self.Bind(wx.EVT_MENU, self.controller.on_rectify, id=self.fullrect_mnui.GetId()) self.rect_mnu.AppendItem(self.fullrect_mnui) self.ops_mnu.AppendMenu(wx.ID_ANY, 'Rectify', self.rect_mnu) self.gate_mnu = wx.Menu() # Gates operations for gate in self.controller.gates: gate_name = self.controller.gates[gate][0] gate_desc = "Applies a {0} gate function to the data".format( gate_name) gate_mnui = wx.MenuItem(self.gate_mnu, id=gate, text=gate_name, help=gate_desc) self.gate_mnu.AppendItem(gate_mnui) self.Bind(wx.EVT_MENU, self.controller.on_apply_gate, id=gate_mnui.GetId()) self.ops_mnu.AppendMenu(wx.ID_ANY, 'Gates', self.gate_mnu) def init_tools_menu(self): """Initializes the Tools Menu (Plugins and external scripts)""" self.tools_mnu = wx.Menu() self.init_plugins_menu() self.menubar.Append(self.tools_mnu, '&Tools') def init_plugins_menu(self): """Initializes the Plugins menu""" # If the Plugins menu already exists, # delete and rebuild. Used to refresh # list of available plugins after installing # a new one plugins_mnu_id = self.tools_mnu.FindItem("Plugins") if plugins_mnu_id != -1: self.tools_mnu.RemoveItem( self.tools_mnu.FindItemById(plugins_mnu_id)) self.plugins_mnu = wx.Menu() plugins = self.controller.available_plugins for plugin_id, plugin in plugins.items(): plugin_name = plugin[1].name plugin_description = plugin[1].description script_mnui = wx.MenuItem(self.tools_mnu, id=plugin_id, text=plugin_name, help=plugin_description) self.Bind(wx.EVT_MENU, self.controller.on_run_toolkit, id=script_mnui.GetId()) self.plugins_mnu.AppendItem(script_mnui) self.plugins_mnu.AppendSeparator() install_plugin_mnui = wx.MenuItem(self.plugins_mnu, wx.ID_ANY, text="Install Plugin...", help="Install a local plugin") self.Bind(wx.EVT_MENU, self.controller.on_install_plugin, id=install_plugin_mnui.GetId()) self.plugins_mnu.AppendItem(install_plugin_mnui) download_plugin_mnui = wx.MenuItem( self.plugins_mnu, wx.ID_ANY, text="Download Plugin...", help="Download and install a new plugin") self.Bind(wx.EVT_MENU, self.controller.on_download_plugin, id=download_plugin_mnui.GetId()) self.plugins_mnu.AppendItem(download_plugin_mnui) self.tools_mnu.AppendMenu(wx.ID_ANY, "Plugins", self.plugins_mnu) def init_help_menu(self): pass
class PlotFigure(Frame): def __init__(self): Frame.__init__(self, None, -1, "96 Well Plate - Dynamic Heat Map") self.fig = Figure((8, 6), 100) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() # On Windows, default frame size behaviour is incorrect # you don't need this under Linux tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(Size(fw, th)) # Create a figure manager to manage things # Now put all into a sizer sizer = BoxSizer(VERTICAL) # This way of adding to sizer allows resizing sizer.Add(self.canvas, 1, LEFT | TOP | GROW) # Best to allow the toolbar to resize! sizer.Add(self.toolbar, 0, GROW) self.SetSizer(sizer) self.Fit() EVT_TIMER(self, TIMER_ID, self.onTimer) def init_plot_data(self): # read in cell numbers self.Nr = int(options.rows) self.Nc = int(options.columns) print "Number of Wells: ", self.Nr * self.Nc # initialize data array and plot for the 1st time self.data = np.zeros([self.Nr * self.Nc]) # create matrix which will contain the number of counted cells well96 = np.zeros([self.Nr, self.Nc]) # labeling schemes LabelX = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24' ] LabelY = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' ] labelx = LabelX[0:self.Nc] labely = LabelY[0:self.Nr] print "Label X: ", labelx print "Label Y: ", labely self.ax1 = self.fig.add_axes([0.075, 0.1, 0.75, 0.85]) self.cax = self.fig.add_axes([0.85, 0.1, 0.075, 0.85]) self.im = self.ax1.imshow(well96, cmap=cm.jet, interpolation='nearest') self.fig.colorbar(self.im, cax=self.cax, orientation='vertical') self.ax1.set_xticks(np.arange(0, self.Nc, 1)) self.ax1.set_xticklabels(labelx) self.ax1.set_yticks(np.arange(0, self.Nr, 1)) self.ax1.set_yticklabels(labely) self.ax1.set_title('Cell Count per Well') self.figure_saved = False def onTimer(self, evt): datain = np.loadtxt(options.filename, delimiter='\t') current_well = datain.shape[0] #print current_well self.data[0:len(datain[:, 1])] = datain[:, 1] welldata = self.data.reshape(self.Nr, self.Nc) #print welldata #self.im.set_array(welldata) self.im = self.ax1.imshow(welldata, vmin=datain[:, 1].min(), vmax=datain[:, 1].max(), cmap=cm.jet, interpolation='nearest') self.fig.colorbar(self.im, cax=self.cax, orientation='vertical') self.canvas.draw() # save plot only when done and only once if (current_well == self.Nr * self.Nc and self.figure_saved == False): self.fig.savefig(savename) self.figure_saved = True
class CanvasFrame(wxFrame): def __init__(self): wxFrame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(wxNamedColor("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.axes.set_xlabel('Time (s)') self.axes.set_ylabel('Price ($)') self.canvas = FigureCanvas(self, -1, self.figure) self.canvas.mpl_connect('motion_notify_event', self.mouse_move) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxLEFT | wxTOP | wxGROW) self.SetSizer(self.sizer) self.Fit() self.statusBar = wxStatusBar(self, -1) self.statusBar.SetFieldsCount(1) self.SetStatusBar(self.statusBar) self.add_toolbar() # comment this out for no toolbar EVT_PAINT(self, self.OnPaint) def mouse_move(self, event): self.draw_cursor(event) def add_toolbar(self): self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wxSize(fw, th)) self.sizer.Add(self.toolbar, 0, wxLEFT | wxEXPAND) # update the axes menu on the toolbar self.toolbar.update() def OnPaint(self, event): self.erase_cursor() try: del self.lastInfo except AttributeError: pass self.canvas.draw() event.Skip() def draw_cursor(self, event): 'event is a MplEvent. Draw a cursor over the axes' if event.inaxes is None: self.erase_cursor() try: del self.lastInfo except AttributeError: pass return canvas = self.canvas figheight = canvas.figure.bbox.height() ax = event.inaxes left,bottom,width,height = ax.bbox.get_bounds() bottom = figheight-bottom top = bottom - height right = left + width x, y = event.x, event.y y = figheight-y dc = wxClientDC(canvas) dc.SetLogicalFunction(wxXOR) wbrush = wxBrush(wxColour(255,255,255), wxTRANSPARENT) wpen = wxPen(wxColour(200, 200, 200), 1, wxSOLID) dc.SetBrush(wbrush) dc.SetPen(wpen) dc.ResetBoundingBox() dc.BeginDrawing() x, y, left, right, bottom, top = [int(val) for val in x, y, left, right, bottom, top] self.erase_cursor() line1 = (x, bottom, x, top) line2 = (left, y, right, y) self.lastInfo = line1, line2, ax, dc dc.DrawLine(*line1) # draw new dc.DrawLine(*line2) # draw new dc.EndDrawing() time, price = event.xdata, event.ydata self.statusBar.SetStatusText("Time=%f Price=%f"% (time, price), 0) def erase_cursor(self): try: lastline1, lastline2, lastax, lastdc = self.lastInfo except AttributeError: pass else: lastdc.DrawLine(*lastline1) # erase old lastdc.DrawLine(*lastline2) # erase old
class UI(wx.Frame): """Basic wxPython user interface""" def __init__(self, *args, **kwargs): self.base_title = "Gocator Profile Plotter" wx.Frame.__init__(self, parent=None, title=self.base_title, *args, **kwargs) self.init_ui() self.data_fname = None def init_ui(self): """Creates the user interface""" self.init_menu() self.SetSize(wx.Size(640, 480)) self.main_panel = wx.Panel(self) self.main_panel_sizer = wx.BoxSizer(wx.VERTICAL) self.figure = Figure() self.canvas = FigureCanvas(self.main_panel, wx.ID_ANY, self.figure) self.main_panel_sizer.Add(self.canvas, 1, sizer_flags, 0) 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.main_panel_sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND, 0) self.toolbar.update() self.main_panel.SetSizerAndFit(self.main_panel_sizer) def init_menu(self): """Creates the main menu""" self.menubar = wx.MenuBar() self.file_mnu = wx.Menu() self.plotdata_mnui = wx.MenuItem( self.file_mnu, wx.ID_ANY, text="Plot Data...\tCTRL+O", help="Reads and plots an XYZ CSV data file") self.Bind(wx.EVT_MENU, self.on_plot_data, id=self.plotdata_mnui.GetId()) self.file_mnu.AppendItem(self.plotdata_mnui) plottype_mnu = wx.Menu() self.plot_pointcloud_mnui = wx.MenuItem( plottype_mnu, wx.ID_ANY, text="Point Cloud", help="Plots the laser profile as a point cloud", kind=wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.on_plot_type, id=self.plot_pointcloud_mnui.GetId()) plottype_mnu.AppendItem(self.plot_pointcloud_mnui) self.plot_surface_mnui = wx.MenuItem( plottype_mnu, wx.ID_ANY, text="Fitted Surface", help="Plots the laser profile as an interpolated surface", kind=wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.on_plot_type, id=self.plot_surface_mnui.GetId()) plottype_mnu.AppendItem(self.plot_surface_mnui) self.plot_wireframe_mnui = wx.MenuItem( plottype_mnu, wx.ID_ANY, text="Fitted Wireframe Surface", help="Plots the laser profile as an interpolated wireframe surface", kind=wx.ITEM_RADIO) plottype_mnu.AppendItem(self.plot_wireframe_mnui) self.Bind(wx.EVT_MENU, self.on_plot_type, id=self.plot_wireframe_mnui.GetId()) self.file_mnu.AppendSubMenu(plottype_mnu, "Type Of Plot") self.plotrawdata = wx.MenuItem(self.file_mnu, wx.ID_ANY, text="Plot Raw Data", help="Plot raw vs. filtered data", kind=wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.on_filter_data, id=self.plotrawdata.GetId()) self.file_mnu.AppendItem(self.plotrawdata) self.setzlim_mnui = wx.MenuItem(self.file_mnu, wx.ID_ANY, text="Set Z Axis Limits...\tCTRL+Z", help="Sets the limits of the Z Axis") self.Bind(wx.EVT_MENU, self.on_setzlim, id=self.setzlim_mnui.GetId()) self.file_mnu.AppendItem(self.setzlim_mnui) self.quit_mnui = wx.MenuItem(self.file_mnu, wx.ID_ANY, text="Exit Plotter\tCTRL+Q") self.Bind(wx.EVT_MENU, self.on_quit, id=self.quit_mnui.GetId()) self.file_mnu.AppendItem(self.quit_mnui) self.menubar.Append(self.file_mnu, "Operation") self.SetMenuBar(self.menubar) def on_plot_data(self, evt): """Handles request to plot data""" allfiles_wildcard = "All Files (*.*)|*.*" txt_wildcards = "Text Files|*.txt;*.csv;*.dat;*.tab;*.asc" wildcards = "|".join([txt_wildcards, allfiles_wildcard]) file_dlg = wx.FileDialog(parent=self, message="Please specify a file", wildcard=wildcards, style=wx.FD_OPEN) if file_dlg.ShowModal() == wx.ID_OK: self.data_fname = file_dlg.GetPath() self.plot_data(self.data_fname) self.SetTitle(' - '.join( [self.base_title, os.path.basename(self.data_fname)])) def plot_data(self, data_fname): """Reads and plots the specified data file""" self.figure.clf() self.axes = self.figure.add_subplot(111, projection='3d') self.axes.grid(True) try: wx.BeginBusyCursor() x, y, z = self.get_data(data_fname) if self.plot_pointcloud_mnui.IsChecked(): # Plot a point cloud self.axes.plot(x, y, z, c='#4F6581', linestyle='', marker=',', rasterized=True) else: xi = np.linspace(min(x), max(x), num=100) yi = np.linspace(min(y), max(y), num=100) X, Y = np.meshgrid(xi, yi) Z = griddata(x, y, z, xi, yi) if self.plot_surface_mnui.IsChecked(): # Interpolate a surface from the point cloud to plot surf = self.axes.plot_surface(X, Y, Z, rstride=3, cstride=3, cmap=cm.get_cmap('spectral'), linewidth=1, antialiased=True) colorbar = self.figure.colorbar(surf) colorbar.set_label("Z Position [mm]") elif self.plot_wireframe_mnui.IsChecked(): # Interpolate a wireframe surface from the point cloud to plot # Uses a higher resolution presentation than the surface - surface tends to bog down # on some systems with stride set to 1 surf = self.axes.plot_wireframe(X, Y, Z, rstride=1, cstride=1, color='#4F6581', linewidth=1, antialiased=True) self.axes.set_zlim3d(np.min(Z), np.max(Z)) self.axes.set_xlabel('X Position [mm]') self.axes.set_ylabel('Y Position [mm]') self.axes.set_zlabel('Z Position [mm]') self.axes.set_title(os.path.basename(self.data_fname)) self.refresh_plot() except IOError: # no data err_dlg = wx.MessageDialog( self, caption="Invalid Data File", message="Unable to read data from {0}.".format(data_fname), style=wx.ICON_ERROR) err_dlg.ShowModal() err_dlg.Destroy() return except ValueError: # couldn't convert to floating point err_dlg = wx.MessageDialog( self, caption="Invalid Input", message= "An error occurred reading the data.\nPlease ensure the data is properly formatted.", style=wx.ICON_ERROR) err_dlg.ShowModal() err_dlg.Destroy() return finally: wx.EndBusyCursor() def get_data(self, data_fname): """Reads the specified data file, optionally filtering the data before returning it as X,Y,Z.""" x, y, z = np.genfromtxt(data_fname, delimiter=",", unpack=True) if not self.plotrawdata.IsChecked(): xi = x[z > -20] yi = y[z > -20] zi = scipy.signal.wiener(z[z > -20], mysize=15, noise=1) else: xi = x yi = y zi = z return xi, yi, zi def get_zlim(self): """Wrapper for matplotlib API changes in retrieving Z limits""" try: min_val, max_val = self.axes.get_zlim() except AttributeError: min_val, max_val = self.axes.get_zlim3d() finally: return min_val, max_val def set_zlim(self, limits_tuple): """Wrapper for matplotlib API changes in setting Z limits""" try: self.axes.set_zlim(limits_tuple) except AttributeError: self.axes.set_zlim3d(limits_tuple) def on_setzlim(self, evt): """Handles request to reset the Z axis limits""" if hasattr(self, 'axes'): rng_dlg = FloatRangeDialog(dlg_title="Set Z Axis Limits") min_val, max_val = self.get_zlim() rng_dlg.setValues(min_val, max_val) if rng_dlg.ShowModal() == wx.ID_OK: min_val, max_val = rng_dlg.GetValue() if min_val is not None and max_val is not None: self.set_zlim((min_val, max_val)) self.refresh_plot() rng_dlg.Destroy() def on_plot_type(self, evt): """Handles change in choice of plot type""" if hasattr(self, 'data_fname'): if self.data_fname is not None: axis_limits = self.get_zlim() self.plot_data(self.data_fname) self.set_zlim(axis_limits) self.refresh_plot() def on_filter_data(self, evt): """Handles change in choice of filtering data""" if hasattr(self, 'data_fname'): if self.data_fname is not None: self.plot_data(self.data_fname) def refresh_plot(self): """Forces plot to redraw itself""" self.canvas.draw() def on_quit(self, evt): """Handles request to exit the program""" self.Destroy()
class CanvasFrameRetMap(wxFrame): def __init__(self): wxFrame.__init__(self, None, -1, 'Return Map', size=(1700, 900)) IBIs = [] IBITimes = [] for i in range(len(pixelvec)): ibis = [] timeZ = [] j = 0 thresh = Threshold[i] print thresh xlp = FilteredLongTS[i] for i in range(2 * 71990): #for i in range(len(longvec)-1): j += 1 if ((xlp[i] < thresh) & (xlp[i + 1] > thresh)): ibis.append(j) timeZ.append(i) j = 0 print 'ibis length, i ', len(ibis), i IBIs.append(ibis) IBITimes.append(timeZ) # print LongTSPixelMat print len(LongTSPixelMat) IBIsA = [] IBIsB = [] for i in range(len(pixelvec)): ibisa = IBIs[i][0:len(IBIs[i]) - 1] ibisb = IBIs[i][1:len(IBIs[i])] IBIsA.append(ibisa) IBIsB.append(ibisb) print 'IBI len ', len(IBIs[0]) print 'IBIsA len ', len(IBIsA) self.SetBackgroundColour(wxNamedColor("BLACK")) # print Threshold self.figure = Figure(figsize=(6, 6), dpi=150) self.axes1 = self.figure.add_subplot(231) self.axes2 = self.figure.add_subplot(232) self.axes2.set_title(str(FileString[0])) self.axes3 = self.figure.add_subplot(233) self.axes4 = self.figure.add_subplot(234) self.axes5 = self.figure.add_subplot(235) # self.axes5.set_xlabel(str(FileString[0]), fontsize = 8) self.axes5.set_xlabel('dfgs', fontsize=8) if (len(pixelvec) > 0): self.axes1.plot(IBIsA[0], IBIsB[0], '.', markersize=2) self.axes1.plot(range(300)) self.axes1.set_xlim([-10, 300]) self.axes1.set_ylim([-10, 300]) self.axes1.set_xlabel(str(coords[0]), fontsize=8) if (len(pixelvec) > 1): self.axes2.plot(IBIsA[1], IBIsB[1], '.', markersize=2) self.axes2.plot(range(300)) self.axes2.set_xlim([-10, 300]) self.axes2.set_ylim([-10, 300]) self.axes2.set_xlabel(str(coords[1]), fontsize=8) if (len(pixelvec) > 2): self.axes3.plot(IBIsA[2], IBIsB[2], '.', markersize=2) self.axes3.plot(range(300)) self.axes3.set_xlim([-10, 300]) self.axes3.set_ylim([-10, 300]) self.axes3.set_xlabel(str(coords[2]), fontsize=8) if (len(pixelvec) > 3): self.axes4.plot(IBIsA[3], IBIsB[3], '.', markersize=2) self.axes4.plot(range(300)) self.axes4.set_xlim([-10, 300]) self.axes4.set_xlabel(str(coords[3]), fontsize=8) self.axes4.set_ylim([-10, 300]) if (len(pixelvec) > 4): self.axes5.plot(IBIsA[4], IBIsB[4], '.', markersize=2) self.axes5.plot(range(300)) self.axes5.set_xlim([-10, 300]) self.axes5.set_ylim([-10, 300]) self.axes5.set_xlabel(str(coords[4]), fontsize=8) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) self.toolbar = MyNavigationToolbar(self.canvas, True) self.toolbar.Realize() if wxPlatform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wxSize(fw, th)) self.sizer.Add(self.toolbar, 0, wxLEFT | wxEXPAND) # 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 RetMapSection(wxFrame): def __init__(self): wxFrame.__init__(self, None, -1, 'Return Map', size=(1700, 900)) print RetMapLims[0] print RetMapLims[1] print ChosenIBIMap i = ChosenIBIMap[len(ChosenIBIMap) - 1] - 1 k = i ibis = [] timeZ = [] j = 0 thresh = Threshold[i] print thresh xlp = FilteredLongTS[i] print len(xlp), 'xlp' RMVec = xlp[RetMapLims[0]:RetMapLims[1]] print len(RMVec), 'RMVec' for i in range(len(RMVec) - 1): #for i in range(len(longvec)-1): j += 1 if ((RMVec[i] < thresh) & (RMVec[i + 1] > thresh)): ibis.append(j) timeZ.append(i) j = 0 print 'ibis length, i ', len(ibis), i ibisa = ibis[0:len(ibis) - 1] ibisb = ibis[1:len(ibis)] self.SetBackgroundColour(wxNamedColor("BLACK")) # print Threshold self.figure = Figure(figsize=(6, 6), dpi=150) self.axes1 = self.figure.add_subplot(111) self.axes1.set_title(str(FileString[0]), fontsize=12) self.axes1.plot(ibisa, ibisb, '.', markersize=2) self.axes1.plot(range(300)) self.axes1.set_xlim([-10, 300]) self.axes1.set_ylim([-10, 300]) print k print coords[k] print RetMapLims[0] print RetMapLims[1] self.axes1.set_xlabel(str(coords[k]) + 'Frames ' + str(RetMapLims[0]) + 'to ' + str(RetMapLims[1]), fontsize=8) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) self.toolbar = MyNavigationToolbar(self.canvas, True) self.toolbar.Realize() if wxPlatform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wxSize(fw, th)) self.sizer.Add(self.toolbar, 0, wxLEFT | wxEXPAND) # 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() print RetMapLims[0] print RetMapLims[1] print ChosenIBIMap
class PlotFigure(Frame): def __init__(self): Frame.__init__(self, None, -1, "Test embedded wxFigure") self.fig = Figure((5, 4), 100) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() # On Windows, default frame size behaviour is incorrect # you don't need this under Linux tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(Size(fw, th)) # Create a figure manager to manage things # Now put all into a sizer sizer = BoxSizer(VERTICAL) # This way of adding to sizer allows resizing sizer.Add(self.canvas, 1, LEFT | TOP | GROW) # Best to allow the toolbar to resize! sizer.Add(self.toolbar, 0, GROW) self.SetSizer(sizer) self.Fit() EVT_TIMER(self, TIMER_ID, self.onTimer) def init_plot_data(self): # initialize data array and plot for the 1st time data = np.array([]) # jdh you can add a subplot directly from the fig rather than # the fig manager self.ax1 = self.fig.add_axes([0.15, 0.15, 0.8, 0.8]) # create subplot 1 self.line, = self.ax1.plot(data, 'bo-', lw=2, label='Cell Count') self.ax1.grid(True) self.ax1.set_xlabel('Frame Number') self.ax1.set_ylabel('Cells detected') def GetToolBar(self): # You will need to override GetToolBar if you are using an # unmanaged toolbar in your frame return self.toolbar def onTimer(self, evt): data = np.loadtxt(options.filename, delimiter='\t') self.line.set_xdata(data[:, 0]) # update the data self.line.set_ydata(data[:, 1]) # update the data #self.ax1.autoscale(enable=True, axis='both', tight=False) self.ax1.set_xlim([data[0, 0] - 1, data[-1, 0] + 1]) self.ax1.set_ylim([data[:, 1].min() * 0.9, data[:, 1].max() * 1.1]) self.canvas.draw() #self.canvas.gui_repaint() # jdh wxagg_draw calls this already def onEraseBackground(self, evt): # this is supposed to prevent redraw flicker on some X servers... pass
class AppFrame(wx.Frame): def __init__(self): setBaseDB('dass.db') initializeBaseDB() def makeSP(name, labels, statictexts = None): panel = wx.Panel(self.sidePanel, -1) box = wx.StaticBox(panel,-1, name) sizer = wx.StaticBoxSizer(box, wx.VERTICAL) panel.rangeValue = {} for name, min_value, value, max_value in labels: sp = SpinPanel(panel, name, min_value, value, max_value, self.OnSpinback) panel.rangeValue[name] = sp sizer.Add(sp, 0, wx.EXPAND) print "done" panel.SetSizer(sizer) return panel wx.Frame.__init__(self, None, title = "CLUSTERING ALGORITHM") ################ Adding Drawing Panel ################ self.displayPanel = DisplayPanel(self) self.figure = Figure() self.axes = self.figure.add_subplot(111) self.axes.set_axis_bgcolor('white') self.canvas = Canvas(self.displayPanel, -1, self.figure) ################ Connecting the canvas to events for selecting intial centroid & nuclei ################### self.figure.canvas.mpl_connect('button_press_event', self.onGraphClick) self.figure.canvas.mpl_connect('pick_event', self.onNucleiPick) ################ Connecting the canvas to events for selecting intial centroid & nuclei ################### sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.canvas, 1, wx.EXPAND) self.displayPanel.SetSizer(sizer) self.displayPanel.Fit() self.toolbar = NavigationToolbar(self.canvas) self.SetToolBar(self.toolbar) self.toolbar.Realize() tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wx.Size(fw, th)) self.toolbar.update() self.redraw_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer) self.stopStart = threading.Event() self.data = None self.centroids = [] self.clusterIds = None self.colors = None self.k = 0 self.iterTimer = 0 self.iterations = 20 self.sidePanel = wx.Panel(self) self.pointToPick = 0 self.selectedFeaturesCount = 0 self.isPickCentroids = False ################ Adding Drawing Panel ################ ################ defining features for clustering algorithm ################ self.dictionary = {'Area':'AREA', 'Perimeter':'PERIMETER', 'Roundness':'ROUNDNESS','Equi-Diameter':'EQUI_DIAMETER', 'Orientation':'ORIENTATION', 'Convex Area':'CONVEX_AREA', 'Solidity': 'SOLIDITY', 'Major Axis':'MAJOR_AXIS_LEN','Minor Axis': 'MINOR_AXIS_LEN', 'Eccentricity':'ECCENTRICITY', 'Min Enclosing Rad':'CIR_RADIUS', 'Shape Index':'SHAPE_INDEX','Border Index':'BORDER_INDEX','Aspect Ratio':'ASPECT_RATION', 'Mean Pixel Intensity':'MEAN_PIXEL_DEN', 'Max Pixel Intensity':'MAX_PIXEL_DEN','Min Pixel Intensity':'MIN_PIXEL_DEN' } featureList = ['Area', 'Perimeter', 'Roundness', 'Equi-Diameter','Orientation', 'Convex Area', 'Solidity', 'Major Axis', 'Minor Axis', 'Eccentricity','Min Enclosing Rad','Shape Index','Border Index','Aspect Ratio', 'Mean Pixel Intensity','Max Pixel Intensity', 'Min Pixel Intensity'] ################ defining features for clustering algorithm ################ ################ Adding File Open Dialog to Show the tiles Info ################ self.chooseImagePanel = wx.Panel(self.sidePanel, -1) box = wx.StaticBox(self.chooseImagePanel, -1, 'Choose Image') self.subPanel = wx.Panel(self.chooseImagePanel, -1) sizer = wx.BoxSizer(wx.VERTICAL) self.filebrowser = filebrowse.FileBrowseButtonWithHistory( self.subPanel, -1, size=(450, -1), changeCallback = self.updateHistory) button = wx.Button(self.subPanel, -1, "View Image") button.Bind(wx.EVT_BUTTON, self.viewImage) sizer.Add(self.filebrowser,0,wx.EXPAND) sizer.Add(button,0,wx.ALL|wx.RIGHT|wx.ALIGN_RIGHT,5) self.subPanel.SetSizer(sizer) sizer = wx.StaticBoxSizer(box, wx.VERTICAL) sizer.Add(self.subPanel) self.chooseImagePanel.SetSizer(sizer) ################ Adding File Open Dialog to Show the tiles Info ################ ################ Adding Algorithm Options Info ################ self.algorithmPanel = wx.Panel(self.sidePanel, -1) box = wx.StaticBox(self.algorithmPanel, -1, 'Algorithms') self.subPanel = wx.Panel(self.algorithmPanel, -1) sizer = wx.BoxSizer(wx.HORIZONTAL) self.algorithm1 = wx.RadioButton(self.subPanel, label="K-MEANS", style = wx.RB_GROUP) self.algorithm2 = wx.RadioButton(self.subPanel, label="OPTICS") self.algorithm1.Bind(wx.EVT_RADIOBUTTON, self.kmeansSelected) self.algorithm2.Bind(wx.EVT_RADIOBUTTON, self.opticsSelected) sizer.Add(self.algorithm1 ,0,wx.ALL|wx.RIGHT|wx.ALIGN_LEFT, 5) sizer.Add((1,1),1) sizer.Add((1,1),1) sizer.Add(self.algorithm2 ,1,wx.ALL|wx.RIGHT|wx.ALIGN_RIGHT,5) self.subPanel.SetSizer(sizer) sizer = wx.StaticBoxSizer(box, wx.VERTICAL) sizer.Add(self.subPanel) self.algorithmPanel.SetSizer(sizer) ################ Adding Algorithm Options Info ################ ################ Adding Features Panel ################ self.featuresPanel = wx.Panel(self.sidePanel, -1) box = wx.StaticBox(self.featuresPanel, -1, 'Features') self.subPanel = wx.Panel(self.featuresPanel, -1) sizer = wx.GridSizer(rows = 6, cols = 3) global featureCB for feature in featureList: cb = wx.CheckBox(self.subPanel, label=feature) cb.Bind(wx.EVT_CHECKBOX, self.featuresSelected) featureCB[feature] = cb sizer.Add(cb, 0, wx.BOTTOM|wx.LEFT, 2) self.subPanel.SetSizer(sizer) sizer = wx.StaticBoxSizer(box, wx.VERTICAL) sizer.Add(self.subPanel) self.featuresPanel.SetSizer(sizer) ################ Adding Features Panel ################ ################ Adding Feature1, Feature2 Range Value ################ self.feature1 = makeSP('FEATURE 1 RANGES', (('Minimum', 1, 1, 3600), ('Maximum', 1, 3600, 3600))) self.feature2 = makeSP('FEATURE 2 RANGES', (('Minimum', 1, 1, 3600), ('Maximum', 1, 3600, 3600))) ################ Adding Feature1, Feature2 Range Value ################ ################ Adding all the panels to the main window ################ self.optionPanel = OptionsPanel(self,self.sidePanel, self.displayPanel) self.buttonStart = wx.Button(self.sidePanel, -1, "Start") self.buttonStart.Bind(wx.EVT_BUTTON, self.startProcess) buttonClose = wx.Button(self.sidePanel, -1, "Close") buttonClose.Bind(wx.EVT_BUTTON, self.stopProcess) self.buttonGenerate = wx.Button(self.sidePanel, -1, "Generate Image") self.buttonGenerate.Bind(wx.EVT_BUTTON, self.generateImage) self.buttonReset = wx.Button(self.sidePanel, -1, "Show Image/Reset") self.buttonReset.Bind(wx.EVT_BUTTON, self.resetProcess) self.feature1.Enable(False) self.feature2.Enable(False) self.buttonStart.Enable(False) self.buttonGenerate.Enable(False) self.algorithmPanel.Enable(False) self.optionPanel.Enable(False) self.buttonReset.Enable(False) panelSizer = wx.BoxSizer(wx.VERTICAL) panelSizer.Add(self.chooseImagePanel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) panelSizer.Add(self.featuresPanel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) panelSizer.Add(self.feature1, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) panelSizer.Add(self.feature2, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) panelSizer.Add(self.algorithmPanel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) panelSizer.Add(self.optionPanel, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.buttonStart ,0,wx.ALL|wx.RIGHT|wx.ALIGN_LEFT, 5) # sizer.Add((1,1),1) sizer.Add(self.buttonGenerate ,0,wx.ALL|wx.RIGHT|wx.ALIGN_CENTER,5) # sizer.Add((1,1),1) sizer.Add(self.buttonReset,0,wx.ALL|wx.RIGHT|wx.ALIGN_CENTER,5) sizer.Add(buttonClose ,0,wx.ALL|wx.RIGHT|wx.ALIGN_RIGHT,5) panelSizer.Add(sizer,0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) # panelSizer.Add(buttonStart, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) # panelSizer.Add(buttonClose, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 5) self.sidePanel.SetSizer(panelSizer) mainSizer = wx.BoxSizer(wx.HORIZONTAL) mainSizer.Add(self.displayPanel, 1, wx.EXPAND) mainSizer.Add(self.sidePanel, 0, wx.EXPAND) self.SetSizer(mainSizer) mainSizer.Fit(self) rw, rh = self.displayPanel.GetSize() sw, sh = self.sidePanel.GetSize() fw, fh = self.GetSize() h = max(600, fh) w = h + fw - rw if verbose: print 'Display Panel Size', (rw, rh) print 'Side Panel Size', (sw, sh) print 'Frame Size', (fw, fh) self.SetSize((w,h)) self.Show() ################ Adding all the panels to the main window ################ ################################################################################# # featureSelected - event handler called when the feature check box is selected # ################################################################################# def featuresSelected(self,event): if event.IsChecked(): self.selectedFeaturesCount += 1 if self.selectedFeaturesCount > 1 : self.optionPanel.Enable(True) self.algorithmPanel.Enable(True) self.buttonGenerate.Enable(True) self.buttonReset.Enable(True) self.feature1.Enable(True) self.feature2.Enable(True) if (self.algorithm1.GetValue()): self.buttonStart.Enable(True) if self.selectedFeaturesCount == 1: self.feature1.Enable(True) for key in featureCB.keys(): if featureCB[key].GetValue() and key == "Mean Pixel Intensity": self.optionPanel.Enable(True) self.algorithmPanel.Enable(True) self.buttonGenerate.Enable(True) self.buttonStart.Enable(True) print key else: self.selectedFeaturesCount -= 1 if self.selectedFeaturesCount <=1 : self.optionPanel.Enable(False) self.algorithmPanel.Enable(False) self.buttonStart.Enable(False) self.buttonGenerate.Enable(False) self.buttonReset.Enable(False) self.feature1.Enable(False) self.feature2.Enable(False) self.axes.clear() self.canvas.draw() if self.selectedFeaturesCount == 1: for key in featureCB.keys(): if featureCB[key].GetValue() and key == "Mean Pixel Intensity": self.optionPanel.Enable(True) self.algorithmPanel.Enable(True) self.buttonGenerate.Enable(True) self.buttonStart.Enable(True) print key self.feature1.Enable(True) def OnSpinback(self, name, value): if verbose: print 'On Spin Back', name, value ################################################ # stopProcess - event handler for close button # ################################################ def stopProcess(self,event): closeConnBaseDB() sys.exit() ############################################################ # resetProcess - event handler for reset/show image button # ############################################################ def resetProcess(self,event): self.axes.clear() self.canvas.draw() self.pointToPick = int(self.optionPanel.textBox.GetValue()) if self.algorithm1.GetValue(): self.buttonStart.Enable(True) else: self.buttonStart.Enable(False) featureList = [] for key in featureCB.keys(): if featureCB[key].GetValue(): featureList.append(key) print featureList self.filename = self.filebrowser.GetValue().split('/')[-1].split('.')[0] self.fullFilename = self.filebrowser.GetValue() datalist = getFeatures(self.filename, self.dictionary[featureList[0]], self.dictionary[featureList[1]]) self.data = vstack([(f1,f2) for (f,n, f1, f2) in datalist]) self.init_plot(self.data, self.k, featureList[0], featureList[1]) self.centroids = [] ##################################################################################### # updateHistory - event handler for file open dialog to store recently opened files # ##################################################################################### def updateHistory(self, event): self.featuresPanel.Enable(True) value = self.filebrowser.GetValue() print 'Update History',value if not value: return history = self.filebrowser.GetHistory() if value not in history: history.append(value) self.filebrowser.SetHistory(history) self.filebrowser.GetHistoryControl().SetStringSelection(value) ################################################################## # viewImage - event handler for View Image button which displays # # the image selected in the open dialog # ################################################################## def viewImage(self,event): print 'View Image' imageFile = self.filebrowser.GetValue() print imageFile win = wx.Frame(None, title = imageFile, size=(500,500), style = wx.DEFAULT_FRAME_STYLE ^wx.RESIZE_BORDER) ipanel = wx.Panel(win, -1) image = wx.ImageFromBitmap(wx.Bitmap(imageFile)) image = image.Scale(500,500, wx.IMAGE_QUALITY_HIGH) bitmap = wx.BitmapFromImage(image) control = wx.StaticBitmap(ipanel,-1,bitmap) control.SetPosition((10,10)) win.Show(True) ################################################################# # generateImage - event handler for Generate Image image button # ################################################################# def generateImage(self,event): print 'generate Image' self.generate_image() ############################################################################## # generate_image - method for generating an image of the tiles # # with mapping of clustered output i.e. each # # cluster is mapped in the tile image with specific colors # ############################################################################## def generate_image(self): #Red,Green,Blue,Marooon,Cyan,Yellow,Magenta,Purple,Navy,Gray(BGR format NOT RGB) #colors = {0:(0,0,255),1:(0,255,0),2:(255,0,0),3:(0,0,128),4:(255,255,0),5:(0,255,255),6:(255,0,255),7:(128,0,128) # ,8:(128,0,0),9:(128,128,128)} colors = [(0,0,255), (0,255,0), (255,0,0)] for i in range(self.k): colors.append((random.choice(range(256)), random.choice(range(256)),random.choice(range(256)))) conn = getConnBaseDB() #Query DB to get boundary values for this image. c = conn.cursor() c.execute("SELECT BOUNDARY_VALS FROM Features WHERE IMAGE_NAME = '%s'" %self.filename) rows = c.fetchall() contour_list = [] for row in rows: boundary_vals = row[0].strip().split(';') boundary_vals.pop() boundary_vals = [[int(float(n)) for n in i.split(',')] for i in boundary_vals] contr = np.array(boundary_vals) contour_list.append(contr) print self.fullFilename im = cv2.imread(self.fullFilename) for index,i in enumerate(self.clusterIds): cv2.drawContours(im,contour_list,index,colors[i],-1) outputfile = "Output_"+self.filename+"_clustered_"+str(int(time.time()))+".tif" cv2.imwrite(outputfile,im); print "'Done Displaying the image" imageFile = outputfile print imageFile win = wx.Frame(None, title = imageFile, size=(500,500), style = wx.DEFAULT_FRAME_STYLE ^wx.RESIZE_BORDER) ipanel = wx.Panel(win, -1) image = wx.ImageFromBitmap(wx.Bitmap(imageFile)) image = image.Scale(500,500, wx.IMAGE_QUALITY_HIGH) bitmap = wx.BitmapFromImage(image) control = wx.StaticBitmap(ipanel,-1,bitmap) control.SetPosition((10,10)) win.Show(True) #cv2.imshow('image',im) #print "show window" #cv2.waitKey() print "byee" #closeConnBaseDB() #return(im) ###################################################################### # pickInputCentroids - method for indicating whether to pick intial # # centroids or not # ###################################################################### def pickInputCentroids(self,userCentroid): self.pointToPick = int(self.optionPanel.textBox.GetValue()) if userCentroid: self.buttonStart.Enable(False) else: self.buttonStart.Enable(True) ########################################################################## # opticsSelected - radio button event for selecting OPTICS algortithm # ########################################################################## def opticsSelected(self,event): self.optionPanel.showUpdates.Enable(False) self.optionPanel.chooseCentroid.Enable(False) self.buttonStart.Enable(True) self.buttonGenerate.Enable(False) ####################################################################### # kmeansSelected - adio button event for selecting KMEANS algortithm # ####################################################################### def kmeansSelected(self,event): self.optionPanel.showUpdates.Enable(True) self.optionPanel.chooseCentroid.Enable(True) self.buttonGenerate.Enable(True) if self.optionPanel.chooseCentroid.GetValue() and self.pointToPick == 0: self.buttonStart.Enable(True) elif not self.optionPanel.chooseCentroid.GetValue(): self.buttonStart.Enable(True) ###################################################################### # onGraphClick - mouse click event handler for selecting intial set # # of centroids from user # ###################################################################### def onGraphClick(self,event): print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%( event.button, event.x, event.y, event.xdata, event.ydata) print self.optionPanel.chooseCentroid.GetValue() print self.pointToPick if self.optionPanel.chooseCentroid.GetValue() and self.pointToPick > 0: self.pointToPick -= 1 #self.axes.plot(event.xdata,event.ydata, color='b',picker=5) self.axes.plot(event.xdata,event.ydata,color='r', marker='H',markersize=20.0,picker=5) self.canvas.draw() self.centroids.append([event.xdata,event.ydata]) #np.concatenate((self.centroids,[event.xdata,event.ydata])) if self.pointToPick == 0 : self.buttonStart.Enable(True) ###################################################################### # onNucleiPick - mouse click event handler for showing the metadata # # of selected nuclei # ###################################################################### def onNucleiPick(self,event): thisline = event.artist xdata = thisline.get_xdata() ydata = thisline.get_ydata() ind = event.ind print thisline print event featureList = [] featureKeys = ['IMAGE FILE','ID','AREA','PERIMETER','ROUNDNESS','EQUI_DIAMETER','CONVEX_AREA','SOLIDITY','MAJOR_AXIS_LEN','MINOR_AXIS_LEN','ORIENTATION','ECCENTRICITY', 'CIR_RADIUS','SHAPE_INDEX','BORDER_INDEX','ASPECT_RATIO','MAX_PIXEL_DEN','MIN_PIXEL_DEN'] for key in featureCB.keys(): if featureCB[key].GetValue(): featureList.append(key) print "xdata",xdata[ind][0] print "ydata",ydata[ind][0] dataList = getAllFeatures(self.filename, self.dictionary[featureList[0]], self.dictionary[featureList[1]],float(xdata[ind][0]),float(ydata[ind][0])); print dataList data = dataList[0] print len(data) win = wx.Frame(None, title = 'Nuclei Metadata', size=(500,500), style = wx.DEFAULT_FRAME_STYLE ^wx.RESIZE_BORDER) print "Creating New Frame" sizer = wx.GridSizer(rows = len(data), cols=2) ipanel = wx.Panel(win, -1) for i in range (0,len(data)): label = wx.StaticText(ipanel, -1, featureKeys[i]) sizer.Add(label, 0, wx.BOTTOM|wx.LEFT, 2) labCtrl = wx.TextCtrl(ipanel, -1, str(data[i]), style = wx.TE_READONLY) sizer.Add(labCtrl, 0, wx.BOTTOM|wx.LEFT, 2) ipanel.SetSizer(sizer) boxSizer = wx.BoxSizer(wx.VERTICAL) boxSizer.Add(ipanel) win.SetSizer(boxSizer) win.Fit() win.Show(True) ########################################################################### # startProcess - event handler for start button # # It initiates the process of clustering # ########################################################################### def startProcess(self, event): print 'in kmeans' featureList =[] isShowUpdate = False k = self.optionPanel.textBox.GetValue() isShowUpdate = self.optionPanel.showUpdates.GetValue() isKmeans = self.algorithm1.GetValue() isOptics = self.algorithm2.GetValue() self.isPickCentroids = self.optionPanel.chooseCentroid.GetValue() print 'spin_panels', spinPanels.keys() for key in featureCB.keys(): if featureCB[key].GetValue(): featureList.append(key) print featureCB[key].GetValue() print "Feature List = ",featureList print "k-value = ",k print "Show Update = ",isShowUpdate print "Kmeans Selected= ",isKmeans print "OPTICS Selected= ",self.algorithm2.GetValue() self.buttonReset.Enable(True) self.buttonStart.Enable(False) for key in spinPanels.keys(): print self.feature1.rangeValue[key].sc.GetValue() print self.feature2.rangeValue[key].sc.GetValue() print self.filebrowser.GetValue() self.filename = self.filebrowser.GetValue().split('/')[-1].split('.')[0] self.fullFilename = self.filebrowser.GetValue() if isKmeans: #start the kmean process self.k = int(k) if not 'Mean Pixel Intensity' in featureList and len(featureList) > 2: print 'Performing kmeans for multiple features' fList = [] for item in featureList: fList.append(self.dictionary[item]) dataList = getFeaturesList(self.filename,fList) #print dataList list1 = [] list2 = [] for index,j in enumerate(fList): list1.append('f'+str(index)) list2 = ['f','n'] + list1 new_list = [map(float,list2[2:]) for list2 in dataList] #new_list = [(float(j) for j in i)for i in new_list] #print "new_list",new_list #self.data = vstack([list1 for list2 in dataList]) self.data = vstack(new_list) #print self.data self.init_plot(self.data, self.k, featureList[0], featureList[1]) self.cluster_kmeansMul(fList, self.k, False) elif not 'Mean Pixel Intensity' in featureList and len(featureList) == 2: print self.filename datalist = getFeatures(self.filename, self.dictionary[featureList[0]], self.dictionary[featureList[1]]) #print datalist self.data = vstack([(f1,f2) for (f,n, f1, f2) in datalist]) #Intial clusters from selecting points -- start #Intial clusters from selecting points -- end self.animation = isShowUpdate self.init_plot(self.data, self.k, featureList[0], featureList[1]) time.sleep(1) if not self.animation: self.cluster_kmeans(datalist, self.k, False) else: print "isPickCentroids =",self.isPickCentroids print "initial centroisds = ", self.centroids if not self.isPickCentroids: self.centroids = self.init_cluster() self.iterTimer = 0 self.redraw_timer.Start(2000) else: self.data = vstack(self.helper_mean()) self.pixel_kmeans() elif isOptics: print 'Calling OPTICS' self.gen_optic_cluster(featureList[0], featureList[1]) else: print 'Select an algorithm' ###################################################################### # gen_optic_cluster - method for executing OPTICS algorithm # ###################################################################### def gen_optic_cluster(self, f1, f2): # generate some spatial data with varying densities np.random.seed(0) con = getConnBaseDB() X = [] cur = con.cursor() stuple = (self.filename,) cur.execute("SELECT "+self.dictionary[f1]+", "+self.dictionary[f2]+" FROM Features WHERE IMAGE_NAME = '%s'" % stuple) rows = cur.fetchall() for row in rows: X.append([row[0], row[1]]) print len(X) #plot scatterplot of points X = np.asarray(X) self.data = X #fig = plt.figure() #ax = fig.add_subplot(111) self.axes.clear() self.xlabel = f1 self.ylabel = f2 self.axes.set_xlabel(self.xlabel) self.axes.set_ylabel(self.ylabel) self.axes.set_title('Intial scatter plot before clustering') pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) self.axes.plot(X[:,0], X[:,1], 'bo') self.canvas.draw() #plt.savefig('Graph.png', dpi=None, facecolor='w', edgecolor='w', # orientation='portrait', papertype=None, format=None, # transparent=False, bbox_inches=None, pad_inches=0.1) #plt.show() #run the OPTICS algorithm on the points, using a smoothing value (0 = no smoothing) RD, CD, order = OP.optics(X,9) RPlot = [] RPoints = [] for item in order: RPlot.append(RD[item]) #Reachability Plot RPoints.append([X[item][0],X[item][1]]) #points in their order determined by OPTICS #hierarchically cluster the data rootNode = AutoC.automaticCluster(RPlot, RPoints) #print Tree (DFS) #AutoC.printTree(rootNode, 0) #graph reachability plot and tree #AutoC.graphTree(rootNode, RPlot) #array of the TreeNode objects, position in the array is the TreeNode's level in the tree array = AutoC.getArray(rootNode, 0, [0]) #get only the leaves of the tree leaves = AutoC.getLeaves(rootNode, []) print 'leaves length = ',len(leaves) #graph the points and the leaf clusters that have been found by OPTICS #fig = plt.figure() #ax = fig.add_subplot(111) self.axes.clear() self.xlabel = f1 self.ylabel = f2 self.axes.set_xlabel(self.xlabel) self.axes.set_ylabel(self.ylabel) self.axes.set_title('Final clusters formed') pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) self.axes.plot(X[:,0], X[:,1], 'yo') #colors = cycle('gmkrcbgrcmk') colors = ['r','g','b'] colors.extend([(random.random(), random.random(), random.random()) for i in range(len(leaves)-3)]) for item, c in zip(leaves, colors): node = [] for v in range(item.start,item.end): node.append(RPoints[v]) node = np.array(node) self.axes.plot(node[:,0],node[:,1], color=c,marker='o',linestyle='None',picker=5) self.canvas.draw() #plt.savefig('Graph2.png', dpi=None, facecolor='w', edgecolor='w', #orientation='portrait', papertype=None, format=None, #transparent=False, bbox_inches=None, pad_inches=0.1) #plt.show() ############################################################################ # pixel_kmeans - method for executing kmeans algorithm for image related # # features (mean pixel density). # ############################################################################ def pixel_kmeans(self, feature1Bound=None, feature2Bound=None,iter=None): random.seed(time.time()) km_obj = KMeans(n_clusters=self.k, init='random', n_init=1, max_iter=self.iterations, tol=0.0001, precompute_distances=True, n_jobs=-1, random_state=None) km_obj.fit(self.data) self.centroids = km_obj.cluster_centers_ self.clusterIds = km_obj.labels_ #self.centroids,_ = kmeans2(self.data, self.k) print len(self.centroids) #self.clusterIds,_ = vq(self.data,self.centroids) sets = set(self.clusterIds) print sets self.generate_image() #TODO: If initial centroid not given only #self.centroids,_ = kmeans2(self.data, self.k, thresh=1e-05, minit='random') #lastCentroids = None #print self.centroids #print '\n' #i = 0 #while not array_equal(lastCentroids,self.centroids) and i < self.iterations: # i+=1 # lastCentroids = vstack(list(self.centroids)[:]) # self.centroids,_ = kmeans2(self.data, lastCentroids, iter=1, thresh=1e-05, minit='matrix') # self.clusterIds,_ = vq(self.data,self.centroids) #self.redraw(-1) #print i, self.iterations #print self.centroids ####################################################################### # helper_mean - helper method for getting mean pixel density feature # # data for clustering. # ####################################################################### def helper_mean(self): conn = getConnBaseDB() c = conn.cursor() c.execute("SELECT MEAN_PIXEL_DEN FROM Features WHERE IMAGE_NAME = '%s'" %self.filename) rows = c.fetchall() data_list = [] for row in rows: item = str(row[0]) match = re.search(r'\((.*)\)',item) if match: data = match.group(1).split(',') data_list.append(data) data_list = [[float(j) for j in i ] for i in data_list] #dbsetup.closeConnBaseDB() return data_list ####################################################################### # init_cluster - method for getting the initial set of centroids for # # kmeans CLUSTERING # ####################################################################### def init_cluster(self): print "init_cluster function" km_obj = KMeans(n_clusters=self.k, init='random', n_init=1, max_iter=1, tol=0.0001, precompute_distances=True, n_jobs=-1, random_state=None) km_obj.fit(self.data) centroids = km_obj.cluster_centers_ return centroids ###################################################################### # timer_kmeans - method performs kmeans clustering and is invoked # # when show updates option is enabled # ###################################################################### def timer_kmeans(self): lastCentroids = vstack(list(self.centroids)[:]) print "timer Kmeans" print "last Centroids", lastCentroids km_obj = KMeans(n_clusters=self.k, init=lastCentroids, n_init=1, max_iter=1, tol=0.0001, precompute_distances=True, n_jobs=-1, random_state=None) km_obj.fit(self.data) self.centroids = km_obj.cluster_centers_ self.clusterIds = km_obj.labels_ self.redraw(self.iterTimer) return array_equal(lastCentroids,self.centroids) ############################################################################# # on_redraw_timer - method for calling the plot method to draw the clusters # # during each update in kmeans process # # Called only when show updates method is selected # ############################################################################# def on_redraw_timer(self, event): print "self.iterTimer",self.iterTimer if self.iterTimer < self.iterations: changed = self.timer_kmeans() self.iterTimer+=1 if self.iterTimer == self.iterations-1 or changed: self.redraw_timer.Stop() #self.redraw(self.data,self.centroids, clusterIds, self.k, -1) self.redraw(-1) ####################################################################### # init_plot - method for displaying the intial plot of the data with # # selected features. # ####################################################################### def init_plot(self,data,k, feature1, feature2): self.axes.clear() x = array([d[0] for d in data]) y = array([d[1] for d in data]) maxX = max(x) minX = min(x) maxY = max(y) minY = min(y) self.xlabel = feature1 self.ylabel = feature2 self.axes.set_xlabel(self.xlabel) self.axes.set_ylabel(self.ylabel) self.axes.set_title('Intial scatter plot before clustering') pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) self.axes.plot(x,y,'bo') self.canvas.draw() self.colors = ['r','g','b'] self.colors.extend([(random.random(), random.random(), random.random()) for i in range(k)]) ############################################################################# # cluster_kmeansMul - method performing kmeans for more than two features # # selected and writes the cluster output to text file # ############################################################################# def cluster_kmeansMul(self, featureList,feature1Bound=None, feature2Bound=None,iter=None): random.seed(time.time()) outputfile = "Output.txt" fh = open(outputfile, "w") km_obj = KMeans(n_clusters=self.k, init='random', n_init=1, max_iter=self.iterations, tol=0.0001, precompute_distances=True, n_jobs=-1, random_state=None) km_obj.fit(self.data) self.centroids = km_obj.cluster_centers_ self.clusterIds = km_obj.labels_ fh.write(str(self.centroids.tolist())) fh.write("Current clusters formed\n") for j in range(self.k): fh.write("Data points of cluster "+str(j)+"\n") for l in range(len(self.data)): if self.clusterIds[l] == j: fh.write(str(self.data[l])+"\n") #fh.write(str(self.clusterIds.tolist())) #print self.data fh.close() print 'done' self.redraw(-1) ######################################################################## # cluster_kmeans - method performing kmeans algorithm on data for # # selected features. This called if two features are # # selected. # ######################################################################## def cluster_kmeans(self, feature1Bound=None, feature2Bound=None,iter=None): random.seed(time.time()) if not self.isPickCentroids: km_obj = KMeans(n_clusters=self.k, init='random', n_init=1, max_iter=self.iterations, tol=0.0001, precompute_distances=True, n_jobs=-1, random_state=None) km_obj.fit(self.data) else : km_obj = KMeans(n_clusters=self.k, init=self.centroids, n_init=1, max_iter=self.iterations, tol=0.0001, precompute_distances=True, n_jobs=-1, random_state=None) km_obj.fit(self.data) self.centroids = km_obj.cluster_centers_ self.clusterIds = km_obj.labels_ #vq(self.data,self.centroids) self.redraw(-1) #print i, self.iterations #print self.centroids ##################################################################### # redraw - method for invoking actual plot drawing module # ##################################################################### def redraw(self, iteration): wx.CallAfter(self.redraw_actual, iteration) ###################################################################### # redraw_actual - method for plotting the cluster output onto the # # scatter plot and display the number of clusters # # alomg with the centroids. # ###################################################################### def redraw_actual(self, iteration): self.axes.clear() self.axes.set_xlabel(self.xlabel) self.axes.set_ylabel(self.ylabel) if iteration == -1: self.axes.set_title('Final clusters formed') else: self.axes.set_title('Clusters during kmeans iteration '+str(iteration)) pylab.setp(self.axes.get_xticklabels(), fontsize=8) pylab.setp(self.axes.get_yticklabels(), fontsize=8) for i in range(self.k): self.axes.plot(self.data[self.clusterIds==i,0],self.data[self.clusterIds==i,1],color=self.colors[i],marker='o',linestyle='None',picker=5) self.axes.plot(self.centroids[i,0],self.centroids[i,1],color=self.colors[i], marker='H',markersize=20.0,picker=5) print(self.centroids) #for i in range(len(self.data)): #self.axes.plot([self.data[i,0],self.centroids[self.clusterIds[i],0]],[self.data[i,1],self.centroids[self.clusterIds[i],1]], color=self.colors[self.clusterIds[i]],picker=5) self.canvas.draw()
class CanvasPanel(wx.Panel): def __init__(self,parent, plot_number): wx.Panel.__init__(self, parent) self.SetBackgroundColour(wx.NamedColour("WHITE")) #self.figure = Figure() #self.axes = self.figure.add_subplot(111) #self.change_plot(0) self.figure,self.axes=return_figure_test(plot_number) 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 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() def change_plot2(self): self.axes.clear() self.figure,self.axes=return_figure_test(3) self.canvas = FigureCanvas(self, -1, self.figure) self.Refresh()
class TopTalkersPlotPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) limit = '8' sql = "select dstaddr as dst_addr, sum(octets)/1024 from flow where dstaddr like '192.168.0%' group by dstaddr order by sum(octets) desc limit " + limit sql_total_volume = "select sum(octets)/1048576 from flow where dstaddr like '192.168.0%'" self.figure = Figure() self.canvas = FigureCanvas(self, -1, self.figure) self.ax = self.figure.add_subplot(111) #self.ax = self.figure.add_subplot(111, polar=True) self.ax.yaxis.grid(True, which='major') self.ax.grid(True) self.timeControlPanel = TimeControlPanel(self) self.start_date = self.timeControlPanel.datepicker_end_date.GetValue() self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.timeControlPanel, 0, wx.LEFT | wx.TOP | wx.GROW) self.sizer.Add(self.canvas, 0, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) #self.sizer.Fit (parent) self.Fit() self.SetSize(panel_size) self.add_toolbar() # comment this out for no toolbar #self.Bind(wx.EVT_BUTTON, self.eventDatesChanged, self.buttonDatesChanged) self.Bind(wx.EVT_BUTTON, self.eventDatesChanged) #EVT_PAINT(self, self.OnPaint) rowset = getRowset(sql) total_traffic_volume = getRowset(sql_total_volume) self.ax.set_title("Top Talkers - Total Volume: %s MB" % total_traffic_volume[0]) labels = [] host_labels = [""] #for offsetting the -1 appearing on the graph #host_labels = [] traffic_volume = [] for row in rowset: labels.append(str(row[0])) host_labels.append(str(row[0])) traffic_volume.append(row[1]) #Plot the horizontal bar chart self.ax.barh(arange(len(labels)), traffic_volume, align='center') self.ax.set_ylabel('Hosts') self.ax.set_xlabel('Volume (Kilobytes)') self.ax.set_yticklabels(host_labels) #print labels for label in self.ax.yaxis.get_ticklabels(): label.set_color('blue') #self.Pack() def OnPaint(self, event): self.canvas.draw() def eventDatesChanged(self, event): self.start_date = self.timeControlPanel.datepicker_start_date.GetValue( ) #print "Top talkers, eventDatesChanged...start_date = ", self.start_date #event.Skip() def eventTimeChoiceChanged(self, event): print "Top talkers eventTimeChoiceChanged' Time selected" event.Skip() def add_toolbar(self): self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() if wx.Platform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wx.Size(fw, th)) self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) # update the axes menu on the toolbar self.toolbar.update()
class PageOne(wx.Panel): def __init__(self, parent, hw_ver, frame): self.frame = frame self.multiplier_list = [1, 2, 4, 5, 8, 10, 16, 20] wx.Panel.__init__(self, parent) self.hw_ver = hw_ver main_sizer = wx.BoxSizer(wx.HORIZONTAL) grid = wx.GridBagSizer(hgap=5, vgap=5) grid_2 = wx.GridBagSizer(hgap=5, vgap=5) horizontal_sizer_2 = wx.BoxSizer(wx.HORIZONTAL) horizontal_sizer = wx.BoxSizer(wx.VERTICAL) plot_sizer = wx.BoxSizer(wx.VERTICAL) self.input_label = wx.StaticBox(self, -1, 'Analog input') self.input_sizer = wx.StaticBoxSizer(self.input_label, wx.HORIZONTAL) self.sample_list = [] for i in range(1, 9): self.sample_list.append("A" + str(i)) self.label_ch_1 = wx.StaticText(self, label="Ch+") grid.Add(self.label_ch_1, pos=(0, 0)) self.edit_ch_1 = wx.ComboBox(self, size=(95, -1), choices=self.sample_list, style=wx.CB_READONLY) self.edit_ch_1.SetSelection(0) grid.Add(self.edit_ch_1, pos=(0, 1)) if self.hw_ver == 1: self.sample_list = ("AGND", "VREF", "A5", "A6", "A7", "A8") else: if self.hw_ver == 2: self.sample_list = ("AGND", "A2") self.label_ch_2 = wx.StaticText(self, label="Ch-") grid.Add(self.label_ch_2, pos=(1, 0)) self.edit_ch_2 = wx.ComboBox(self, size=(95, -1), choices=self.sample_list, style=wx.CB_READONLY) self.edit_ch_2.SetSelection(0) grid.Add(self.edit_ch_2, pos=(1, 1)) self.Bind(wx.EVT_COMBOBOX, self.edit_ch_1_change, self.edit_ch_1) self.Bind(wx.EVT_COMBOBOX, self.edit_ch_2_change, self.edit_ch_2) if self.hw_ver == 1: self.sample_list = ("+-12 V", "+-4 V", "+-2 V", "+-0.4 V", "+-0.04 V") self.label_range = wx.StaticText(self, label="Range") else: if self.hw_ver == 2: self.sample_list = ("x1", "x2", "x4", "x5", "x8", "x10", "x16", "x20") self.label_range = wx.StaticText(self, label="Multiplier") grid.Add(self.label_range, pos=(2, 0)) self.edit_range = wx.ComboBox(self, size=(95, -1), choices=self.sample_list, style=wx.CB_READONLY) self.edit_range.SetSelection(0) grid.Add(self.edit_range, pos=(2, 1)) if self.hw_ver == 2: self.edit_range.Enable(False) self.label_rate = wx.StaticText(self, label="Rate(s)") grid.Add(self.label_rate, pos=(3, 0)) self.edit_rate = (FloatSpin(self, value=1, min_val=0.1, max_val=65.535, increment=0.1, digits=1)) grid.Add(self.edit_rate, pos=(3, 1)) self.button_play = wx.Button(self, label="Play", size=(95, 25)) self.Bind(wx.EVT_BUTTON, self.play_event, self.button_play) self.button_stop = wx.Button(self, label="Stop", size=(95, 25)) self.Bind(wx.EVT_BUTTON, self.stop_event, self.button_stop) self.button_stop.Enable(False) grid.Add(self.button_play, pos=(4, 0)) grid.Add(self.button_stop, pos=(4, 1)) self.label_value = wx.StaticText(self, label="Last value (V)") grid.Add(self.label_value, pos=(5, 0)) self.input_value = wx.TextCtrl(self, style=wx.TE_READONLY, size=(95, 25)) grid.Add(self.input_value, pos=(5, 1)) self.input_sizer.Add(grid, 0, wx.ALL, border=10) self.output_label = wx.StaticBox(self, -1, 'Analog output') self.output_sizer = wx.StaticBoxSizer(self.output_label, wx.HORIZONTAL) if hw_ver == 1: self.edit_value = FloatSpin(self, value=0, min_val=-4.0, max_val=4.0, increment=0.1, digits=3) elif hw_ver == 2: self.edit_value = FloatSpin(self, value=0, min_val=0, max_val=4.0, increment=0.1, digits=3) self.Bind(wx.lib.agw.floatspin.EVT_FLOATSPIN, self.slider_change, self.edit_value) self.lblDAC = wx.StaticText(self, label="DAC value (V)") grid_2.Add(self.lblDAC, pos=(0, 0)) grid_2.Add(self.edit_value, pos=(0, 3)) self.output_sizer.Add(grid_2, 0, wx.ALL, border=10) self.export_label = wx.StaticBox(self, -1, 'Export') self.export_sizer = wx.StaticBoxSizer(self.export_label, wx.HORIZONTAL) self.png = wx.Button(self, label="As PNG file...", size=(98, 25)) self.Bind(wx.EVT_BUTTON, self.save_as_png_event, self.png) self.csv = wx.Button(self, label="As CSV file...", size=(98, 25)) self.Bind(wx.EVT_BUTTON, self.save_as_csv_event, self.csv) horizontal_sizer_2.Add(self.png, 0, wx.ALL) horizontal_sizer_2.Add(self.csv, 0, wx.ALL) self.export_sizer.Add(horizontal_sizer_2, 0, wx.ALL, border=10) self.figure = Figure(facecolor='#ece9d8') self.axes = self.figure.add_subplot(111) self.canvas = FigureCanvas(self, -1, self.figure) self.axes.set_xlabel("Time (s)", fontsize=12) self.axes.set_ylabel("Voltage (mV)", fontsize=12) self.canvas.SetInitialSize(size=(600, 600)) self.add_toolbar() self.cidUpdate = self.canvas.mpl_connect('motion_notify_event', self.UpdateStatusBar) plot_sizer.Add(self.toolbar, 0, wx.CENTER) plot_sizer.Add(self.canvas, 0, wx.ALL) horizontal_sizer.Add(self.input_sizer, 0, wx.CENTRE) horizontal_sizer.Add(self.output_sizer, 0, wx.EXPAND) horizontal_sizer.Add(self.export_sizer, 0, wx.EXPAND) main_sizer.Add(horizontal_sizer, 0, wx.ALL, border=10) main_sizer.Add(plot_sizer, 0, wx.ALL) self.SetSizerAndFit(main_sizer) self.data_packet = [] self.x = [] self.y = [] # Create a publisher receiver pub.subscribe(self.new_data, "newdata") pub.subscribe(self.clear_canvas, "clearcanvas") def new_data(self, msg): data = msg.data if isinstance(msg.data, float): self.input_value.Clear() self.input_value.AppendText(str(data)) if (self.toolbar.mode == "pan/zoom"): return if (self.toolbar.mode == "zoom rect"): return self.canvas.mpl_disconnect(self.frame.page_1.cidUpdate) self.axes.cla() self.axes.grid(color='gray', linestyle='dashed') self.axes.plot(self.y, self.x) self.canvas.draw() self.cidUpdate = self.frame.page_1.canvas.mpl_connect( 'motion_notify_event', self.frame.page_1.UpdateStatusBar) def clear_canvas(self, msg): self.input_value.Clear() self.axes.cla() self.axes.grid(color='gray', linestyle='dashed') self.axes.plot(self.y, self.x) self.canvas.draw() def UpdateStatusBar(self, event): if event.inaxes: x, y = event.xdata, event.ydata self.frame.status_bar.SetStatusText( ("x= " + "%.4g" % x + " y=" + "%.4g" % y), 1) def add_toolbar(self): self.toolbar = MyCustomToolbar(self.canvas) self.toolbar.Realize() # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wx.Size(fw, th)) #self.main_sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) # update the axes menu on the toolbar self.toolbar.update() def save_as_png_event(self, event): self.directory_name = '' dlg = wx.FileDialog(self, "Choose a file", self.directory_name, "", "*.png", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: self.file_name = dlg.GetFilename() self.directory_name = dlg.GetDirectory() self.figure.savefig(self.directory_name + "\\" + self.file_name) dlg.Destroy() def save_as_csv_event(self, event): self.directory_name = '' dlg = wx.FileDialog(self, "Choose a file", self.directory_name, "", "*.odq", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: self.file_name = dlg.GetFilename() self.directory_name = dlg.GetDirectory() with open(self.directory_name + "\\" + self.file_name, 'wb') as file: spamwriter = csv.writer(file, quoting=csv.QUOTE_MINIMAL) for i in range(len(self.frame.comunication_thread.data)): spamwriter.writerow([ self.frame.comunication_thread.x[i], self.frame.comunication_thread.y[i] ]) dlg.Destroy() def zoom_up(self, event): pass def play_event(self, event): self.data_packet = [] self.x = [] self.y = [] self.ch_1 = self.edit_ch_1.GetCurrentSelection() self.ch_2 = self.edit_ch_2.GetCurrentSelection() self.range = self.edit_range.GetCurrentSelection() self.rate = self.edit_rate.GetValue() * 1000 self.edit_rate.SetValue(self.edit_rate.GetValue()) self.edit_value.SetValue(self.edit_value.GetValue()) if self.ch_1 == -1: self.frame.show_error_parameters() return if self.ch_2 == -1: self.frame.show_error_parameters() return if self.range == -1: self.frame.show_error_parameters() return if self.hw_ver == 2 and self.ch_2 == 1: self.ch_2 = self.edit_ch_2.GetValue() self.ch_2 = self.ch_2[1] if self.hw_ver == 1: if self.ch_2 == 1: self.ch_2 = 25 elif self.ch_2 > 1: self.ch_2 += 3 self.frame.comunication_thread.config(self.ch_1, int(self.ch_2), self.range, self.rate) self.button_play.Enable(False) self.button_stop.Enable(True) self.edit_ch_1.Enable(False) self.edit_ch_2.Enable(False) self.edit_range.Enable(False) self.edit_rate.Enable(False) self.frame.daq.set_led(3) wx.CallAfter(pub.sendMessage, "clearcanvas", None) if self.frame.comunication_thread.is_alive(): self.frame.comunication_thread.restart() else: self.frame.comunication_thread.start() self.frame.comunication_thread.stop() self.play_event(0) def stop_event(self, event): self.button_play.Enable(True) self.button_stop.Enable(False) self.edit_ch_1.Enable(True) self.edit_ch_2.Enable(True) self.edit_rate.Enable(True) if (self.hw_ver == 1 or (self.hw_ver == 2 and self.edit_ch_2.GetValue() != "AGND")): self.edit_range.Enable(True) self.frame.daq.set_led(1) self.frame.comunication_thread.stop() def slider_change(self, event): dac_value = self.edit_value.GetValue() self.frame.daq.set_analog(dac_value) def edit_ch_1_change(self, event): if self.hw_ver == 1: return value = self.edit_ch_1.GetValue() self.edit_ch_2.Clear() self.edit_ch_2.Append("AGND") if (int(value[1]) % 2) == 0: self.edit_ch_2.Append("A" + str(int(value[1]) - 1)) else: self.edit_ch_2.Append("A" + str(int(value[1]) + 1)) self.edit_ch_2.SetSelection(0) self.edit_range.SetSelection(0) self.edit_range.Enable(False) def edit_ch_2_change(self, event): if self.hw_ver == 1: return if self.edit_ch_2.GetValue() == "AGND": self.edit_range.Enable(False) self.edit_range.SetSelection(0) else: self.edit_range.Enable(True)
class TopApplicationsPlotPanel(wx.Panel): def __init__( self, parent): wx.Panel.__init__( self, parent) # initialize matplotlib stuff self.figure = Figure() self.canvas = FigureCanvas( self, -1, self.figure ) self.ax = self.figure.add_subplot(111) #print "Top Applications ..." self.timeControlPanel = TimeControlPanel(self) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.timeControlPanel, 0, wx.LEFT | wx.TOP | wx.GROW) self.sizer.Add(self.canvas, 0, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.SetSize(panel_size) self.add_toolbar() # comment this out for no toolbar self.ax.set_title('Most active applications', bbox={'facecolor':'0.8', 'pad':5}) self.Fit() #print sql rowset = getRowset(sql) print "sql = " + sql_total_volume total_traffic_volume = getRowset(sql_total_volume) labels = [] prot_num_array = [] prot_totals_array=[] total_outbound_traffic = 0; for row in total_traffic_volume: total_outbound_traffic = row[0] #print total_outbound_traffic other_traffic = 0 less_than_one_percent = 0 for row in rowset: port_num = row[0] port_total = row[1] percentage = (float(port_total)/total_outbound_traffic)*100 if application_dictionary.has_key(port_num): #print port_num if (percentage>1): #print percentage prot_num_array.append(port_num) prot_totals_array.append(port_total) else: less_than_one_percent = less_than_one_percent + port_total else: other_traffic = other_traffic + port_total for item in prot_num_array: labels.append(application_dictionary.__getitem__(item)) labels.append("<1%") labels.append("Other") prot_totals_array.append(less_than_one_percent) prot_totals_array.append(other_traffic) #print labels self.ax.pie(prot_totals_array, explode=None, labels=labels, autopct='%1.1f%%', shadow=True) #title('Most active applications', bbox={'facecolor':'0.8', 'pad':5}) 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) # update the axes menu on the toolbar self.toolbar.update()
class DataPlotPanel(wx.Panel): """Class for plotting data from FitResultTable. Implements 'observer' for FitResultTable.""" colors = 'kbgcmr' """@ivar: list of colors for multiple plots""" colors_rgba = matplotlib.colors.ColorConverter().to_rgba_array(colors) markers = 'os^vd' """@ivar: list of marker styles for plots with multiple data""" linestyles = ['-', '--', '-.', ':'] ID_AutoscaleX = wx.NewId() ID_AutoscaleY = wx.NewId() ID_Save = wx.NewId() def __init__(self, parent, name = ''): """create panel and axes""" self.name = name wx.Panel.__init__(self, parent, size = (400, 300)) self._create_canvas(parent) self.axs = [] def _create_canvas(self, parent): self.fig = pylab.Figure() self.canvas = FigureCanvas(self, -1, self.fig) #self.canvas = FigureCanvas(parent, -1, self.fig) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self._create_toolbar() tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(wx.Size(fw, th)) self.toolbar.update() #?? self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) self.Fit() self.canvas.mpl_connect('pick_event', self.onpick) def _create_toolbar(self): """create standard toolbar and add tools for toggling automatic scaling""" self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.DeleteTool(self.toolbar._NTB2_SAVE) self.toolbar.DeleteTool(self.toolbar._NTB2_SUBPLOT) self.toolbar.AddLabelTool(self.ID_Save, 'Save', wx.Bitmap(os.path.join(settings.bitmappath, 'save.png'), wx.BITMAP_TYPE_PNG), shortHelp = "Save Image", longHelp = "Save Image to File") self.toolbar.AddSeparator() self.toolbar.AddCheckTool(self.ID_AutoscaleX, wx.Bitmap(os.path.join(settings.bitmappath, 'Xscale.png'), wx.BITMAP_TYPE_PNG), shortHelp = 'Autoscale X', longHelp = 'automatic scaling of X-axis') self.toolbar.AddCheckTool(self.ID_AutoscaleY, wx.Bitmap(os.path.join(settings.bitmappath, 'Yscale.png'), wx.BITMAP_TYPE_PNG), shortHelp = 'Autoscale Y', longHelp = 'automatic scaling of Y-axis') wx.EVT_TOOL(self, self.ID_Save, self.OnSave) wx.EVT_TOOL(self, self.ID_AutoscaleX, self.OnAutoscaleX) wx.EVT_TOOL(self, self.ID_AutoscaleY, self.OnAutoscaleY) self.toolbar.ToggleTool(self.ID_AutoscaleX, True) self.toolbar.ToggleTool(self.ID_AutoscaleY, True) self.autoscaleX = True self.autoscaleY = True self.toolbar.Realize() def draw(self): self.fig.canvas.draw() def update(self, subject): """update status by requesting and storing data from calling subject (given as argument), using the plotdata property""" #store pointer to subject (table) which sends message that #data has changed, needed for displaying mouse selection of #data self.subject = subject #get data from subject xdata, ydatas, d = subject.plotdata if d['xcol']: # and len(d['ycols']) > 0: #note xcol could be None self.datax = xdata self.datasy = ydatas self.dataid = d['yid'] self.datagidx = d['gidx'] self.datamask = d['masked'] self.datadict = d self.refresh() else: #TODO: something wrong here! if False: #no valid data: escape self.datax = [] self.datasy = [] self.dataid = [] self.datagidx = [] self.datamask = [] #TODO: fix for group data return def prepare_axes(self, n): """create n subplots (axes) by adding or removing subplots (axes), try to keep existing limits""" nold = len(self.axs) if n == nold: return #save old limits lims = [(a.get_xlim(), a.get_ylim()) for a in self.axs] #delete old axes for a in self.axs: self.fig.delaxes(a) self.axs = [] #create new axes for k in range(n): if k>0: ax = self.fig.add_subplot(n,1,k+1, sharex = self.axs[0]) else: ax = self.fig.add_subplot(n,1,k+1) if k>nold-1: #newly appended axis #need x autoscaling if no old axis exists if nold == 0: ax.cam_need_autoscalex = True else: ax.set_xlim(lims[0][0]) ax.cam_need_autoscalex = False #appended axes need autoscaling for first plot ax.cam_need_autoscaley = True else: ax.set_xlim(lims[k][0]) ax.cam_need_autoscalex = False ax.set_ylim(lims[k][1]) ax.cam_need_autoscaley = False ax.set_picker(True) self.axs.append(ax) def refresh(self): """refresh plot based on saved status""" if not self.canvas.IsShownOnScreen(): return #plot data, store handles self.phs = [] self.prepare_axes( len(self.datasy) ) #do empty plots for group values legend #save axes limits xlimits = self.axs[0].get_xlim() ylimits = self.axs[0].get_ylim() self.axs[0].set_autoscale_on(False) gvals = self.datadict['gvals'] sh = [] st = [] for k, gval in enumerate(gvals): h = self.axs[0].plot([], [], color = 'k', linestyle = self.linestyles[k%len(self.linestyles)], ) sh.append(h[0]) st.append('%g'%gval) #restore limits self.axs[0].set_xlim(xlimits) self.axs[0].set_ylim(ylimits) # prepare 2 row of fields for saving averaged data of 2 subplots self.avgdatafields = [] self.avg_plotted_data = [] for k in range(len(self.datasy)): h = self.do_plot(self.axs[k], self.datax, self.datasy[k], self.datadict['ycollabels'][k], self.datadict['ycols'][k], groupidx = self.datagidx, dataid = self.dataid, showtitle = (k==0), showxlabel = (k+1 == len(self.axs)), ) self.phs.append(h) fieldsrow = [self.datadict.get('xcollabel')] ylabels = self.datadict['ycollabels'][k] for icolumn in range(len(ylabels)): yfield = ylabels[icolumn] groups = numpy.unique(self.datagidx) if len(groups)>1: yfield = "" for gidx in groups: if gidx<0: pass else: fieldsrow.append(ylabels[icolumn]+"_"+st[gidx]) fieldsrow.append(ylabels[icolumn]+"_"+st[gidx]+"_err") else: fieldsrow.append(ylabels[icolumn]) fieldsrow.append(ylabels[icolumn]+"_err") self.avgdatafields.append(fieldsrow) if sh: import matplotlib.legend l = matplotlib.legend.Legend(self.fig, sh, st, loc = 'upper left') self.axs[0].add_artist(l) #self.axs[0].legend(sh, st, loc = 'best') self.do_autoscale() #self.draw() #self.axs[0].get_xaxis().set_picker(True) def do_plot(self, ax, datax, datay, ylabels, ycols, groupidx, dataid, showtitle = True, showxlabel = True): """do plot in single axis. do not change axes limits""" if len(datax) == 0 or len(datay) == 0: print "no data, no plot" ax.clear() return #TODO: ???? #create a masked array to store averaged data unique_datax = numpy.ma.array(numpy.unique(datax)) avg_p_data = numpy.ma.vstack((unique_datax,numpy.ma.masked_all((2,len(unique_datax))))) avg_p_data = avg_p_data.transpose() #save axes limits xlimits = ax.get_xlim() ylimits = ax.get_ylim() ##workaround for 0.98.3, xlimits return view of internal data, ##need to copy data #if isinstance(xlimits, numpy.ndarray): # xlimits = xlimits.copy() #if isinstance(ylimits, numpy.ndarray): # ylimits = ylimits.copy() #clear and initialize axis ax.clear() ax.hold(True) ax.set_autoscale_on(False) handles = [] for col in range(datay.shape[1]): try: groups = numpy.unique(groupidx) for gidx in groups: if gidx<0 and len(groups)>1: pass else: sel = groupidx == gidx dysel = datay[sel, col] # dysel.shape = (-1, 1) xmed, ymed, yerr = avgdata(datax[sel], dysel) valid = ~ymed.mask.ravel() # ax.plot(xmed[valid], ymed[valid], color = self.colors[ycols[col]%len(self.colors)], linestyle = self.linestyles[gidx%len(self.linestyles)], ) ### fill the masked array of averaged data for idatax in range(len(unique_datax)): for ixmed in range(len(xmed[valid])): if xmed[valid][ixmed] == avg_p_data[idatax,0]: avg_p_data[idatax,-2] = ymed[valid][ixmed] avg_p_data[idatax,-1] = yerr[valid][ixmed] avg_p_data = numpy.ma.hstack((avg_p_data,numpy.ma.masked_all((len(unique_datax),2)))) if False: #True: #plot all data h = ax.plot(datax, datay[:,col], 'o', label = ylabels[col], marker = self.markers[ycols[col]%len(self.markers)], color = self.colors[ycols[col]%len(self.colors)], picker = 3.0, ) handles.extend(h) #plot masked data #TODO: error if all values of y are not valid xd = datax[self.datamask] yd = datay[self.datamask, col] try: ax.plot(datax[self.datamask], datay[self.datamask, col], 'o', label = '_nolegend_', #marker = self.markers[ycols[col]%len(self.markers)], markersize = 9, markeredgecolor = 'b', markerfacecolor = 'w', alpha = 0.5, ) except StandardError, e: print "Error plotting masked data" pass else: #use scatter to plot masked and non masked data #points, using scatter. Note: problems with alpha #handling in scatter need fixes, see #sandbox/testscatter cc = self.colors_rgba[[ycols[col]%len(self.colors)]*len(datax)] cc[:,3] = 1.0 - self.datamask*0.7 #cc[dataid[-1],3] = 0.5 #TODO: emphasize last data point h = ax.scatter(datax, datay[:,col], s = 15*groupidx+30 + 15, c = cc, marker = self.markers[ycols[col]%len(self.markers)], picker = 3.0, label = ylabels[col], ) handles.extend([h]) except StandardError, e: print "Error in plotting data:", e raise return []
class plot_2d_data(wx.Frame): """Generic 2d plotting routine - inputs are: - data (2d array of values), - x and y extent of the data, - title of graph, and - pixel mask to be used during summation - must have same dimensions as data (only data entries corresponding to nonzero values in pixel_mask will be summed) - plot_title, x_label and y_label are added to the 2d-plot as you might expect""" def __init__(self, data, extent, caller = None, scale = 'log', window_title = 'log plot', pixel_mask = None, plot_title = "data plot", x_label = "x", y_label = "y", parent=None): wx.Frame.__init__(self, parent=None, title=window_title, pos = wx.DefaultPosition, size=wx.Size(800,600)) print parent self.extent = extent self.data = data self.caller = caller self.window_title = window_title x_range = extent[0:2] #x_range.sort() self.x_min, self.x_max = x_range y_range = extent[2:4] #y_range.sort() self.y_min, self.y_max = y_range self.plot_title = plot_title self.x_label = x_label self.y_label = y_label self.slice_xy_range = (x_range, y_range) self.ID_QUIT = wx.NewId() self.ID_LOGLIN = wx.NewId() self.ID_UPCOLLIM = wx.NewId() self.ID_LOWCOLLIM = wx.NewId() menubar = wx.MenuBar() filemenu = wx.Menu() quit = wx.MenuItem(filemenu, 1, '&Quit\tCtrl+Q') #quit.SetBitmap(wx.Bitmap('icons/exit.png')) filemenu.AppendItem(quit) plotmenu = wx.Menu() self.menu_log_lin_toggle = plotmenu.Append(self.ID_LOGLIN, 'Plot 2d data with log color scale', 'plot 2d on log scale', kind=wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self.toggle_2d_plot_scale, id=self.ID_LOGLIN) menu_upper_colormap_limit = plotmenu.Append(self.ID_UPCOLLIM, 'Set upper limit of color map', 'Set upper limit of color map') self.Bind(wx.EVT_MENU, self.set_new_upper_color_limit, id=self.ID_UPCOLLIM) menu_lower_colormap_limit = plotmenu.Append(self.ID_LOWCOLLIM, 'Set lower limit of color map', 'Set lower limit of color map') self.Bind(wx.EVT_MENU, self.set_new_lower_color_limit, id=self.ID_LOWCOLLIM) #live_on_off = wx.MenuItem(live_update, 1, '&Live Update\tCtrl+L') #quit.SetBitmap(wx.Bitmap('icons/exit.png')) #live_update.AppendItem(self.live_toggle) #self.menu_log_lin_toggle.Check(True) menubar.Append(filemenu, '&File') menubar.Append(plotmenu, '&Plot') self.SetMenuBar(menubar) self.Centre() if pixel_mask == None: pixel_mask = ones(data.shape) if pixel_mask.shape != data.shape: print "Warning: pixel mask shape incompatible with data" pixel_mask = ones(data.shape) self.pixel_mask = pixel_mask self.show_data = transpose(data.copy()) #self.minimum_intensity = self.data[pixel_mask.nonzero()].min() # correct for floating-point weirdness: self.minimum_intensity = self.data[self.data > 1e-17].min() #if scale == 'log': #self.show_data = log ( self.data.copy().T + self.minimum_intensity/2.0 ) #self._scale = 'log' #self.menu_log_lin_toggle.Check(True) #elif (scale =='lin' or scale == 'linear'): #self._scale = 'lin' #self.menu_log_lin_toggle.Check(True) #self.bin_data = caller.bin_data #self.params = caller.params #fig = figure() self.fig = Figure(dpi=80, figsize=(5,5)) #self.fig = figure() fig = self.fig self.canvas = Canvas(self, -1, self.fig) self.show_sliceplots = False # by default, sliceplots on self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) #self.toolbar = Toolbar(self.canvas) self.toolbar = MyNavigationToolbar(self.canvas, True, self) self.toolbar.Realize() if wx.Platform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wx.Size(fw, th)) self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) self.statusbar = self.CreateStatusBar() self.statusbar.SetFieldsCount(2) self.statusbar.SetStatusWidths([-1, -2]) self.statusbar.SetStatusText("Current Position:", 0) self.canvas.mpl_connect('motion_notify_event', self.onmousemove) #self.canvas.mpl_connect('button_press_event', self.right_click_handler) #self.axes = fig.add_subplot(111) #self.axes = self.fig.gca() #ax = self.axes self.mapper = FigureImage(self.fig) #im = self.axes.pcolor(x,y,V,shading='flat') #self.mapper.add_observer(im) #self.show_data = transpose(log(self.show_data + self.minimum_intensity / 2.0)) #self.canvas.mpl_connect('pick_event', self.log_lin_select) ax = fig.add_subplot(221, label='2d_plot') fig.sx = fig.add_subplot(222, label='sx', picker=True) fig.sx.xaxis.set_picker(True) fig.sx.yaxis.set_picker(True) fig.sx.yaxis.set_ticks_position('right') fig.sx.set_zorder(1) fig.sz = fig.add_subplot(223, label='sz', picker=True) fig.sz.xaxis.set_picker(True) fig.sz.yaxis.set_picker(True) fig.sz.set_zorder(1) self.RS = RectangleSelector(ax, self.onselect, drawtype='box', useblit=True) fig.slice_overlay = None ax.set_position([0.125,0.1,0.7,0.8]) fig.cb = fig.add_axes([0.85,0.1,0.05,0.8]) fig.cb.set_zorder(2) fig.ax = ax fig.ax.set_zorder(2) self.axes = ax ax.set_title(plot_title) #connect('key_press_event', self.toggle_selector) if scale == 'log': self.show_data = log ( self.data.copy().T + self.minimum_intensity/2.0 ) self.__scale = 'log' self.fig.cb.set_xlabel('$\log_{10}I$') self.menu_log_lin_toggle.Check(True) elif (scale =='lin' or scale == 'linear'): self.__scale = 'lin' self.fig.cb.set_xlabel('$I$') self.menu_log_lin_toggle.Check(False) im = self.axes.imshow(self.show_data, interpolation='nearest', aspect='auto', origin='lower',cmap=cm.jet, extent=extent) #im = ax.imshow(data, interpolation='nearest', aspect='auto', origin='lower',cmap=cm.jet, extent=extent) fig.im = im ax.set_xlabel(x_label, size='large') ax.set_ylabel(y_label, size='large') self.toolbar.update() #zoom_colorbar(im) #fig.colorbar(im, cax=fig.cb) zoom_colorbar(im=im, cax=fig.cb) #figure(fig.number) #fig.canvas.draw() #return self.SetSizer(self.sizer) self.Fit() self.canvas.Bind(wx.EVT_RIGHT_DOWN, self.OnContext) self.Bind(wx.EVT_CLOSE, self.onExit) self.sliceplots_off() self.SetSize(wx.Size(800,600)) self.canvas.draw() return def onExit(self, event): self.Destroy() def exit(self, event): wx.GetApp().Exit() def set_new_upper_color_limit(self, evt = None): current_uplim = self.fig.im.get_clim()[1] current_lowlim = self.fig.im.get_clim()[0] dlg = wx.TextEntryDialog(None, "Change upper limit of color map (currently %f)" % current_uplim, defaultValue = "%f" % current_uplim) if dlg.ShowModal() == wx.ID_OK: new_val = dlg.GetValue() xlab = self.fig.cb.get_xlabel() ylab = self.fig.cb.get_ylabel() self.fig.im.set_clim((current_lowlim, float(new_val))) self.fig.cb.set_xlabel(xlab) self.fig.cb.set_ylabel(ylab) self.fig.canvas.draw() dlg.Destroy() def set_new_lower_color_limit(self, evt = None): current_uplim = self.fig.im.get_clim()[1] current_lowlim = self.fig.im.get_clim()[0] dlg = wx.TextEntryDialog(None, "Change lower limit of color map (currently %f)" % current_lowlim, defaultValue = "%f" % current_lowlim) if dlg.ShowModal() == wx.ID_OK: new_val = dlg.GetValue() xlab = self.fig.cb.get_xlabel() ylab = self.fig.cb.get_ylabel() self.fig.im.set_clim((float(new_val), current_uplim)) self.fig.cb.set_xlabel(xlab) self.fig.cb.set_ylabel(ylab) self.fig.canvas.draw() dlg.Destroy() def OnContext(self, evt): print self.show_sliceplots mpl_x = evt.X mpl_y = self.fig.canvas.GetSize()[1] - evt.Y mpl_mouseevent = matplotlib.backend_bases.MouseEvent('button_press_event', self.canvas, mpl_x, mpl_y, button = 3) if (mpl_mouseevent.inaxes == self.fig.ax): self.area_context(mpl_mouseevent, evt) elif ((mpl_mouseevent.inaxes == self.fig.sx or mpl_mouseevent.inaxes == self.fig.sz) and (self.show_sliceplots == True)): self.lineplot_context(mpl_mouseevent, evt) def area_context(self, mpl_mouseevent, evt): area_popup = wx.Menu() item1 = area_popup.Append(wx.ID_ANY,'&Grid on/off', 'Toggle grid lines') wx.EVT_MENU(self, item1.GetId(), self.OnGridToggle) cmapmenu = CMapMenu(self, callback = self.OnColormap, mapper=self.mapper, canvas=self.canvas) item2 = area_popup.Append(wx.ID_ANY,'&Toggle log/lin', 'Toggle log/linear scale') wx.EVT_MENU(self, item2.GetId(), lambda evt: self.toggle_log_lin(mpl_mouseevent)) item3 = area_popup.AppendMenu(wx.ID_ANY, "Colourmaps", cmapmenu) self.PopupMenu(area_popup, evt.GetPositionTuple()) def figure_list_dialog(self): figure_list = get_fignums() figure_list_names = [] for fig in figure_list: figure_list_names.append('Figure ' + str(fig)) figure_list_names.insert(0, 'New Figure') figure_list.insert(0, None) #selection_num = wx.GetSingleChoiceIndex('Choose other plot', '', other_plot_names) dlg = wx.SingleChoiceDialog(None, 'Choose figure number', '', figure_list_names) dlg.SetSize(wx.Size(640,480)) if dlg.ShowModal() == wx.ID_OK: selection_num=dlg.GetSelection() dlg.Destroy() print selection_num return figure_list[selection_num] def lineplot_context(self, mpl_mouseevent, evt): popup = wx.Menu() item1 = popup.Append(wx.ID_ANY,'&Toggle log/lin', 'Toggle log/linear scale of slices') wx.EVT_MENU(self, item1.GetId(), lambda evt: self.toggle_log_lin(mpl_mouseevent)) if mpl_mouseevent.inaxes == self.fig.sx: item2 = popup.Append(wx.ID_ANY, "Save x slice", "save this slice") wx.EVT_MENU(self, item2.GetId(), self.save_x_slice) item3 = popup.Append(wx.ID_ANY, '&Popout plot', 'Open this data in a figure window') wx.EVT_MENU(self, item3.GetId(), lambda evt: self.popout_x_slice()) elif mpl_mouseevent.inaxes == self.fig.sz: item2 = popup.Append(wx.ID_ANY, "Save y slice", "save this slice") wx.EVT_MENU(self, item2.GetId(), self.save_y_slice) item3 = popup.Append(wx.ID_ANY, '&Popout plot', 'Open this data in a new plot window') wx.EVT_MENU(self, item3.GetId(), lambda evt: self.popout_y_slice()) self.PopupMenu(popup, evt.GetPositionTuple()) def popout_y_slice(self, event=None, figure_num = None, label = None): if figure_num == None: figure_num = self.figure_list_dialog() fig = figure(figure_num) # if this is None, matplotlib automatically increments figure number to highest + 1 ax = self.fig.sz slice_desc = '\nsliceplot([%f,%f],[%f,%f])' % (self.slice_xy_range[0][0],self.slice_xy_range[0][1],self.slice_xy_range[1][0],self.slice_xy_range[1][1]) if figure_num == None: default_title = self.plot_title + slice_desc dlg = wx.TextEntryDialog(None, 'Enter title for plot', defaultValue = default_title) if dlg.ShowModal() == wx.ID_OK: title = dlg.GetValue() else: title = default_title dlg.Destroy() new_ax = fig.add_subplot(111) new_ax.set_title(title, size='large') new_ax.set_xlabel(self.x_label, size='x-large') new_ax.set_ylabel('$I_{summed}$', size='x-large') else: new_ax = fig.axes[0] if label == None: default_label = self.window_title + ': ' + self.plot_title + slice_desc dlg = wx.TextEntryDialog(None, 'Enter data label (for plot legend)', defaultValue = default_label) if dlg.ShowModal() == wx.ID_OK: label = dlg.GetValue() else: label = default_label dlg.Destroy() xy = ax.lines[0].get_data() x = xy[0] y = xy[1] new_ax.plot(x,y, label = label) font = FontProperties(size='small') lg = legend(prop=font) drag_lg = DraggableLegend(lg) drag_lg.connect() fig.canvas.draw() fig.show() def popout_x_slice(self, event=None, figure_num = None, label = None): if figure_num == None: figure_num = self.figure_list_dialog() fig = figure(figure_num) ax = self.fig.sx slice_desc = '\nsliceplot([%f,%f],[%f,%f])' % (self.slice_xy_range[0][0],self.slice_xy_range[0][1],self.slice_xy_range[1][0],self.slice_xy_range[1][1]) if figure_num == None: default_title = self.plot_title + slice_desc dlg = wx.TextEntryDialog(None, 'Enter title for plot', defaultValue = default_title) if dlg.ShowModal() == wx.ID_OK: title = dlg.GetValue() else: title = default_title dlg.Destroy() new_ax = fig.add_subplot(111) new_ax.set_title(title, size='large') new_ax.set_xlabel(self.y_label, size='x-large') new_ax.set_ylabel('$I_{summed}$', size='x-large') else: new_ax = fig.axes[0] if label == None: default_label = self.window_title + ': ' + self.plot_title + slice_desc dlg = wx.TextEntryDialog(None, 'Enter data label (for plot legend)', defaultValue = default_label) if dlg.ShowModal() == wx.ID_OK: label = dlg.GetValue() else: label = default_label dlg.Destroy() xy = ax.lines[0].get_data() x = xy[1] y = xy[0] new_ax.plot(x,y, label = label) font = FontProperties(size='small') lg = legend(prop=font) drag_lg = DraggableLegend(lg) drag_lg.connect() fig.canvas.draw() fig.show() def save_x_slice(self, event=None, outFileName=None): if outFileName == None: dlg = wx.FileDialog(None, "Save 2d data as:", '', "", "", wx.FD_SAVE) if dlg.ShowModal() == wx.ID_OK: fn = dlg.GetFilename() fd = dlg.GetDirectory() dlg.Destroy() outFileName = fd + '/' + fn outFile = open(outFileName, 'w') outFile.write('#'+self.title+'\n') outFile.write('#xmin: ' + str(self.slice_xy_range[0][0]) + '\n') outFile.write('#xmax: ' + str(self.slice_xy_range[0][1]) + '\n') outFile.write('#ymin: ' + str(self.slice_xy_range[1][0]) + '\n') outFile.write('#ymax: ' + str(self.slice_xy_range[1][1]) + '\n') outFile.write("#y\tslice_x_data\n") if not (self.slice_x_data == None): for i in range(self.slice_x_data.shape[0]): x = self.y[i] y = self.slice_x_data[i] outFile.write(str(x) + "\t" + str(y) + "\n") outFile.close() print('saved x slice in %s' % (outFileName)) return def save_y_slice(self, event=None, outFileName=None): if outFileName == None: dlg = wx.FileDialog(None, "Save 2d data as:", '', "", "", wx.FD_SAVE) if dlg.ShowModal() == wx.ID_OK: fn = dlg.GetFilename() fd = dlg.GetDirectory() dlg.Destroy() outFileName = fd + '/' + fn outFile = open(outFileName, 'w') outFile.write('#'+self.title+'\n') outFile.write('#xmin: ' + str(self.slice_xrange[0]) + '\n') outFile.write('#xmax: ' + str(self.slice_xrange[1]) + '\n') outFile.write('#ymin: ' + str(self.slice_yrange[0]) + '\n') outFile.write('#ymax: ' + str(self.slice_yrange[1]) + '\n') outFile.write("#x\tslice_y_data\n") if not (self.slice_y_data == None): for i in range(self.slice_y_data.shape[0]): x = self.x[i] y = self.slice_y_data[i] outFile.write(str(x) + "\t" + str(y) + "\n") outFile.close() print('saved y slice in %s' % (outFileName)) return def OnGridToggle(self, event): self.fig.ax.grid() self.fig.canvas.draw_idle() def OnColormap(self, name): print "Selected colormap",name self.fig.im.set_cmap(get_cmap(name)) self.fig.canvas.draw() def toggle_2d_plot_scale(self, event=None): if self.__scale == 'log': self.show_data = self.data.T self.fig.im.set_array(self.show_data) self.fig.im.autoscale() self.fig.cb.set_xlabel('$I$') self.__scale = 'lin' self.menu_log_lin_toggle.Check(False) self.statusbar.SetStatusText("%s scale" % self.__scale, 0) self.fig.canvas.draw_idle() elif self.__scale == 'lin': self.show_data = log ( self.data.copy().T + self.minimum_intensity/2.0 ) self.fig.im.set_array(self.show_data) self.fig.im.autoscale() self.fig.cb.set_xlabel('$\log_{10}I$') self.__scale = 'log' self.menu_log_lin_toggle.Check(True) self.statusbar.SetStatusText("%s scale" % self.__scale, 0) self.fig.canvas.draw_idle() def toggle_log_lin(self,event): ax = event.inaxes label = ax.get_label() if label == '2d_plot': self.toggle_2d_plot_scale() if label == 'sz': scale = ax.get_yscale() if scale == 'log': ax.set_yscale('linear') ax.figure.canvas.draw_idle() elif scale == 'linear': ax.set_yscale('log') ax.figure.canvas.draw_idle() elif label == 'sx': scale = ax.get_xscale() if scale == 'log': ax.set_xscale('linear') ax.figure.canvas.draw_idle() elif scale == 'linear': ax.set_xscale('log') ax.figure.canvas.draw_idle() def onmousemove(self,event): # the cursor position is given in the wx status bar #self.fig.gca() if event.inaxes: x, y = event.xdata, event.ydata self.statusbar.SetStatusText("%s scale x = %.3g, y = %.3g" % (self.__scale,x,y), 1) #self.statusbar.SetStatusText("y = %.3g" %y, 2) def onselect(self, eclick, erelease): x_range = [eclick.xdata, erelease.xdata] y_range = [eclick.ydata, erelease.ydata] ax = eclick.inaxes self.sliceplot((x_range, y_range), ax) print 'sliceplot(([%f,%f],[%f,%f]))' % (x_range[0],x_range[1],y_range[0],y_range[1]) def sliceplots_off(self): self.fig.ax.set_position([0.125,0.1,0.7,0.8]) self.fig.cb.set_position([0.85,0.1,0.05,0.8]) #self.fig.cb.set_visible(True) self.fig.sx.set_visible(False) self.fig.sz.set_visible(False) if self.fig.slice_overlay: self.fig.slice_overlay[0].set_visible(False) self.RS.set_active(False) self.show_sliceplots = False self.fig.canvas.draw() def sliceplots_on(self): self.fig.ax.set_position([0.125,0.53636364, 0.35227273,0.36363636]) self.fig.cb.set_position([0.49,0.53636364, 0.02, 0.36363636]) self.fig.sx.set_position([0.58,0.53636364, 0.35227273,0.36363636]) self.fig.sx.set_visible(True) self.fig.sz.set_visible(True) #self.fig.cb.set_visible(False) if self.fig.slice_overlay: self.fig.slice_overlay[0].set_visible(True) self.RS.set_active(True) self.show_sliceplots = True self.fig.canvas.draw() def toggle_sliceplots(self): """switch between views with and without slice plots""" if self.show_sliceplots == True: self.sliceplots_off() else: # self.show_sliceplots == False self.sliceplots_on() def show_slice_overlay(self, x_range, y_range, x, slice_y_data, y, slice_x_data): """sum along x and z within the box defined by qX- and qZrange. sum along qx is plotted to the right of the data, sum along qz is plotted below the data. Transparent white rectangle is overlaid on data to show summing region""" from matplotlib.ticker import FormatStrFormatter, ScalarFormatter if self.fig == None: print('No figure for this dataset is available') return fig = self.fig ax = fig.ax extent = fig.im.get_extent() if fig.slice_overlay == None: fig.slice_overlay = ax.fill([x_range[0],x_range[1],x_range[1],x_range[0]],[y_range[0],y_range[0],y_range[1],y_range[1]],fc='white', alpha=0.3) fig.ax.set_ylim(extent[2],extent[3]) else: fig.slice_overlay[0].xy = [(x_range[0],y_range[0]), (x_range[1],y_range[0]), (x_range[1],y_range[1]), (x_range[0],y_range[1])] fig.sz.clear() default_fmt = ScalarFormatter(useMathText=True) default_fmt.set_powerlimits((-2,4)) fig.sz.xaxis.set_major_formatter(default_fmt) fig.sz.yaxis.set_major_formatter(default_fmt) fig.sz.xaxis.set_major_formatter(FormatStrFormatter('%.2g')) fig.sz.set_xlim(x[0], x[-1]) fig.sz.plot(x, slice_y_data) fig.sx.clear() fig.sx.yaxis.set_major_formatter(default_fmt) fig.sx.xaxis.set_major_formatter(default_fmt) fig.sx.yaxis.set_ticks_position('right') fig.sx.yaxis.set_major_formatter(FormatStrFormatter('%.2g')) fig.sx.set_ylim(y[0], y[-1]) fig.sx.plot(slice_x_data, y) fig.im.set_extent(extent) fig.canvas.draw() def copy_intensity_range_from(self, other_plot): if isinstance(other_plot, type(self)): xlab = self.fig.cb.get_xlabel() ylab = self.fig.cb.get_ylabel() self.fig.im.set_clim(other_plot.fig.im.get_clim()) self.fig.cb.set_xlabel(xlab) self.fig.cb.set_ylabel(ylab) self.fig.canvas.draw() def sliceplot(self, xy_range, ax = None): """sum along x and z within the box defined by qX- and qZrange. sum along qx is plotted to the right of the data, sum along qz is plotted below the data. Transparent white rectangle is overlaid on data to show summing region""" self.sliceplots_on() x_range, y_range = xy_range x, slice_y_data, y, slice_x_data = self.do_xy_slice(x_range, y_range) self.x = x self.slice_y_data = slice_y_data self.y = y self.slice_x_data = slice_x_data self.slice_xy_range = xy_range self.show_slice_overlay(x_range, y_range, x, slice_y_data, y, slice_x_data) def do_xy_slice(self, x_range, y_range): """ slice up the data, once along x and once along z. returns 4 arrays: a y-axis for the x data, an x-axis for the y data.""" #params = self.params print 'doing xy slice' data = self.data pixels = self.pixel_mask # zero out any pixels in the sum that have zero in the pixel count: data[pixels == 0] = 0 normalization_matrix = ones(data.shape) normalization_matrix[pixels == 0] = 0 x_min = min(x_range) x_max = max(x_range) y_min = min(y_range) y_max = max(y_range) x_size,y_size = data.shape global_x_range = (self.x_max - self.x_min) global_y_range = (self.y_max - self.y_min) x_pixel_min = round( (x_min - self.x_min) / global_x_range * x_size ) x_pixel_max = round( (x_max - self.x_min) / global_x_range * x_size ) y_pixel_min = round( (y_min - self.y_min) / global_y_range * y_size ) y_pixel_max = round( (y_max - self.y_min) / global_y_range * y_size ) #correct any sign switches: if (x_pixel_min > x_pixel_max): new_min = x_pixel_max x_pixel_max = x_pixel_min x_pixel_min = new_min if (y_pixel_min > y_pixel_max): new_min = y_pixel_max y_pixel_max = y_pixel_min y_pixel_min = new_min new_x_min = x_pixel_min / x_size * global_x_range + self.x_min new_x_max = x_pixel_max / x_size * global_x_range + self.x_min new_y_min = y_pixel_min / y_size * global_y_range + self.y_min new_y_max = y_pixel_max / y_size * global_y_range + self.y_min x_pixel_min = int(x_pixel_min) x_pixel_max = int(x_pixel_max) y_pixel_min = int(y_pixel_min) y_pixel_max = int(y_pixel_max) y_norm_factor = sum(normalization_matrix[x_pixel_min:x_pixel_max,y_pixel_min:y_pixel_max], axis=1) x_norm_factor = sum(normalization_matrix[x_pixel_min:x_pixel_max,y_pixel_min:y_pixel_max], axis=0) # make sure the normalization has a minimum value of 1 everywhere, # to avoid divide by zero errors: y_norm_factor[y_norm_factor == 0] = 1 x_norm_factor[x_norm_factor == 0] = 1 slice_y_data = sum(data[x_pixel_min:x_pixel_max,y_pixel_min:y_pixel_max], axis=1) / y_norm_factor slice_x_data = sum(data[x_pixel_min:x_pixel_max,y_pixel_min:y_pixel_max], axis=0) / x_norm_factor #slice_y_data = slice_y_data #slice_x_data = slice_x_data x_vals = arange(slice_y_data.shape[0], dtype = 'float') / slice_y_data.shape[0] * (new_x_max - new_x_min) + new_x_min y_vals = arange(slice_x_data.shape[0], dtype = 'float') / slice_x_data.shape[0] * (new_y_max - new_y_min) + new_y_min return x_vals, slice_y_data, y_vals, slice_x_data
class CanvasFrameTS(wxFrame): def __init__(self): wxFrame.__init__(self, None, -1, 'Time Series', size=(1450, 1100)) self.SetBackgroundColour(wxNamedColor("BLACK")) self.figure = Figure(figsize=(5, 5), dpi=100) self.axes1 = self.figure.add_subplot(511) self.axes2 = self.figure.add_subplot(512) self.axes3 = self.figure.add_subplot(513) self.axes4 = self.figure.add_subplot(514) self.axes5 = self.figure.add_subplot(515) self.axes5.set_xlabel(str(FileString[0]), fontsize=8) if (len(pixelvec) > 0): ###Might try all on one axis system self.axes1.plot(FilteredLongTS[0]) tvec = Threshold[0] + ones(len(FilteredLongTS[0])) self.axes1.plot(tvec) if (len(pixelvec) > 1): self.axes2.plot(FilteredLongTS[1]) tvec = Threshold[1] + ones(len(FilteredLongTS[0])) self.axes2.plot(tvec) if (len(pixelvec) > 2): self.axes3.plot(FilteredLongTS[2]) tvec = Threshold[2] + ones(len(FilteredLongTS[0])) self.axes3.plot(tvec) if (len(pixelvec) > 3): self.axes4.plot(FilteredLongTS[3]) tvec = Threshold[3] + ones(len(FilteredLongTS[0])) self.axes4.plot(tvec) if (len(pixelvec) > 4): self.axes5.plot(FilteredLongTS[4]) tvec = Threshold[4] + ones(len(FilteredLongTS[0])) self.axes5.plot(tvec) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) self.toolbar = MyNavigationToolbar(self.canvas, True) self.toolbar.Realize() if wxPlatform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wxSize(fw, th)) self.sizer.Add(self.toolbar, 0, wxLEFT | wxEXPAND) # 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 CanvasFrame(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, -1, title, size=(550, 350)) self.SetBackgroundColour(wx.NamedColour("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() # File Menu 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: # Equation Menu 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 PlotFigure(wx.Frame): def OnKeyPressed(self, event): key = event.key if key == 'q': self.OnClose(event) def __init__(self, func, timer_period): wx.Frame.__init__(self, None, -1, "Plot Figure") self.fig = Figure((12, 9), 75) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) self.canvas.mpl_connect('key_press_event', self.OnKeyPressed) self.toolbar = NavigationToolbar2Wx(self.canvas) self.toolbar.Realize() self.func = func self.plot = None self.timer_period = timer_period self.timer = wx.Timer(self) self.is_stopped = False if os.name == 'nt': # On Windows, default frame size behaviour is incorrect # you don't need this under Linux tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() self.toolbar.SetSize(Size(fw, th)) # Create a figure manager to manage things # Now put all into a sizer sizer = wx.BoxSizer(wx.VERTICAL) # 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! sizer.Add(self.toolbar, 0, wx.GROW) self.SetSizer(sizer) self.Fit() self.Bind(wx.EVT_TIMER, self.OnTimerWrap, self.timer) self.Bind(wx.EVT_CLOSE, self.OnClose) self.timer.Start(timer_period) def GetToolBar(self): # You will need to override GetToolBar if you are using an # unmanaged toolbar in your frame return self.toolbar def OnClose(self, event): self.is_stopped = True print('Closing PlotFigure, please wait.') self.timer.Stop() self.Destroy() def OnTimerWrap(self, evt): if self.is_stopped: print('Ignoring timer callback') return t = time.time() try: self.OnTimer(evt) except KeyboardInterrupt: self.OnClose(evt) duration = 1000 * (time.time() - t) if duration > self.timer_period: print('Changing timer_period from %s to %s msec' % (self.timer_period, 1.2 * duration)) self.timer_period = 1.2 * duration self.timer.Stop() self.timer.Start(self.timer_period) def OnTimer(self, evt): try: xdata, ydata_list, legend = self.func() except RuntimeError: traceback.print_exc(file=sys.stderr) self.OnClose(evt) return if len(ydata_list.shape) == 1: ydata_list = ydata_list.reshape((1, ydata_list.size)) if self.plot is None: self.axes = self.fig.add_axes([0.1, 0.1, 0.8, 0.8]) l = [] for ydata in ydata_list: l.extend([xdata, ydata]) self.plot = self.axes.plot(*l) self.axes.set_xlabel('Seconds') self.axes.set_ylabel('Volts') self.axes.set_title('nof samples=%s' % (len(xdata))) self.axes.legend(legend) else: self.axes.set_xlim(xmin=xdata[0], xmax=xdata[-1]) ymin, ymax = 1e9, -1e9 for line, data in zip(self.plot, ydata_list): line.set_xdata(xdata) line.set_ydata(data) ymin, ymax = min(data.min(), ymin), max(data.max(), ymax) dy = (ymax - ymin) / 20 self.axes.set_ylim(ymin=ymin - dy, ymax=ymax + dy) self.canvas.draw() def onEraseBackground(self, evt): # this is supposed to prevent redraw flicker on some X servers... pass