# -*- coding: utf-8 -*- # # Copyright © 2009 Pierre Raybaut # Licensed under the terms of the MIT License # see the mpl licenses directory for a copy of the license """Module that provides a GUI-based editor for matplotlib's figure options""" from __future__ import (absolute_import, division, print_function, unicode_literals) from matplotlib.externals import six import os.path as osp import matplotlib.backends.qt_editor.formlayout as formlayout from matplotlib.backends.qt_compat import QtGui from matplotlib import markers from matplotlib.colors import colorConverter, rgb2hex def get_icon(name): import matplotlib basedir = osp.join(matplotlib.rcParams['datapath'], 'images') return QtGui.QIcon(osp.join(basedir, name)) LINESTYLES = {'-': 'Solid', '--': 'Dashed', '-.': 'DashDot', ':': 'Dotted', 'none': 'None', } DRAWSTYLES = {'default': 'Default', 'steps': 'Steps', } MARKERS = markers.MarkerStyle.markers 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 = axes.get_xlim() ymin, ymax = axes.get_ylim() general = [('Title', axes.get_title()), sep, (None, "X-Axis"), ('Min', xmin), ('Max', xmax), ('Label', axes.get_xlabel()), ('Scale', [axes.get_xscale(), 'linear', 'log']), sep, (None, "Y-Axis"), ('Min', ymin), ('Max', ymax), ('Label', axes.get_ylabel()), ('Scale', [axes.get_yscale(), 'linear', 'log']), sep, ('(Re-)Generate automatic legend', False), ] # Save the unit data xconverter = axes.xaxis.converter yconverter = axes.yaxis.converter 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 = [] linestyles = list(six.iteritems(LINESTYLES)) drawstyles = list(six.iteritems(DRAWSTYLES)) markers = list(six.iteritems(MARKERS)) 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', [line.get_linestyle()] + linestyles), ('Draw Style', [line.get_drawstyle()] + drawstyles), ('Width', line.get_linewidth()), ('Color', color), sep, (None, 'Marker'), ('Style', [line.get_marker()] + markers), ('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) datalist = [(general, "Axes", "")] if has_curve: datalist.append((curves, "Curves", "")) 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, \ generate_legend = 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) # Restore the unit data axes.xaxis.converter = xconverter axes.yaxis.converter = yconverter axes.xaxis.set_units(xunits) axes.yaxis.set_units(yunits) 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) # re-generate legend, if checkbox is checked if generate_legend: draggable = None ncol = 1 if axes.legend_ is not None: old_legend = axes.get_legend() draggable = old_legend._draggable is not None ncol = old_legend._ncol new_legend = axes.legend(ncol=ncol) if new_legend: new_legend.draggable(draggable) # Redraw figure = axes.get_figure() figure.canvas.draw() data = formlayout.fedit(datalist, title="Figure options", parent=parent, icon=get_icon('qt4_editor_options.svg'), apply=apply_callback) if data is not None: apply_callback(data)