diff --git a/system/dataset.py b/system/dataset.py index ad6a617..d5f5866 100644 --- a/system/dataset.py +++ b/system/dataset.py @@ -263,6 +263,7 @@ class GraphDataset(Dataset): Dataset.__init__(self,array=array,identifiers=identifiers,name='A') self._graph = None self._type = 'g' + self._pos = None def asnetworkx(self,nx_type='graph'): dim = self.get_dim_name()[0] diff --git a/system/plots.py b/system/plots.py index 11e0de2..60d99e0 100644 --- a/system/plots.py +++ b/system/plots.py @@ -249,7 +249,6 @@ class Plot (gtk.Frame): def __init__(self, title): gtk.Frame.__init__(self) self.title = title - self.sel_obj = None self.selection_listener = None self.fig = Figure() self.canvas = FigureCanvas(self.fig) @@ -257,7 +256,8 @@ class Plot (gtk.Frame): self._background = None self._sel_sensitive = True self.canvas.add_events(gtk.gdk.ENTER_NOTIFY_MASK) - + self.current_dim = None + def set_selection_sensitive(self,event): if event: if event.get_active(): @@ -271,9 +271,19 @@ class Plot (gtk.Frame): def get_title(self): return self.title - def selection_changed(self, selection): - if not self._sel_sensitive or not self.get_property('visible'): + def selection_changed(self, dim_name, selection): + """ Selection observer handle. + + A selection change in a plot is only drawn if: + 1.) plot is sensitive to selections (not freezed) + 2.) plot is visible (has a view) + 3.) the selections dim_name is the plot's dimension. + """ + + if not self._sel_sensitive or not self.get_property('visible') or self.current_dim!=dim_name: + print "Ignored a selection changed call in plot: %s" %self.get_title() return + print "Setting current selection in: %s " %self.get_title() self.set_current_selection(selection) def set_selection_listener(self, listener): @@ -436,6 +446,7 @@ has no color and size options.""" 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 xdata = self.xaxis_data @@ -472,6 +483,7 @@ has no color and size options.""" self.ax.draw_artist(self._selection_line) self.canvas.blit() else: + print "A draw happened in: %s" %self.get_title() self.canvas.draw() @@ -507,13 +519,13 @@ class ScatterPlot(Plot): # create toolbar self._toolbar = PlotToolbar(self.canvas, self) self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive) - self._toolbar.set_property('show-arrow', False) self._toolbar.set_select_callback(self.rectangle_select_callback) 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 xdata = self.xaxis_data @@ -532,7 +544,9 @@ class ScatterPlot(Plot): def set_current_selection(self, selection): ids = selection[self.current_dim] # current identifiers if len(ids)==0: + print "nothing selected" return + 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: @@ -542,12 +556,13 @@ class ScatterPlot(Plot): if len(index)>0: lw.put(2.,index) self.coll.set_linewidth(lw) - self._toolbar.forward() #update data lims before draw - + if self.use_blit: + print "A blit happened in : %s " %self.get_title() self.canvas.blit() self.ax.draw_artist(self.coll) else: + print "A draw happened in : %s " %self.get_title() self.canvas.draw() @@ -558,6 +573,7 @@ class NetworkPlot(Plot): self.dataset = dataset self.keywords = kw self.dim_name = self.dataset.get_dim_name(0) + self.current_dim = self.dim_name if not kw.has_key('name'): kw['name'] = self.dataset.get_name() if not kw.has_key('prog'): @@ -607,14 +623,12 @@ class NetworkPlot(Plot): # Setup toolbar self._toolbar = PlotToolbar(self.canvas, self) self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive) - self._toolbar.set_property('show-arrow', False) self._toolbar.set_select_callback(self.rectangle_select_callback) def get_toolbar(self): return self._toolbar def rectangle_select_callback(self, x1, y1, x2, y2): - 'event1 and event2 are the press and release events' pos = self.keywords['pos'] ydata = scipy.zeros((len(pos),), 'l') xdata = scipy.zeros((len(pos),), 'l') @@ -635,10 +649,10 @@ class NetworkPlot(Plot): ids = [node_ids[i] for i in index] - self.selection_listener(self.dataset.get_dim_name(0), ids) + self.selection_listener(self.current_dim, ids) def set_current_selection(self, selection): - ids = selection[self.dataset.get_dim_name(0)] # current identifiers + ids = selection[self.current_dim] # current identifiers node_set = set(self.graph.nodes()) selected_nodes = list(ids.intersection(node_set)) @@ -688,6 +702,7 @@ class PlotToolbar(NavigationToolbar2,gtk.Toolbar): def __init__(self, canvas, plot): self.win = None + self.plot = plot gtk.Toolbar.__init__(self) NavigationToolbar2.__init__(self, canvas) self._idleId = 0 @@ -758,16 +773,29 @@ class PlotToolbar(NavigationToolbar2,gtk.Toolbar): def on_enter_notify(self, widget, event): if self._active != active_mode: self.set_mode(active_mode) + self.set_mode(active_mode) def set_mode(self, active): + print "Set mode called in toolbar from: %s" %self.plot.get_title() # if state is unkown or not set, set to default if active == None or active not in self._states.keys(): active = 'DEFAULT' # remove current Selector: - if self._selector: - print "Removing selector" + if self._selector != None: + # problem is ... i have mutliple selectors still connected + # trying to remove old selectors connections + # + # blah + # Her Einar ... + # + self.canvas.mpl_disconnect(self._selector.onmove) + self.canvas.mpl_disconnect(self._selector.press) + self.canvas.mpl_disconnect(self._selector.release) + self.canvas.mpl_disconnect(self._selector.update_background) + print "Removing selector in: %s" %self.plot.get_title() self._selector = None + # remove current button bindings if self._idPress != None: self._idPress = self.canvas.mpl_disconnect(self._idPress) @@ -782,14 +810,14 @@ class PlotToolbar(NavigationToolbar2,gtk.Toolbar): continue if state == 'SELECT': - ax, = self.canvas.figure.get_axes() - props = dict(facecolor='blue', edgecolor = 'black', - alpha=0.3, fill=True) - self._selector = RectangleSelector(ax, self.onselect, - drawtype='box', useblit=True, - rectprops=props) - self.mode = 'Select rectangle mode' - print self.mode + for ax in self.canvas.figure.get_axes(): + props = dict(facecolor='blue', edgecolor = 'black', + alpha=0.3, fill=True) + print "creating a selector" + self._selector = RectangleSelector(ax, self.on_select, + drawtype='box', useblit=True, + rectprops=props) + self.mode = 'Select rectangle mode' elif state == 'PAN': self._idPress = self.canvas.mpl_connect( @@ -837,10 +865,11 @@ class PlotToolbar(NavigationToolbar2,gtk.Toolbar): return self.set_mode('SELECT') - def onselect(self,eclick, erelease): + def on_select(self,eclick, erelease): 'eclick and erelease are matplotlib events at press and release' if self._select_callback: - self._select_callback(eclick.xdata, eclick.ydata, erelease.xdata, erelease.ydata) + print "Onselect called" + self._select_callback(eclick.xdata, eclick.ydata, erelease.xdata, erelease.ydata) def pan(self, button): """Activate the pan/zoom tool. pan with left button, zoom with right""" @@ -885,9 +914,6 @@ class PlotToolbar(NavigationToolbar2,gtk.Toolbar): def dynamic_update(self): # legacy method; new method is canvas.draw_idle self.canvas.draw_idle() - - def mpl_draw_rubberband(self,event): - """Use RectangleSelector for rubberband drawing""" def draw_rubberband(self, event, x0, y0, x1, y1): 'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744' diff --git a/system/project.py b/system/project.py index 1b879d0..995d86f 100644 --- a/system/project.py +++ b/system/project.py @@ -25,12 +25,12 @@ class Project: def add_selection_observer(self, observer): self._selection_observers.append(observer) - observer.selection_changed(self.get_selection()) + #observer.selection_changed(self.get_selection()) def notify_selection_listeners(self, dim_name): """Notifies observers""" for observer in self._selection_observers: - observer.selection_changed(self.get_selection()) + observer.selection_changed(dim_name, self.get_selection()) def add_dataset_observer(self, observer): self._dataset_observers.append(observer) @@ -43,11 +43,11 @@ class Project: def set_selection(self, dim_name, selection): """Sets a current selection and notify observers""" - if self._last_selection != selection: + if self._last_selection != selection: self.sel_obj[dim_name] = set(selection) self.notify_selection_listeners(dim_name) self._last_selection = selection - + def get_selection(self): """Returns the current selection object""" return self.sel_obj diff --git a/system/selections.py b/system/selections.py index 45be493..425e6a2 100644 --- a/system/selections.py +++ b/system/selections.py @@ -139,7 +139,7 @@ class DimListController: values = (selection.title, selection, dataset.get_dim_name(0)) self.selstore.insert_after(i, None, values) - def selection_changed(self, selection): + def selection_changed(self, dim_name, selection): """Callback function from Project.""" for dim in selection.dims(): diff --git a/workflows/test_workflow.py b/workflows/test_workflow.py index 5fe6566..68f4f6f 100644 --- a/workflows/test_workflow.py +++ b/workflows/test_workflow.py @@ -103,7 +103,7 @@ class TestDataFunction(workflow.Function): def run(self): logger.log('notice', 'Injecting foo test data') - x = randn(5000,4) + x = randn(500,4) X = dataset.Dataset(x) p = plots.ScatterPlot(X, X, 'rows', 'rows', '0_1', '0_2',name='scatter') p2 = plots.ScatterMarkerPlot(X, X, 'rows', 'rows', '0_1', '0_2',name='marker')