diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index fa0a42f17c99..dec202cdef9e 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1703,6 +1703,8 @@ def add_image(self, image): Returns the image. """ self._set_artist_props(image) + if not image.get_label(): + image.set_label('_image%d' % len(self.images)) self.images.append(image) image._remove_method = lambda h: self.images.remove(h) return image diff --git a/lib/matplotlib/backends/backend_qt5.py b/lib/matplotlib/backends/backend_qt5.py index cea7b5d7b21c..fc24fe186f1d 100644 --- a/lib/matplotlib/backends/backend_qt5.py +++ b/lib/matplotlib/backends/backend_qt5.py @@ -587,7 +587,7 @@ def _init_toolbar(self): if figureoptions is not None: a = self.addAction(self._icon("qt4_editor_options.png"), 'Customize', self.edit_parameters) - a.setToolTip('Edit curves line and axes parameters') + a.setToolTip('Edit axis, curve and image parameters') self.buttons = {} diff --git a/lib/matplotlib/backends/qt_editor/figureoptions.py b/lib/matplotlib/backends/qt_editor/figureoptions.py index f2fc9e115efc..566c06d8bfb5 100644 --- a/lib/matplotlib/backends/qt_editor/figureoptions.py +++ b/lib/matplotlib/backends/qt_editor/figureoptions.py @@ -16,7 +16,7 @@ import matplotlib.backends.qt_editor.formlayout as formlayout from matplotlib.backends.qt_compat import QtGui -from matplotlib import markers +from matplotlib import cm, markers from matplotlib.colors import colorConverter, rgb2hex @@ -43,8 +43,6 @@ def figure_edit(axes, parent=None): """Edit matplotlib figure options""" sep = (None, None) # separator - has_curve = len(axes.get_lines()) > 0 - # Get / General xmin, xmax = map(float, axes.get_xlim()) ymin, ymax = map(float, axes.get_ylim()) @@ -69,79 +67,103 @@ def figure_edit(axes, parent=None): xunits = axes.xaxis.get_units() yunits = axes.yaxis.get_units() - if has_curve: - # Get / Curves - linedict = {} - for line in axes.get_lines(): - label = line.get_label() - if label == '_nolegend_': - continue - linedict[label] = line - curves = [] - - def prepare_data(d, init): - """Prepare entry for FormLayout. - - `d` is a mapping of shorthands to style names (a single style may - have multiple shorthands, in particular the shorthands `None`, - `"None"`, `"none"` and `""` are synonyms); `init` is one shorthand - of the initial style. - - This function returns an list suitable for initializing a - FormLayout combobox, namely `[initial_name, (shorthand, - style_name), (shorthand, style_name), ...]`. - """ - # Drop duplicate shorthands from dict (by overwriting them during - # the dict comprehension). - name2short = {name: short for short, name in d.items()} - # Convert back to {shorthand: name}. - short2name = {short: name for name, short in name2short.items()} - # Find the kept shorthand for the style specified by init. - canonical_init = name2short[d[init]] - # Sort by representation and prepend the initial value. - return ([canonical_init] + - sorted(short2name.items(), - key=lambda short_and_name: short_and_name[1])) - - curvelabels = sorted(linedict.keys()) - for label in curvelabels: - line = linedict[label] - color = rgb2hex(colorConverter.to_rgb(line.get_color())) - ec = rgb2hex(colorConverter.to_rgb(line.get_markeredgecolor())) - fc = rgb2hex(colorConverter.to_rgb(line.get_markerfacecolor())) - curvedata = [ - ('Label', label), - sep, - (None, 'Line'), - ('Line Style', prepare_data(LINESTYLES, line.get_linestyle())), - ('Draw Style', prepare_data(DRAWSTYLES, line.get_drawstyle())), - ('Width', line.get_linewidth()), - ('Color', color), - sep, - (None, 'Marker'), - ('Style', prepare_data(MARKERS, line.get_marker())), - ('Size', line.get_markersize()), - ('Facecolor', fc), - ('Edgecolor', ec)] - curves.append([curvedata, label, ""]) - - # make sure that there is at least one displayed curve - has_curve = bool(curves) + # Get / Curves + linedict = {} + for line in axes.get_lines(): + label = line.get_label() + if label == '_nolegend_': + continue + linedict[label] = line + curves = [] + + def prepare_data(d, init): + """Prepare entry for FormLayout. + + `d` is a mapping of shorthands to style names (a single style may + have multiple shorthands, in particular the shorthands `None`, + `"None"`, `"none"` and `""` are synonyms); `init` is one shorthand + of the initial style. + + This function returns an list suitable for initializing a + FormLayout combobox, namely `[initial_name, (shorthand, + style_name), (shorthand, style_name), ...]`. + """ + # Drop duplicate shorthands from dict (by overwriting them during + # the dict comprehension). + name2short = {name: short for short, name in d.items()} + # Convert back to {shorthand: name}. + short2name = {short: name for name, short in name2short.items()} + # Find the kept shorthand for the style specified by init. + canonical_init = name2short[d[init]] + # Sort by representation and prepend the initial value. + return ([canonical_init] + + sorted(short2name.items(), + key=lambda short_and_name: short_and_name[1])) + + curvelabels = sorted(linedict.keys()) + for label in curvelabels: + line = linedict[label] + color = rgb2hex(colorConverter.to_rgb(line.get_color())) + ec = rgb2hex(colorConverter.to_rgb(line.get_markeredgecolor())) + fc = rgb2hex(colorConverter.to_rgb(line.get_markerfacecolor())) + curvedata = [ + ('Label', label), + sep, + (None, 'Line'), + ('Line Style', prepare_data(LINESTYLES, line.get_linestyle())), + ('Draw Style', prepare_data(DRAWSTYLES, line.get_drawstyle())), + ('Width', line.get_linewidth()), + ('Color', color), + sep, + (None, 'Marker'), + ('Style', prepare_data(MARKERS, line.get_marker())), + ('Size', line.get_markersize()), + ('Facecolor', fc), + ('Edgecolor', ec)] + curves.append([curvedata, label, ""]) + # Is there a curve displayed? + has_curve = bool(curves) + + # Get / Images + imagedict = {} + for image in axes.get_images(): + label = image.get_label() + if label == '_nolegend_': + continue + imagedict[label] = image + imagelabels = sorted(imagedict) + images = [] + cmaps = [(cmap, name) for name, cmap in sorted(cm.cmap_d.items())] + for label in imagelabels: + image = imagedict[label] + cmap = image.get_cmap() + if cmap not in cm.cmap_d: + cmaps = [(cmap, cmap.name)] + cmaps + imagedata = [ + ('Label', label), + ('Colormap', [cmap.name] + cmaps) + ] + images.append([imagedata, label, ""]) + # Is there an image displayed? + has_image = bool(images) datalist = [(general, "Axes", "")] - if has_curve: + if curves: datalist.append((curves, "Curves", "")) + if images: + datalist.append((images, "Images", "")) def apply_callback(data): """This function will be called to apply changes""" - if has_curve: - general, curves = data - else: - general, = data + general = data.pop(0) + curves = data.pop(0) if has_curve else [] + images = data.pop(0) if has_image else [] + if data: + raise ValueError("Unexpected field") # Set / General - title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale, \ - generate_legend = general + (title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale, + generate_legend) = general axes.set_xscale(xscale) axes.set_yscale(yscale) axes.set_title(title) @@ -158,26 +180,30 @@ def apply_callback(data): axes.xaxis._update_axisinfo() axes.yaxis._update_axisinfo() - if has_curve: - # Set / Curves - for index, curve in enumerate(curves): - line = linedict[curvelabels[index]] - label, linestyle, drawstyle, linewidth, color, \ - marker, markersize, markerfacecolor, markeredgecolor \ - = curve - line.set_label(label) - line.set_linestyle(linestyle) - line.set_drawstyle(drawstyle) - 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) + # Set / Curves + for index, curve in enumerate(curves): + line = linedict[curvelabels[index]] + (label, linestyle, drawstyle, linewidth, color, marker, markersize, + markerfacecolor, markeredgecolor) = curve + line.set_label(label) + line.set_linestyle(linestyle) + line.set_drawstyle(drawstyle) + 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) + + # Set / Images + for index, image_settings in enumerate(images): + image = imagedict[imagelabels[index]] + label, cmap = image_settings + image.set_label(label) + image.set_cmap(cm.get_cmap(cmap)) # re-generate legend, if checkbox is checked - if generate_legend: draggable = None ncol = None