Limit legend to visible data

Is there a straightforward way to limit the legend only to lines that
appear within the current display limits? I have a plot that has too
many separate data series to show on the legend at once, but once I
zoom in it would be good to re-set the legend to show only the visible
data points/lines.

I guess the way to do that is:

- catch the DrawEvent
- call get_xlim() and get_ylim() to get the new bounds
- figure out which lines are within the bounds and add them to a new
legend. I could run through each line and compare xlim/ylim with
line.get_xydata(); is there already a function to do this?

Thanks for your help,
    Justin

This seems to do the trick, but might be a bit too clever. I'm not
sure if get_children() (or findobjs) is the right call to retrieve all
the plot elements.

def add_legend_viewlim(ax, fontsize='xx-small', **kwargs):
    """Reset the legend in ax to only display lines that are currenlty
visible"""
    label_objs =
    label_texts =
    font = matplotlib.font_manager.FontProperties(size=fontsize);
    for obj in ax.get_children():
        if not hasattr(obj, 'get_xydata'): continue
        if ax.viewLim.overlaps(matplotlib.transforms.Bbox(obj.get_xydata())):
            label = obj.get_label()
            if (label is not None) and (label != ''):
                label_objs.append(obj)
                label_texts.append(label)
    leg = ax.legend(label_objs, label_texts, prop=font, **kwargs)
    return leg

···

On Wed, Dec 1, 2010 at 11:58 AM, Justin McCann <jneilm@...287...> wrote:

Is there a straightforward way to limit the legend only to lines that
appear within the current display limits? I have a plot that has too
many separate data series to show on the legend at once, but once I
zoom in it would be good to re-set the legend to show only the visible
data points/lines.

I guess the way to do that is:

- catch the DrawEvent
- call get_xlim() and get_ylim() to get the new bounds
- figure out which lines are within the bounds and add them to a new
legend. I could run through each line and compare xlim/ylim with
line.get_xydata(); is there already a function to do this?

2010/12/3 Justin McCann <jneilm@...287...>:

···

On Wed, Dec 1, 2010 at 11:58 AM, Justin McCann <jneilm@...287...> wrote:
This seems to do the trick, but might be a bit too clever. I'm not
sure if get_children() (or findobjs) is the right call to retrieve all
the plot elements.

If you are just looking for line2D instances then use ax.get_lines().

Goyo