def __init__(self, ax, plots, legendkw): '''enable legend picking''' #initialize auto-connect ConnectionMixin.__init__(self, ax.figure) #Auto-generate labels #NOTE: This needs to be done to enable legend picking. if the artists #are unlabeled, no legend will be created and we therefor cannot pick them! i = 0 for plot in plots: if not plot.get_label(): lbl = self.label_map[type(plot)].format(i) plot.set_label(lbl) i += 1 #update default legend props with user specified props lkw = self._default_legend lkw.update(legendkw) #create the legend #print('PING!!'*10 ) #embed() #self.legend = ax.legend( plots, labels, **lkw ) self.legend = ax.legend(**lkw) if self.legend: #if no labels --> no legend, and we are done! #create mapping between the picked legend artists (markers), and the #original (axes) artists self.to_orig = {} self.to_leg = {} self.to_handle = {} #enable legend picking by setting the picker method for handel, origart in zip(self.legend.legendHandles, plots): #get_lines() self.to_orig[handel.markers] = NamedErrorbarContainer(origart) self.to_leg[handel.markers] = handel self.to_handle[origart[0]] = handel
def __init__(self, plots, offsets=None, linked=[], auto_legend=True, **legendkw): #TODO: update docstring #(optionally nested) Line2D objects or ErrorbarContainers ''' Parameters ---------- plots : list of plot objects List of ErrorbarContainers offsets : sequence of floats Initial offsets to use for Line2D objects linked : sequence of linked artists (or sequence of sequences of linked artists) all artists in the linked sequence will move together with all the others in the sequence when one of them is dragged. The offset text will only be displayed for the first artist in the sequence. auto_legend : boolean whether to create a legend or not Keywords -------- legendkw : dict, optional Keywords passed directly to axes.legend ''' self.selection = None self.select_point = None if offsets is None: offsets = np.zeros(len(plots)) #self.offsets = {} #map pickable artist to offset value for that artist self.tmp_offset = 0 #in case of pick without motion #self.plots = plots #= flatten(plots) self.ax = ax = plots[0][0].axes self.figure = ax.figure #initialize mapping self.draggables = {} #TODO: make this a indexable Ordered dict #initialize auto-connect ConnectionMixin.__init__(self, ax.figure) #esure linked argument is a nested list if len(linked) and isinstance(linked[0], ErrorbarContainer): #HACK linked = [linked] #np.atleast_2d does not work because it unpacks the ErrorbarContainer else: linked = list(linked) _friends = [f for _, *friends in linked for f in friends] #build the draggable objects for plot, offset in zip(plots, offsets): #if isinstance(plot, ErrorbarContainer): #NOTE: will need to check this when generalizing annotate = not plot in _friends #only annotate the "first" linked artist draggable = DraggableErrorbarContainer(plot, offset=offset, annotate=annotate) markers, _, _ = draggable #map Line2D to DraggableErrorbarContainer. The picker returns the markers. self.draggables[markers] = draggable #create ghost artists draggable.haunt() self.lines = list(self.draggables.keys()) #establish links for links in linked: link_set = [self.draggables[m] for m, _, _ in links] #set of linked DraggableErrorbarContainers for i, draggable in enumerate(link_set): draggable.linked = link_set #each linked artist carries a copy of all those artists linked to it #enable legend picking self.legend = None if legendkw or auto_legend: self.legend = DynamicLegend(ax, plots, legendkw) self.legend.connect()