diff --git a/system/plots.py b/system/plots.py index cb96942..aafa630 100644 --- a/system/plots.py +++ b/system/plots.py @@ -294,6 +294,9 @@ class Plot (View): def get_title(self): return self.title + def get_toolbar(self): + return self._toolbar + def selection_changed(self, dim_name, selection): """ Selection observer handle. @@ -303,7 +306,7 @@ class Plot (View): 3.) the selections dim_name is the plot's dimension. """ - if not self._sel_sensitive \ + if self._frozen \ or not self.get_property('visible') \ or self.current_dim != dim_name: print "Ignored a selection changed call in plot: %s" %self.get_title() @@ -384,10 +387,6 @@ class LineViewPlot(Plot): self._toolbar = PlotToolbar(self) self.canvas.mpl_connect('resize_event', self.clear_background) - - def get_toolbar(self): - return self._toolbar - def clear_background(self, event): self._background = None @@ -407,27 +406,23 @@ class LineViewPlot(Plot): line_coll = LineCollection(segs, colors=(1,0,0,1)) line_coll.set_clip_box(self.ax.bbox) self.ax.update_datalim(line_coll.get_verts(self.ax.transData)) - self._toolbar.forward() + if self.use_blit: self.ax.draw_artist(line_coll) - #print "\nLine collection clip box:" line_coll.get_clip_box().get_bounds() - #print "\nLine collection bbox:" - #print self.ax.bbox.get_bounds() - #print "Background bbox:" - #print self._bbox.get_bounds() - #self.canvas.blit(self._bbox) self.canvas.blit() - #self.ax.draw_artist(line_coll) else: self.ax.add_collection(line_coll) self.canvas.draw() + class ScatterMarkerPlot(Plot): """The ScatterMarkerPlot is faster than regular scatterplot, but -has no color and size options.""" - def __init__(self, dataset_1, dataset_2, id_dim, sel_dim, id_1, id_2,s=6, name="Scatter plot"): + has no color and size options.""" + + def __init__(self, dataset_1, dataset_2, id_dim, sel_dim, + id_1, id_2, s=6, name="Scatter plot"): Plot.__init__(self, name) self.use_blit = False self._background = None @@ -447,9 +442,6 @@ has no color and size options.""" self.add(self.canvas) self.canvas.show() - def get_toolbar(self): - return self._toolbar - def rectangle_select_callback(self, x1, y1, x2, y2): print "Rectangle select happened in: %s" %self.get_title() ydata = self.yaxis_data @@ -483,7 +475,7 @@ has no color and size options.""" self._selection_line, = self.ax.plot(xdata_new, ydata_new,marker='o', markersize=self.ms, linestyle=None, markerfacecolor='r') - self._toolbar.forward() #update data lims before draw +# self._toolbar.forward() #update data lims before draw if self.use_blit: self.ax.draw_artist(self._selection_line) self.canvas.blit() @@ -521,9 +513,6 @@ class ScatterPlot(Plot): self.add(self.canvas) self.canvas.show() - def get_toolbar(self): - return self._toolbar - def rectangle_select_callback(self, x1, y1, x2, y2): print "Rectangle select happened in: %s" %self.get_title() ydata = self.yaxis_data @@ -546,7 +535,7 @@ class ScatterPlot(Plot): if len(ids)==0: print "nothing selected" return - self._toolbar.forward() #update data lims before draw + #self._toolbar.forward() #update data lims before draw index = self.dataset_1.get_indices(self.current_dim, ids) if self.use_blit: if self._background is None: @@ -684,10 +673,12 @@ class PlotMode: to the toolbar button is activated by calling setup(ax) for the axis system ax. """ - def __init__(self, name, tooltip, image_file): + def __init__(self, plot, name, tooltip, image_file): self.name = name self.tooltip = tooltip self.image_file = image_file + self.plot = plot + self.canvas = plot.canvas def get_icon(self): """Returns the icon for the PlotMode""" @@ -696,7 +687,7 @@ class PlotMode: image.set_from_file(fname) return image - def activate(self, canvas): + def activate(self): pass def deactivate(self): @@ -704,19 +695,19 @@ class PlotMode: class DefaultPlotMode (PlotMode): - def __init__(self): - PlotMode.__init__(self, 'default', 'Default mode', 'cursor.png') + def __init__(self, plot): + PlotMode.__init__(self, plot, 'default', 'Default mode', 'cursor.png') class PanPlotMode (PlotMode): - def __init__(self): - PlotMode.__init__(self, 'pan', + def __init__(self, plot): + PlotMode.__init__(self, plot, 'pan', 'Pan axes with left mouse, zoom with right', 'move.png') self._button_press = None self._button_release = None - def activate(self, canvas): + def activate(self): self._button_press = self.canvas.mpl_connect( 'button_press_event', self._on_button_press) self._button_relese = self.canvas.mpl_connect( @@ -730,42 +721,30 @@ class PanPlotMode (PlotMode): if self._button_release: self.canvas.mpl_disconnect(self._button_release) + def _on_button_press(self, event): + pass + + def _on_button_release(self, event): + pass + class ZoomPlotMode (PlotMode): - def __init__(self): - PlotMode.__init__(self, 'zoom', + def __init__(self, plot): + PlotMode.__init__(self, plot, 'zoom', 'Zoom to rectangle','zoom_to_rect.png') + self._selectors = {} - def activate(self, canvas): - self._button_press = self.canvas.mpl_connect( - 'button_press_event', self._on_button_press) - self._button_relese = self.canvas.mpl_connect( - 'button_release_event', self._on_button_release) - self.mode = 'pan/zoom mode' + def activate(self): + for ax in self.canvas.figure.get_axes(): + props = dict(facecolor = 'blue', + edgecolor = 'black', + alpha = 0.3, + fill = True) - def deactivate(self): - if self._button_press: - self.canvas.mpl_disconnect(self._button_press) - - if self._button_release: - self.canvas.mpl_disconnect(self._button_release) - - -class SelectPlotMode (PlotMode): - def __init__(self): - PlotMode.__init__(self, 'select', - 'Select within rectangle', 'select.png') - self._selectors = [] - - - def activate(self, canvas): - for ax in canvas.figure.get_axes(): - props = dict(facecolor='blue', edgecolor = 'black', - alpha=0.3, fill=True) - - rs = RectangleSelector(ax, self.on_select, drawtype='box', + rs = RectangleSelector(ax, self._on_select, drawtype='box', useblit=True, rectprops = props) - self._selectors.append(rs) + self.canvas.draw() + self._selectors[rs] = ax def deactivate(self): for sel in self.selectors: @@ -773,6 +752,44 @@ class SelectPlotMode (PlotMode): self.canvas.mpl_disconnect(sel.press) self.canvas.mpl_disconnect(sel.release) self.canvas.mpl_disconnect(sel.update_background) + self._selectors = {} + + def _on_select(self, start, end): + min_x = min(start.xdata, end.xdata) + min_y = min(start.ydata, end.ydata) + max_x = max(start.xdata, end.xdata) + max_y = max(start.ydata, end.ydata) + + +class SelectPlotMode (PlotMode): + def __init__(self, plot): + PlotMode.__init__(self, plot, 'select', + 'Select within rectangle', 'select.png') + self._selectors = {} + + def activate(self): + for ax in self.canvas.figure.get_axes(): + props = dict(facecolor = 'blue', + edgecolor = 'black', + alpha = 0.3, + fill = True) + + rs = RectangleSelector(ax, self._on_select, drawtype='box', + useblit=True, rectprops = props) + self.canvas.draw() + self._selectors[rs] = ax + + def deactivate(self): + for sel in self.selectors: + self.canvas.mpl_disconnect(sel.onmove) + self.canvas.mpl_disconnect(sel.press) + self.canvas.mpl_disconnect(sel.release) + self.canvas.mpl_disconnect(sel.update_background) + self._selectors = {} + + def _on_select(self, start, end): + self.plot.rectangle_select_callback(start.xdata, start.ydata, + end.xdata, end.ydata) class PlotToolbar(gtk.Toolbar): @@ -791,10 +808,10 @@ class PlotToolbar(gtk.Toolbar): #canvas.connect('enter-notify-event', self.on_enter_notify) self.show() - self.add_mode(DefaultPlotMode()) - self.add_mode(PanPlotMode()) - self.add_mode(ZoomPlotMode()) - self.add_mode(SelectPlotMode()) + self.add_mode(DefaultPlotMode(self.plot)) + self.add_mode(PanPlotMode(self.plot)) + self.add_mode(ZoomPlotMode(self.plot)) + self.add_mode(SelectPlotMode(self.plot)) self.show_all() def add_mode(self, mode): @@ -832,8 +849,10 @@ class PlotToolbar(gtk.Toolbar): def get_button(self, mode_name): """Returns the button that corresponds to a mode name.""" for b, m in self._mode_buttons.items(): - if m == mode_name: + if m.name == mode_name: + print "Found button for mode: %s" % mode_name return b + print "Couldn't find button for mode: %s" % mode_name return None def set_mode(self, mode_name): @@ -846,13 +865,16 @@ class PlotToolbar(gtk.Toolbar): new_mode = self.get_mode_by_name(mode_name) if new_mode: - new_mode.activate(self.canvas) + new_mode.activate() self._current_mode = self.get_mode_by_name(mode_name) else: logger.log('warning', 'No such mode: %s' % mode_name) - + + if self.get_button(mode_name) and not self.get_button(mode_name).get_active(): + self.get_button(mode_name).set_active(True) return self._current_mode + def _on_mode_toggle(self, button): if button.get_active(): self.set_mode(self._mode_buttons[button].name)