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?
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()