Figure Options dialog does not update the legend

The new Figure Options button in the PyQt plot toolbar is a really nice feature that allows the user to change the line style for curves in the plot. Unfortunately, the legend does not get updated, so the legend becomes out of sync with the plot - when a user changes a line from black to red, the legend will still show the line as black, for instance. Forcing the legend to redraw itself via a draw() operation does not solve the problem - it redraws, but still with the old color.

The issue seems to be that there doesn’t appear to be a way to have a legend update what its artists should look like based on their latest appearances. I’ve developed a fix for this that seems to work, but wanted to see if anyone had something better, or if people think I should submit this as a potential fix. I’m not thrilled with it (it will fail if there are multiple legends on the figure, for instance), but it does work for simple plots and figures with multiple subplots.

The fix is in the apply_callback function inside the the matplotlib.backends.qt4_editor.figureoptions.figure_edit function. I’ve included the whole function below, with the fix contained within the designated comments.

Comments? Is there an easier, better way to do this?

Dave

def apply_callback(data):
    """This function will be called to apply changes"""
    if has_curve:

        general, curves = data
    else:
        general, = data
       
    # Set / General
    title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale = general
    axes.set_xscale(xscale)

    axes.set_yscale(yscale)
    axes.set_title(title)
    axes.set_xlim(xmin, xmax)
    axes.set_xlabel(xlabel)
    axes.set_ylim(ymin, ymax)
    axes.set_ylabel(ylabel)

    if has_curve:

        # Set / Curves
        for index, curve in enumerate(curves):
            line = linedict[curvelabels[index]]
            label, linestyle, linewidth, color, \
                marker, markersize, markerfacecolor, markeredgecolor = curve

            line.set_label(label)
            line.set_linestyle(linestyle)
            line.set_linewidth(linewidth)
            line.set_color(color)
            if marker is not 'none':

                line.set_marker(marker)
                line.set_markersize(markersize)
                line.set_markerfacecolor(markerfacecolor)
                line.set_markeredgecolor(markeredgecolor)

Fix begins here

        # Recalculate the color and style of legend artists - note, this
        # does not work for multiple legends on the same figure.
        figure = axes.get_figure()

        all_axes = figure.get_axes()
        for legend in figure.legends:
            # Need to gather all the legend items from all the subplots
            all_handles = []            
            all_labels = []

            for one_axes in all_axes:
                handles, labels = one_axes.get_legend_handles_labels()
                all_handles.extend(handles)
                all_labels.extend(labels)

            # Location and title are altered by the _init_legend_box
            # function, so preserve the current values
            loc = legend._loc
            title = legend.get_title().get_text()

            if title == 'None':
                title = None
            # This function recalculates colors and styles
            legend._init_legend_box(all_handles, all_labels)
            legend._loc = loc

            legend.set_title(title)

Fix ends here

    # Redraw
    figure = axes.get_figure()
    figure.canvas.draw()