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()
------------------------------------------------------------------------------
AppSumo Presents a FREE Video for the SourceForge Community by Eric
Ries, the creator of the Lean Startup Methodology on "Lean Startup
Secrets Revealed." This video shows you how to validate your ideas,
optimize your ideas and identify your business strategy.
http://p.sf.net/sfu/appsumosfdev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users