def animate(self, duration, repeat=False, figure=None):
        """ Animate the scatter collection, taking *duration* seconds to do so.
            LinkedPanels works across figures, but matplotlib's animation tools are
            figure-centric, so a figure is chosen arbitrarily from the set of
            figures associated with the axes in self.panels.panels. The figure
            can be specified by the kwarg *figure* if desired.
            
        """
        # LinkedPanels is figure-agnostic (works across figures), so get all figures
        # from panels
        fig_set = set()
        for k in self.panels.panels:
            fig_k = self.panels.panels[k].figure
            fig_set.add(fig_k)
        if figure is None:
            figure = tuple(fig_set)[0]
                
                
        pipe_anim = PipelineAnimation(
                        duration, self.artist_outlets, 
                        variable='time',
                        limits=self.panels.bounds.time,
                        branchpoint_data_source=self.branchpoint)

        # Send a refresh of the data down the pipe to load the animation's
        # cache of the current data display.
        get_exchange('SD_reflow_start').send("Pre-animation data reflow")

        # skip the reflow done message, since nothing should have changed about the data
        # or bounds from the previous reflow. Prevents an extra draw of the figure.
        # get_exchange('SD_reflow_done').send("Pre-animation data reflow done")
        
        the_animator = FixedDurationAnimation(figure, duration, pipe_anim, interval=50, repeat=repeat)
        
        return the_animator
Beispiel #2
0
    def on_axes_changed(self, axes):
        """ Examine axes to see if axis limits really changed, and if so trigger a message. """

        # Expect that the axes where the event was generated are this instance's axes
        if axes != self.axes:
            return
            
        get_exchange('MPL_interaction_complete').send(self)

        
    def __init__(self, panels, color_field='time', default_color_bounds=None, s=4, antialiased=False, **kwargs):
        """ *panels* is a LinkedPanels instance. extra kwargs are passed to the call to scatter"""
        
        if default_color_bounds is None:
            default_color_bounds = Bounds()
        self.default_color_bounds = default_color_bounds
        self.mappable_updaters = set()
        self.color_field = color_field
        self.panels=panels
        self.artist_outlet_controllers = set()
        
        bounds_updated_xchg = get_exchange('SD_bounds_updated')
        artist_outlets = []
        empty = [0,]
        for ax in panels.ax_specs:
            # create a new scatter artist
            art = ax.scatter(empty, empty, c=empty, s=s, edgecolors='none', antialiased=antialiased, **kwargs)
            
            # Need to update the color mapping using the specified color field. It needs to know that the
            # bounds have been updated in order to adjust the color limits.
            up = MappableRangeUpdater(art, color_field=color_field, default_bounds=default_color_bounds)
            bounds_updated_xchg.attach(up)
            self.mappable_updaters.add(up)

            # Need to update the actual scatter coordinate data on each scatter artist
            outlet = ScatterArtistOutlet(art, coord_names=panels.ax_specs[ax], color_field=color_field)
            self.artist_outlet_controllers.add(outlet)
            self.mappable_updaters.add(outlet)

            artist_outlets.append(outlet.update())
            self.artist_outlets=artist_outlets

        self.branchpoint = Branchpoint(artist_outlets)
Beispiel #4
0
    def __init__(self, h5filename, table_path=None, target=None, mode='r'):
        self.target = target

        self.h5file = tables.openFile(h5filename, mode=mode)
        self.table = self.h5file.getNode(table_path)
        self.data = self.table[:]

        get_exchange('SD_reflow_start').attach(self)

        flash_table_path = table_path.replace('events', 'flashes')
        try:
            self.flash_table = self.h5file.getNode(flash_table_path)
            self.flash_data = self.flash_table[:]
        except tables.NoSuchNodeError:
            self.flash_table = None
            print "Did not find flash data at {0}".format(flash_table_path)
Beispiel #5
0
def scatter_dataset_on_panels(panels, color_field=None):
    bounds_updated_xchg = get_exchange('SD_bounds_updated')
    all_outlets = []
    empty = [
        0,
    ]
    for ax in panels.ax_specs:
        # create a new scatter artist
        art = ax.scatter(empty,
                         empty,
                         c=empty,
                         s=4,
                         marker='s',
                         edgecolors='none')

        # Need to update the color mapping using the specified color field. It needs to know that the
        # bounds have been updated in order to adjust the color limits.
        up = MappableRangeUpdater(art, color_field=color_field)
        bounds_updated_xchg.attach(up)

        # Need to update the actual scatter coordinate data on each scatter artist
        outlet = ScatterArtistOutlet(art,
                                     coord_names=panels.ax_specs[ax],
                                     color_field=color_field)

        all_outlets.append(outlet.update())

    brancher = Branchpoint(all_outlets)
    return brancher
Beispiel #6
0
 def __init__(self, h5filename, table_path=None, target=None, mode='r'):
     self.target = target
     
     self.h5file = tables.openFile(h5filename, mode=mode)
     self.table = self.h5file.getNode(table_path)
     self.data = self.table[:]
     
     get_exchange('SD_reflow_start').attach(self)
     
     flash_table_path = table_path.replace('events', 'flashes')
     try:
         self.flash_table = self.h5file.getNode(flash_table_path)
         self.flash_data = self.flash_table[:]
     except tables.NoSuchNodeError:
         self.flash_table = None
         print "Did not find flash data at {0}".format(flash_table_path)
Beispiel #7
0
    def __init__(self, target=None, initial_height=0.0, alt_name='alt', alt_factor=1000.0):

        self.bounds_updated_xchg = get_exchange('SD_bounds_updated')
        self.bounds_updated_xchg.attach(self)

        self.alt_factor = alt_factor
        self.alt_name = alt_name
        self.z = initial_height
        self.target=target
Beispiel #8
0
    def __init__(self, data, target=None):
        self.target = target
        self.data = data
        self.reflow_start_xchg = get_exchange('SD_reflow_start')

        # Need to find a way to detach when "done" with dataset. __del__ doesn't work
        # because of some gc issues. context manager doesn't exactly work, since the
        # dataset objects are not one-shot tasks; they live for the whole lifecycle.
        # Anyway, ignoring for now.
        self.reflow_start_xchg.attach(self)
Beispiel #9
0
def redraw(panels):
    """ this function forces a manual redraw / re-flow of the data to the plot.
    
    """
    get_exchange('SD_bounds_updated').send(panels.bounds)
    get_exchange('SD_reflow_start').send('Manual redraw')
    get_exchange('SD_reflow_done').send('Manual redraw complete')
Beispiel #10
0
def redraw(panels):
    """ this function forces a manual redraw / re-flow of the data to the plot.
    
    """
    get_exchange("SD_bounds_updated").send(panels.bounds)
    get_exchange("SD_reflow_start").send("Manual redraw")
    get_exchange("SD_reflow_done").send("Manual redraw complete")
Beispiel #11
0
 def __init__(self, target=None, host=None, basedate=None):
     self.target = target
     get_exchange('SD_reflow_start').attach(self)
     
     self._t_offset = 0.0
     if basedate is not None:
         # corrects for the meaning of time in the LMA analysis code
         self._t_offset += (basedate - datetime(1970, 1, 1)).total_seconds()           
         
     self._dataq = deque([])
     
     self.livesource = LiveLMAController()
     
     # New sources are sent as messages to self.show
     self.livesource.views.append(self)
     
     self._websocket_client = WebsocketClient(host=host)
     # client.connect(on_message=liveDataController.on_message)
     sock_thr = threading.Thread(target=self._websocket_client.connect, 
                     kwargs={'on_message':self.livesource.on_message})
     sock_thr.daemon=True
     sock_thr.start()
Beispiel #12
0
    def __init__(self,
                 panels,
                 color_field='time',
                 default_color_bounds=None,
                 s=4,
                 antialiased=False,
                 **kwargs):
        """ *panels* is a LinkedPanels instance. extra kwargs are passed to the call to scatter"""

        if default_color_bounds is None:
            default_color_bounds = Bounds()
        self.default_color_bounds = default_color_bounds
        self.mappable_updaters = set()
        self.color_field = color_field
        self.panels = panels
        self.artist_outlet_controllers = set()

        bounds_updated_xchg = get_exchange('SD_bounds_updated')
        artist_outlets = []
        empty = [
            0,
        ]
        for ax in panels.ax_specs:
            # create a new scatter artist
            art = ax.scatter(empty,
                             empty,
                             c=empty,
                             s=s,
                             edgecolors='none',
                             antialiased=antialiased,
                             **kwargs)

            # Need to update the color mapping using the specified color field. It needs to know that the
            # bounds have been updated in order to adjust the color limits.
            up = MappableRangeUpdater(art,
                                      color_field=color_field,
                                      default_bounds=default_color_bounds)
            bounds_updated_xchg.attach(up)
            self.mappable_updaters.add(up)

            # Need to update the actual scatter coordinate data on each scatter artist
            outlet = ScatterArtistOutlet(art,
                                         coord_names=panels.ax_specs[ax],
                                         color_field=color_field)
            self.artist_outlet_controllers.add(outlet)
            self.mappable_updaters.add(outlet)

            artist_outlets.append(outlet.update())
            self.artist_outlets = artist_outlets

        self.branchpoint = Branchpoint(artist_outlets)
Beispiel #13
0
    def animate(self, duration, repeat=False, figure=None):
        """ Animate the scatter collection, taking *duration* seconds to do so.
            LinkedPanels works across figures, but matplotlib's animation tools are
            figure-centric, so a figure is chosen arbitrarily from the set of
            figures associated with the axes in self.panels.panels. The figure
            can be specified by the kwarg *figure* if desired.
            
        """
        # LinkedPanels is figure-agnostic (works across figures), so get all figures
        # from panels
        fig_set = set()
        for k in self.panels.panels:
            fig_k = self.panels.panels[k].figure
            fig_set.add(fig_k)
        if figure is None:
            figure = tuple(fig_set)[0]

        pipe_anim = PipelineAnimation(duration,
                                      self.artist_outlets,
                                      variable='time',
                                      limits=self.panels.bounds.time,
                                      branchpoint_data_source=self.branchpoint)

        # Send a refresh of the data down the pipe to load the animation's
        # cache of the current data display.
        get_exchange('SD_reflow_start').send("Pre-animation data reflow")

        # skip the reflow done message, since nothing should have changed about the data
        # or bounds from the previous reflow. Prevents an extra draw of the figure.
        # get_exchange('SD_reflow_done').send("Pre-animation data reflow done")

        the_animator = FixedDurationAnimation(figure,
                                              duration,
                                              pipe_anim,
                                              interval=50,
                                              repeat=repeat)

        return the_animator
Beispiel #14
0
def scatter_dataset_on_panels(panels, color_field=None):
    bounds_updated_xchg = get_exchange('SD_bounds_updated')
    all_outlets = []
    empty = [0,]
    for ax in panels.ax_specs:
        # create a new scatter artist
        art = ax.scatter(empty, empty, c=empty, s=4, marker='s', edgecolors='none')
        
        # Need to update the color mapping using the specified color field. It needs to know that the
        # bounds have been updated in order to adjust the color limits.
        up = MappableRangeUpdater(art, color_field=color_field)
        bounds_updated_xchg.attach(up)
                
        # Need to update the actual scatter coordinate data on each scatter artist
        outlet = ScatterArtistOutlet(art, coord_names=panels.ax_specs[ax], color_field=color_field)

        all_outlets.append(outlet.update())

    brancher = Branchpoint(all_outlets)
    return brancher
Beispiel #15
0
    def __init__(self, *args, **kwargs):
        """ Register to receive lasso events. 

            cache_segment is typically set to receive the results of all data
            selection operations, as though it were a plot, so that the
            current plot state can be subset. The instantiator of this class
            should set the target of a data emitter to
            payload_lasso.cache_segment.cache_segment(), The target of the
            cache segment is a lasso_filter, followed by the addition of the
            payload, and finally, the target kwarg passed when this class is
            instantiated.

            On receiving a new lasso, trigger a resend of the cached data 
            to the dataset modifier.
        """
        self.target = kwargs.pop('target', None)
        self._payload = None
        self.lasso_filter = LassoFilter(target=self.add_payload_value(target=self.target))
        self.lasso_xchg = get_exchange('B4D_panel_lasso_drawn')
        self.lasso_xchg.attach(self)
        self.cache_segment = CachedTriggerableSegment(target=self.lasso_filter.filter())
Beispiel #16
0
    def __init__(self, *args, **kwargs):
        """ Register to receive lasso events. 

            cache_segment is typically set to receive the results of all data
            selection operations, as though it were a plot, so that the
            current plot state can be subset. The instantiator of this class
            should set the target of a data emitter to
            payload_lasso.cache_segment.cache_segment(), The target of the
            cache segment is a lasso_filter, followed by the addition of the
            payload, and finally, the target kwarg passed when this class is
            instantiated.

            On receiving a new lasso, trigger a resend of the cached data 
            to the dataset modifier.
        """
        self.target = kwargs.pop('target', None)
        self._payload = None
        self.lasso_filter = LassoFilter(target=self.add_payload_value(
            target=self.target))
        self.lasso_xchg = get_exchange('B4D_panel_lasso_drawn')
        self.lasso_xchg.attach(self)
        self.cache_segment = CachedTriggerableSegment(
            target=self.lasso_filter.filter())
Beispiel #17
0
 def __init__(self, h5dataset, target=None):
     self.target = target
     self.h5dataset = h5dataset
     get_exchange('SD_reflow_start').attach(self)
Beispiel #18
0
 def _setup_events(self):
     self.interaction_xchg = get_exchange('MPL_interaction_complete')
     self.interaction_xchg.attach(self)
     self.bounds_updated_xchg = get_exchange('SD_bounds_updated')
     self.reflow_start_xchg = get_exchange('SD_reflow_start')
     self.reflow_done_xchg = get_exchange('SD_reflow_done')
Beispiel #19
0
 def __init__(self, figure):
     self.figure = figure
     # Tell the figure to update (draw) when the bounds change.
     get_exchange('SD_reflow_done').attach(self)
Beispiel #20
0
 def _setup_events(self):
     self.interaction_xchg = get_exchange('MPL_interaction_complete')
     self.interaction_xchg.attach(self)
     self.bounds_updated_xchg = get_exchange('SD_bounds_updated') 
     self.reflow_start_xchg = get_exchange('SD_reflow_start')
     self.reflow_done_xchg = get_exchange('SD_reflow_done')
Beispiel #21
0
 def __init__(self, figure):
     self.figure=figure
     # Tell the figure to update (draw) when the bounds change.
     get_exchange('SD_reflow_done').attach(self)
Beispiel #22
0
 def __init__(self, h5dataset, target=None):
     self.target=target
     self.h5dataset = h5dataset
     get_exchange('SD_reflow_start').attach(self)
Beispiel #23
0
 def _lasso_callback(self, ax, lasso_line, verts):
     self.figure.canvas.widgetlock.release(self._active_lasso)
     self._active_lasso = None
     xchg = get_exchange("B4D_panel_lasso_drawn")
     xchg.send((self, ax, lasso_line, verts))
Beispiel #24
0
 def _lasso_callback(self, ax, lasso_line, verts):
     self.figure.canvas.widgetlock.release(self._active_lasso)
     self._active_lasso=None
     xchg = get_exchange('B4D_panel_lasso_drawn')
     xchg.send((self, ax, lasso_line, verts))