diff --git a/Framework/PythonInterface/mantid/plots/__init__.py b/Framework/PythonInterface/mantid/plots/__init__.py index 7ce38b4fc87b82bc384a9b413339977fb768d34b..8031d9567800cf57ebe109b57404da199b6ba535 100644 --- a/Framework/PythonInterface/mantid/plots/__init__.py +++ b/Framework/PythonInterface/mantid/plots/__init__.py @@ -19,7 +19,7 @@ try: from collections.abc import Iterable except ImportError: # check Python 2 location - from collections import Iterable + from collections import Iterable from matplotlib.axes import Axes from matplotlib.collections import Collection from matplotlib.colors import Colormap @@ -35,11 +35,11 @@ from mpl_toolkits.mplot3d.axes3d import Axes3D from mantid.api import AnalysisDataService as ads from mantid.kernel import logger from mantid.plots import helperfunctions, plotfunctions, plotfunctions3D -from mantid.plots.utility import autoscale_on_update +from mantid.plots.legend import LegendProperties from mantid.plots.helperfunctions import get_normalize_by_bin_width from mantid.plots.scales import PowerScale, SquareScale -from mantid.plots.utility import artists_hidden, MantidAxType, legend_set_draggable -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties +from mantid.plots.utility import (artists_hidden, autoscale_on_update, + legend_set_draggable, MantidAxType) def plot_decorator(func): diff --git a/Framework/PythonInterface/mantid/plots/legend.py b/Framework/PythonInterface/mantid/plots/legend.py new file mode 100644 index 0000000000000000000000000000000000000000..5cf25f89661cb7ddd62b5054bbab13c4b6bb12d8 --- /dev/null +++ b/Framework/PythonInterface/mantid/plots/legend.py @@ -0,0 +1,174 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2020 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + +# This file is part of the mantid package +# +# +""" +Functionality for dealing with legends on plots +""" +from __future__ import (absolute_import, division, print_function) + +import sys + +import matplotlib +from matplotlib import colors +from matplotlib.patches import BoxStyle + +from mantid.plots.utility import legend_set_draggable + + +def convert_color_to_hex(color): + """Convert a matplotlib color to its hex form""" + try: + return colors.cnames[color] + except (KeyError, TypeError): + rgb = colors.colorConverter.to_rgb(color) + return colors.rgb2hex(rgb) + + +class LegendProperties(dict): + def __getattr__(self, item): + return self[item] + + @classmethod + def from_legend(cls, legend): + props = dict() + + props['visible'] = legend.get_visible() + + title = legend.get_title() + if sys.version_info[0] >= 3: + if isinstance(title.get_text(), str): + props['title'] = title.get_text() + else: + props['title'] = None + else: + if isinstance(title.get_text(), unicode): + props['title'] = title.get_text() + else: + props['title'] = None + + props['title_font'] = title.get_fontname() + props['title_size'] = title.get_fontsize() + props['title_color'] = convert_color_to_hex(title.get_color()) + + props['box_visible'] = legend.get_frame_on() + + box = legend.get_frame() + props['background_color'] = convert_color_to_hex(box.get_facecolor()) + props['edge_color'] = convert_color_to_hex(box.get_edgecolor()) + props['transparency'] = box.get_alpha() + + text = legend.get_texts()[0] + props['entries_font'] = text.get_fontname() + props['entries_size'] = text.get_fontsize() + props['entries_color'] = convert_color_to_hex(text.get_color()) + + props['marker_size'] = legend.handlelength + props['shadow'] = legend.shadow + + boxstyle = legend.legendPatch.get_boxstyle() + if isinstance(boxstyle, BoxStyle.Round): + props['round_edges'] = True + else: + props['round_edges'] = False + + props['columns'] = legend._ncol + props['column_spacing'] = legend.columnspacing + props['label_spacing'] = legend.labelspacing + + position = legend._legend_handle_box.get_children()[0].align + if position == "baseline": + props['marker_position'] = "Left of Entries" + else: + props['marker_position'] = "Right of Entries" + + props['markers'] = legend.numpoints + props['border_padding'] = legend.borderpad + props['marker_label_padding'] = legend.handletextpad + + return cls(props) + + @classmethod + def from_view(cls, view): + props = dict() + props['visible'] = not view.hide_legend_check_box.isChecked() + props['title'] = view.get_title() + props['background_color'] = view.get_background_color() + props['edge_color'] = view.get_edge_color() + props['transparency'] = (100-float(view.get_transparency_spin_box_value()))/100 + props['entries_font'] = view.get_entries_font() + props['entries_size'] = view.get_entries_size() + props['entries_color'] = view.get_entries_color() + props['title_font'] = view.get_title_font() + props['title_size'] = view.get_title_size() + props['title_color'] = view.get_title_color() + props['marker_size'] = view.get_marker_size() + props['box_visible'] = not view.get_hide_box() + return cls(props) + + @classmethod + def from_view_advanced(cls, view): + props = dict() + props['shadow'] = view.get_shadow() + props['round_edges'] = view.get_round_edges() + props['columns'] = view.get_number_of_columns() + props['column_spacing'] = view.get_column_spacing() + props['label_spacing'] = view.get_label_spacing() + props['marker_position'] = view.get_marker_position() + props['markers'] = view.get_number_of_markers() + props['border_padding'] = view.get_border_padding() + props['marker_label_padding'] = view.get_marker_label_padding() + return cls(props) + + @classmethod + def create_legend(cls, props, ax): + if int(matplotlib.__version__[0]) >= 2: + legend = ax.legend(ncol=props['columns'], + prop={'size': props['entries_size']}, + numpoints=props['markers'], + markerfirst=props['marker_position'] == "Left of Entries", + frameon=props['box_visible'], + fancybox=props['round_edges'], + shadow=props['shadow'], + framealpha=props['transparency'], + facecolor=props['background_color'], + edgecolor=props['edge_color'], + title=props['title'], + borderpad=props['border_padding'], + labelspacing=props['label_spacing'], + handlelength=props['marker_size'], + handletextpad=props['marker_label_padding'], + columnspacing=props['column_spacing']) + else: + legend = ax.legend(ncol=props['columns'], + prop={'size': props['entries_size']}, + numpoints=props['markers'], + markerfirst=props['marker_position'] == "Left of Entries", + frameon=props['box_visible'], + fancybox=props['round_edges'], + shadow=props['shadow'], + framealpha=props['transparency'], + title=props['title'], + borderpad=props['border_padding'], + labelspacing=props['label_spacing'], + handlelength=props['marker_size'], + handletextpad=props['marker_label_padding'], + columnspacing=props['column_spacing']) + + title = legend.get_title() + title.set_fontname(props['title_font']) + title.set_fontsize(props['title_size']) + title.set_color(props['title_color']) + + for text in legend.get_texts(): + text.set_fontname(props['entries_font']) + text.set_fontsize(props['entries_size']) + text.set_color(props['entries_color']) + + legend.set_visible(props['visible']) + legend_set_draggable(legend, True) diff --git a/qt/applications/workbench/workbench/plotting/figureerrorsmanager.py b/qt/applications/workbench/workbench/plotting/figureerrorsmanager.py index f77488c193feb767a6c6a1aa1747c750a001b2d8..ac8d16650e1b1d1cb826c9601b41b6c73f3e8b80 100644 --- a/qt/applications/workbench/workbench/plotting/figureerrorsmanager.py +++ b/qt/applications/workbench/workbench/plotting/figureerrorsmanager.py @@ -12,8 +12,8 @@ from matplotlib.container import ErrorbarContainer from matplotlib.lines import Line2D from mantid.plots import MantidAxes from mantid.plots.helperfunctions import get_data_from_errorbar_container, set_errorbars_hidden +from mantid.plots.legend import LegendProperties from mantidqt.widgets.plotconfigdialog.curvestabwidget import curve_has_errors, CurveProperties, remove_curve_from_ax -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties class FigureErrorsManager(object): diff --git a/qt/python/mantidqt/project/plotsloader.py b/qt/python/mantidqt/project/plotsloader.py index 309998423ad26e10d528cf38546021858f0e1b0e..30505f16ee118ad6e51fc158c92b527df0f2765e 100644 --- a/qt/python/mantidqt/project/plotsloader.py +++ b/qt/python/mantidqt/project/plotsloader.py @@ -16,9 +16,10 @@ from matplotlib import axis, ticker # noqa from mantid import logger from mantid.api import AnalysisDataService as ADS +from mantid.plots.legend import LegendProperties # Constants set in workbench.plotting.functions but would cause backwards reliability from mantidqt.plotting.functions import pcolormesh -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties + SUBPLOT_WSPACE = 0.5 SUBPLOT_HSPACE = 0.5 diff --git a/qt/python/mantidqt/project/plotssaver.py b/qt/python/mantidqt/project/plotssaver.py index 615fd2dab26a51ab5dddd8f0e123f66aad1f1fcd..2622abeac9ea197d8b944400e44533dcd4b73cd4 100644 --- a/qt/python/mantidqt/project/plotssaver.py +++ b/qt/python/mantidqt/project/plotssaver.py @@ -13,7 +13,7 @@ from matplotlib import ticker from matplotlib.image import AxesImage from mantid import logger -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties +from mantid.plots.legend import LegendProperties try: from matplotlib.colors import to_hex diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/colorselector.py b/qt/python/mantidqt/widgets/plotconfigdialog/colorselector.py index 28cd82e7ed12864867d3ea55e8b11ca229c2772c..5e72ce5576633d10b0cca9f18b1f70f45cdf2b8a 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/colorselector.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/colorselector.py @@ -8,22 +8,14 @@ from __future__ import (absolute_import, unicode_literals) -from matplotlib import colors, rcParams +from mantid.plots.legend import convert_color_to_hex +from matplotlib import rcParams from qtpy.QtCore import QRegExp from qtpy.QtGui import QColor, QPalette, QRegExpValidator from qtpy.QtWidgets import (QWidget, QLineEdit, QPushButton, QHBoxLayout, QColorDialog) -def convert_color_to_hex(color): - """Convert a matplotlib color to its hex form""" - try: - return colors.cnames[color] - except (KeyError, TypeError): - rgb = colors.colorConverter.to_rgb(color) - return colors.rgb2hex(rgb) - - MPL_DEFAULT = convert_color_to_hex(rcParams['lines.color']) diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/curvestabwidget/presenter.py b/qt/python/mantidqt/widgets/plotconfigdialog/curvestabwidget/presenter.py index a634b85b517b1ddb427f862dd76a11f5f081a908..613c8c8d1c582e3d5dc0402344b722e08e604695 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/curvestabwidget/presenter.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/curvestabwidget/presenter.py @@ -8,12 +8,12 @@ from __future__ import (absolute_import, unicode_literals) +from mantid.plots.legend import LegendProperties from mantidqt.utils.qt import block_signals from mantidqt.widgets.plotconfigdialog import get_axes_names_dict, curve_in_ax from mantidqt.widgets.plotconfigdialog.curvestabwidget import ( CurveProperties, curve_has_errors, remove_curve_from_ax) from mantidqt.widgets.plotconfigdialog.curvestabwidget.view import CurvesTabWidgetView -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties from workbench.plotting.figureerrorsmanager import FigureErrorsManager diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py index 5e5ffb2aea1f1e66d05ccd6c287e3fe352bb7dba..db65bfdd56145fdd2d6d2eccf8d7684e66930c50 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/__init__.py @@ -7,155 +7,3 @@ # This file is part of the mantid workbench. from __future__ import (absolute_import, unicode_literals) - -from mantid.plots.utility import legend_set_draggable -from mantidqt.widgets.plotconfigdialog.colorselector import convert_color_to_hex -import matplotlib -from matplotlib.patches import BoxStyle - -import sys - - -class LegendProperties(dict): - def __getattr__(self, item): - return self[item] - - @classmethod - def from_legend(cls, legend): - props = dict() - - props['visible'] = legend.get_visible() - - title = legend.get_title() - if sys.version_info[0] >= 3: - if isinstance(title.get_text(), str): - props['title'] = title.get_text() - else: - props['title'] = None - else: - if isinstance(title.get_text(), unicode): - props['title'] = title.get_text() - else: - props['title'] = None - - props['title_font'] = title.get_fontname() - props['title_size'] = title.get_fontsize() - props['title_color'] = convert_color_to_hex(title.get_color()) - - props['box_visible'] = legend.get_frame_on() - - box = legend.get_frame() - props['background_color'] = convert_color_to_hex(box.get_facecolor()) - props['edge_color'] = convert_color_to_hex(box.get_edgecolor()) - props['transparency'] = box.get_alpha() - - text = legend.get_texts()[0] - props['entries_font'] = text.get_fontname() - props['entries_size'] = text.get_fontsize() - props['entries_color'] = convert_color_to_hex(text.get_color()) - - props['marker_size'] = legend.handlelength - props['shadow'] = legend.shadow - - boxstyle = legend.legendPatch.get_boxstyle() - if isinstance(boxstyle, BoxStyle.Round): - props['round_edges'] = True - else: - props['round_edges'] = False - - props['columns'] = legend._ncol - props['column_spacing'] = legend.columnspacing - props['label_spacing'] = legend.labelspacing - - position = legend._legend_handle_box.get_children()[0].align - if position == "baseline": - props['marker_position'] = "Left of Entries" - else: - props['marker_position'] = "Right of Entries" - - props['markers'] = legend.numpoints - props['border_padding'] = legend.borderpad - props['marker_label_padding'] = legend.handletextpad - - return cls(props) - - @classmethod - def from_view(cls, view): - props = dict() - props['visible'] = not view.hide_legend_check_box.isChecked() - props['title'] = view.get_title() - props['background_color'] = view.get_background_color() - props['edge_color'] = view.get_edge_color() - props['transparency'] = (100-float(view.get_transparency_spin_box_value()))/100 - props['entries_font'] = view.get_entries_font() - props['entries_size'] = view.get_entries_size() - props['entries_color'] = view.get_entries_color() - props['title_font'] = view.get_title_font() - props['title_size'] = view.get_title_size() - props['title_color'] = view.get_title_color() - props['marker_size'] = view.get_marker_size() - props['box_visible'] = not view.get_hide_box() - return cls(props) - - @classmethod - def from_view_advanced(cls, view): - props = dict() - props['shadow'] = view.get_shadow() - props['round_edges'] = view.get_round_edges() - props['columns'] = view.get_number_of_columns() - props['column_spacing'] = view.get_column_spacing() - props['label_spacing'] = view.get_label_spacing() - props['marker_position'] = view.get_marker_position() - props['markers'] = view.get_number_of_markers() - props['border_padding'] = view.get_border_padding() - props['marker_label_padding'] = view.get_marker_label_padding() - return cls(props) - - @classmethod - def create_legend(cls, props, ax): - if int(matplotlib.__version__[0]) >= 2: - legend = ax.legend(ncol=props['columns'], - prop={'size': props['entries_size']}, - numpoints=props['markers'], - markerfirst=props['marker_position'] == "Left of Entries", - frameon=props['box_visible'], - fancybox=props['round_edges'], - shadow=props['shadow'], - framealpha=props['transparency'], - facecolor=props['background_color'], - edgecolor=props['edge_color'], - title=props['title'], - borderpad=props['border_padding'], - labelspacing=props['label_spacing'], - handlelength=props['marker_size'], - handletextpad=props['marker_label_padding'], - columnspacing=props['column_spacing']) - else: - legend = ax.legend(ncol=props['columns'], - prop={'size': props['entries_size']}, - numpoints=props['markers'], - markerfirst=props['marker_position'] == "Left of Entries", - frameon=props['box_visible'], - fancybox=props['round_edges'], - shadow=props['shadow'], - framealpha=props['transparency'], - title=props['title'], - borderpad=props['border_padding'], - labelspacing=props['label_spacing'], - handlelength=props['marker_size'], - handletextpad=props['marker_label_padding'], - columnspacing=props['column_spacing']) - - title = legend.get_title() - title.set_fontname(props['title_font']) - title.set_fontsize(props['title_size']) - title.set_color(props['title_color']) - - for text in legend.get_texts(): - text.set_fontname(props['entries_font']) - text.set_fontsize(props['entries_size']) - text.set_color(props['entries_color']) - - legend.set_visible(props['visible']) - - legend_set_draggable(legend, True) diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/advancedlegendoptionsdialog/view.py b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/advancedlegendoptionsdialog/view.py index f8d52ef6f10b9e257f3b67b4582658727505e068..aeb8953684ace67c7cd50df244fcf0398b704450 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/advancedlegendoptionsdialog/view.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/advancedlegendoptionsdialog/view.py @@ -12,8 +12,8 @@ from qtpy.QtCore import Qt, QSize from qtpy.QtGui import QIcon from qtpy.QtWidgets import QDialog +from mantid.plots.legend import LegendProperties from mantidqt.utils.qt import load_ui -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties class AdvancedLegendOptionsView(QDialog): diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py index 1628fca82994c54a4c31d6d93fd3443d9e30ebca..0d0a98ad86a59d4db04c3f5141c51b70d4cfaf6e 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/presenter.py @@ -8,8 +8,8 @@ from __future__ import (absolute_import, unicode_literals) +from mantid.plots.legend import LegendProperties from mantidqt.widgets.plotconfigdialog.legendtabwidget.view import LegendTabWidgetView -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties import matplotlib import matplotlib.font_manager diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/view.py b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/view.py index 44e930baad4cf1f5700e100d3abdcde0d3b250cf..03688639f8b6562fc1a4f83d731b438ac8a818da 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/view.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/legendtabwidget/view.py @@ -11,9 +11,9 @@ from __future__ import (absolute_import, unicode_literals) from qtpy.QtCore import Qt from qtpy.QtWidgets import QWidget +from mantid.plots.legend import LegendProperties from mantidqt.utils.qt import load_ui from mantidqt.widgets.plotconfigdialog.colorselector import ColorSelector -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties from mantidqt.widgets.plotconfigdialog.legendtabwidget.advancedlegendoptionsdialog.view import AdvancedLegendOptionsView diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/test/test_apply_all_properties.py b/qt/python/mantidqt/widgets/plotconfigdialog/test/test_apply_all_properties.py index 142baa29fbdb5d94be52dbe0d96270873ac130f7..a018b5bb42f9a4a521dc69324804a95daad59ead 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/test/test_apply_all_properties.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/test/test_apply_all_properties.py @@ -16,12 +16,12 @@ from matplotlib.colors import LogNorm from matplotlib.patches import BoxStyle from matplotlib.pyplot import figure +from mantid.plots.legend import LegendProperties from mantid.py3compat.mock import Mock, patch from mantidqt.widgets.plotconfigdialog.colorselector import convert_color_to_hex from mantidqt.widgets.plotconfigdialog.axestabwidget import AxProperties from mantidqt.widgets.plotconfigdialog.imagestabwidget import ImageProperties from mantidqt.widgets.plotconfigdialog.curvestabwidget import CurveProperties -from mantidqt.widgets.plotconfigdialog.legendtabwidget import LegendProperties from mantidqt.widgets.plotconfigdialog.presenter import PlotConfigDialogPresenter AX_VIEW = 'mantidqt.widgets.plotconfigdialog.axestabwidget.presenter.AxesTabWidgetView'