diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/__init__.py b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/__init__.py index 96bd7a51cb88ea107b07c806f0b42dc9860e7b4d..2643519a86f07190c5aaf30db33d6d89cf1a0e1f 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/__init__.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/__init__.py @@ -6,6 +6,7 @@ # SPDX - License - Identifier: GPL - 3.0 + # This file is part of the mantid workbench. +from mpl_toolkits.mplot3d import Axes3D class AxProperties(dict): """ @@ -29,16 +30,22 @@ class AxProperties(dict): props['ylim'] = ax.get_ylim() props['ylabel'] = ax.get_ylabel() props['yscale'] = ax.get_yscale().title() + + if isinstance(ax, Axes3D): + props['zlim'] = ax.get_zlim() + props['zlabel'] = ax.get_zlabel() + props['zscale'] = ax.get_zscale().title() + return cls(props) @classmethod def from_view(cls, view): props = dict() props['title'] = view.get_title() - props['xlim'] = (view.get_xlower_limit(), view.get_xupper_limit()) - props['ylim'] = (view.get_ylower_limit(), view.get_yupper_limit()) - props['xlabel'] = view.get_xlabel() - props['xscale'] = view.get_xscale() - props['ylabel'] = view.get_ylabel() - props['yscale'] = view.get_yscale() + + ax = view.get_axis() + props[f'{ax}lim'] = (view.get_lower_limit(), view.get_upper_limit()) + props[f'{ax}label'] = view.get_label() + props[f'{ax}scale'] = view.get_scale() + return cls(props) diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/axes_tab_widget.ui b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/axes_tab_widget.ui index 0ee043e67222efc026093b7435269e48c9456247..593b8a13bfa6638748d5bc8c6affcef0872a77de 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/axes_tab_widget.ui +++ b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/axes_tab_widget.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>381</width> + <width>387</width> <height>586</height> </rect> </property> @@ -14,6 +14,23 @@ <string>Form</string> </property> <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="axes_selector_layout"> + <property name="topMargin"> + <number>5</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Select a set of axes</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="select_axes_combo_box"/> + </item> + </layout> + </item> <item row="1" column="0"> <spacer name="verticalSpacer_6"> <property name="orientation"> @@ -40,36 +57,6 @@ </property> </spacer> </item> - <item row="5" column="0"> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="0"> - <layout class="QVBoxLayout" name="axes_selector_layout"> - <property name="topMargin"> - <number>5</number> - </property> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Select a set of axes</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="select_axes_combo_box"/> - </item> - </layout> - </item> <item row="2" column="0"> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="topMargin"> @@ -125,75 +112,56 @@ </item> </layout> </item> - <item row="4" column="0"> - <layout class="QGridLayout" name="gridLayout"> - <property name="topMargin"> - <number>4</number> - </property> - <property name="bottomMargin"> - <number>4</number> - </property> - <item row="1" column="2"> - <widget class="QLineEdit" name="xlower_limit_line_edit"/> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="x_right_limit_label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item row="5" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item alignment="Qt::AlignHCenter"> + <widget class="QRadioButton" name="x_radio_button"> <property name="text"> - <string>Upper Limit</string> + <string>x</string> </property> + <property name="checked"> + <bool>true</bool> + </property> + <attribute name="buttonGroup"> + <string notr="true">axis_button_group</string> + </attribute> </widget> </item> - <item row="4" column="0"> - <widget class="QLabel" name="x_scale_label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item alignment="Qt::AlignHCenter"> + <widget class="QRadioButton" name="y_radio_button"> <property name="text"> - <string>Scale</string> + <string>y</string> </property> + <attribute name="buttonGroup"> + <string notr="true">axis_button_group</string> + </attribute> </widget> </item> - <item row="4" column="2"> - <widget class="QComboBox" name="xscale_combo_box"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item alignment="Qt::AlignHCenter"> + <widget class="QRadioButton" name="z_radio_button"> + <property name="enabled"> + <bool>false</bool> </property> - <item> - <property name="text"> - <string>Linear</string> - </property> - </item> - <item> - <property name="text"> - <string>Log</string> - </property> - </item> - <item> - <property name="text"> - <string>Symlog</string> - </property> - </item> - <item> - <property name="text"> - <string>Logit</string> - </property> - </item> + <property name="text"> + <string>z</string> + </property> + <attribute name="buttonGroup"> + <string notr="true">axis_button_group</string> + </attribute> </widget> </item> - <item row="4" column="1"> - <spacer name="horizontalSpacer_5"> + </layout> + </item> + <item row="14" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <property name="topMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item row="2" column="1"> + <spacer name="horizontalSpacer_4"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -208,8 +176,8 @@ </property> </spacer> </item> - <item row="3" column="1"> - <spacer name="horizontalSpacer_4"> + <item row="0" column="1"> + <spacer name="horizontalSpacer_2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -224,21 +192,8 @@ </property> </spacer> </item> - <item row="0" column="0"> - <widget class="QLabel" name="x_axis_label"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>X-Axis</string> - </property> - </widget> - </item> <item row="3" column="0"> - <widget class="QLabel" name="x_label_label"> + <widget class="QLabel" name="scale_label"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -246,43 +201,11 @@ </sizepolicy> </property> <property name="text"> - <string>Label</string> - </property> - </widget> - </item> - <item row="3" column="2"> - <widget class="QLineEdit" name="xlabel_line_edit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>211</width> - <height>20</height> - </size> + <string>Scale</string> </property> </widget> </item> <item row="1" column="1"> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>58</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="2" column="1"> <spacer name="horizontalSpacer_3"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -298,47 +221,38 @@ </property> </spacer> </item> - <item row="1" column="0"> - <widget class="QLabel" name="x_left_limit_label"> + <item row="3" column="2"> + <widget class="QComboBox" name="scale_combo_box"> <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="text"> - <string>Lower Limit</string> - </property> - </widget> - </item> - <item row="2" column="2"> - <widget class="QLineEdit" name="xupper_limit_line_edit"/> - </item> - </layout> - </item> - <item row="6" column="0"> - <layout class="QGridLayout" name="gridLayout_2"> - <property name="topMargin"> - <number>4</number> - </property> - <property name="bottomMargin"> - <number>4</number> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="y_axis_label"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>Y-Axis</string> - </property> + <item> + <property name="text"> + <string>Linear</string> + </property> + </item> + <item> + <property name="text"> + <string>Log</string> + </property> + </item> + <item> + <property name="text"> + <string>Symlog</string> + </property> + </item> + <item> + <property name="text"> + <string>Logit</string> + </property> + </item> </widget> </item> - <item row="1" column="0"> - <widget class="QLabel" name="y_left_limit_label"> + <item row="2" column="0"> + <widget class="QLabel" name="label_label"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -346,12 +260,15 @@ </sizepolicy> </property> <property name="text"> - <string>Lower Limit</string> + <string>Label</string> </property> </widget> </item> - <item row="2" column="0"> - <widget class="QLabel" name="y_right_limit_label"> + <item row="1" column="2"> + <widget class="QLineEdit" name="upper_limit_line_edit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="right_limit_label"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -363,24 +280,8 @@ </property> </widget> </item> - <item row="2" column="1"> - <spacer name="horizontalSpacer_7"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>58</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="3" column="2"> - <widget class="QLineEdit" name="ylabel_line_edit"> + <item row="2" column="2"> + <widget class="QLineEdit" name="label_line_edit"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -395,51 +296,11 @@ </property> </widget> </item> - <item row="4" column="0"> - <widget class="QLabel" name="y_scale_label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Scale</string> - </property> - </widget> - </item> - <item row="4" column="2"> - <widget class="QComboBox" name="yscale_combo_box"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <item> - <property name="text"> - <string>Linear</string> - </property> - </item> - <item> - <property name="text"> - <string>Log</string> - </property> - </item> - <item> - <property name="text"> - <string>Symlog</string> - </property> - </item> - <item> - <property name="text"> - <string>Logit</string> - </property> - </item> - </widget> + <item row="0" column="2"> + <widget class="QLineEdit" name="lower_limit_line_edit"/> </item> - <item row="4" column="1"> - <spacer name="horizontalSpacer_9"> + <item row="3" column="1"> + <spacer name="horizontalSpacer_5"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -454,8 +315,8 @@ </property> </spacer> </item> - <item row="3" column="0"> - <widget class="QLabel" name="y_label_label"> + <item row="0" column="0"> + <widget class="QLabel" name="left_limit_label"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -463,52 +324,14 @@ </sizepolicy> </property> <property name="text"> - <string>Label</string> + <string>Lower Limit</string> </property> </widget> </item> - <item row="3" column="1"> - <spacer name="horizontalSpacer_8"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>58</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="1" column="1"> - <spacer name="horizontalSpacer_10"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>58</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="1" column="2"> - <widget class="QLineEdit" name="ylower_limit_line_edit"/> - </item> - <item row="2" column="2"> - <widget class="QLineEdit" name="yupper_limit_line_edit"/> - </item> </layout> </item> - <item row="7" column="0"> - <spacer name="verticalSpacer_3"> + <item row="15" column="0"> + <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> @@ -525,11 +348,12 @@ <tabstops> <tabstop>select_axes_combo_box</tabstop> <tabstop>axes_title_line_edit</tabstop> - <tabstop>xlabel_line_edit</tabstop> - <tabstop>xscale_combo_box</tabstop> - <tabstop>ylabel_line_edit</tabstop> - <tabstop>yscale_combo_box</tabstop> + <tabstop>label_line_edit</tabstop> + <tabstop>scale_combo_box</tabstop> </tabstops> <resources/> <connections/> + <buttongroups> + <buttongroup name="axis_button_group"/> + </buttongroups> </ui> diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/presenter.py b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/presenter.py index 982a686cd6f4e91b40ace8b63e6ef3cf1cf28809..511dedf0c93329e11739a868551e2cd5d1c48e9b 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/presenter.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/presenter.py @@ -6,6 +6,8 @@ # SPDX - License - Identifier: GPL - 3.0 + # This file is part of the mantid workbench. +from mpl_toolkits.mplot3d import Axes3D + from mantidqt.widgets.plotconfigdialog import generate_ax_name, get_axes_names_dict from mantidqt.widgets.plotconfigdialog.axestabwidget import AxProperties from mantidqt.widgets.plotconfigdialog.axestabwidget.view import AxesTabWidgetView @@ -23,7 +25,9 @@ class AxesTabWidgetPresenter: # Store a copy of the current view props. This allows us to tell if any # properties have been changed by the user; especially solving issues # with x and y axis limits interfering with figure autoscaling - self.current_view_props = None + self.current_view_props = {} + + self.current_axis = "x" # Dictionary mapping ax name to Axes object self.axes_names_dict = get_axes_names_dict(self.fig) @@ -35,29 +39,34 @@ class AxesTabWidgetPresenter: # Signals self.view.select_axes_combo_box.currentIndexChanged.connect( self.update_view) + self.view.axis_button_group.buttonClicked.connect( + self.axis_changed) def apply_properties(self): """Update the axes with the user inputted properties""" + # Make sure current_view_props is up to date if values have been changed + self.axis_changed() + ax = self.get_selected_ax() - try: - new_props = self.view.get_properties() - except ValueError as e: - self.view.error_occurred(str(e)) - else: - self.set_ax_title(ax, new_props.title) - ax.set_xlabel(new_props.xlabel) - ax.set_xscale(new_props.xscale) - if new_props.xscale == 'Log' and new_props.xlim[0] < 0: - ax.set_xlim(new_props.xlim[1]*0.01, new_props.xlim[1]) - else: - ax.set_xlim(new_props.xlim) - ax.set_ylabel(new_props.ylabel) - ax.set_yscale(new_props.yscale) - if new_props.yscale == 'Log' and new_props.ylim[0] < 0: - ax.set_ylim(new_props.ylim[1]*0.01, new_props.ylim[1]) - else: - ax.set_ylim(new_props.ylim) - self.update_view() + + self.set_ax_title(ax, self.current_view_props['title']) + + if "xlabel" in self.current_view_props: + ax.set_xlabel(self.current_view_props['xlabel']) + ax.set_xscale(self.current_view_props['xscale']) + ax.set_xlim(self.current_view_props['xlim']) + + if "ylabel" in self.current_view_props: + ax.set_ylabel(self.current_view_props['ylabel']) + ax.set_yscale(self.current_view_props['yscale']) + ax.set_ylim(self.current_view_props['ylim']) + + if "zlabel" in self.current_view_props: + ax.set_zlabel(self.current_view_props['zlabel']) + ax.set_zscale(self.current_view_props['zscale']) + ax.set_zlim(self.current_view_props['zlim']) + + self.update_view() def get_selected_ax(self): """Get Axes object of selected axes""" @@ -95,13 +104,39 @@ class AxesTabWidgetPresenter: def update_view(self): """Update the properties in the view from the selected axes""" ax_props = self.get_selected_ax_properties() + + # Enable the z-axis option if the plot is 3D. + self.view.z_radio_button.setEnabled("zlim" in ax_props) + + # Changing the axis scale doesn't work with 3D plots, this is a known matplotlib issue, + # so the scale option is disabled. + self.view.scale_combo_box.setEnabled("zlim" not in ax_props) + + ax = self.view.get_axis() self.view.set_title(ax_props.title) - self.view.set_xlower_limit(ax_props.xlim[0]) - self.view.set_xupper_limit(ax_props.xlim[1]) - self.view.set_xlabel(ax_props.xlabel) - self.view.set_xscale(ax_props.xscale) - self.view.set_ylower_limit(ax_props.ylim[0]) - self.view.set_yupper_limit(ax_props.ylim[1]) - self.view.set_ylabel(ax_props.ylabel) - self.view.set_yscale(ax_props.yscale) - self.current_view_props = AxProperties.from_view(self.view) + lim = ax_props[f"{ax}lim"] + self.view.set_lower_limit(lim[0]) + self.view.set_upper_limit(lim[1]) + self.view.set_label(ax_props[f"{ax}label"]) + self.view.set_scale(ax_props[f"{ax}scale"]) + + self.current_view_props.update(self.view.get_properties()) + + def axis_changed(self): + ax = self.current_axis + + self.current_view_props[f"{ax}lim"] = (self.view.get_lower_limit(), self.view.get_upper_limit()) + self.current_view_props[f"{ax}label"] = self.view.get_label() + self.current_view_props[f"{ax}scale"] = self.view.get_scale() + + new_ax = self.view.get_axis() + self.current_axis = new_ax + + if f"{new_ax}lim" in self.current_view_props: + lim = self.current_view_props[f"{new_ax}lim"] + self.view.set_lower_limit(lim[0]) + self.view.set_upper_limit(lim[1]) + self.view.set_label(self.current_view_props[f"{new_ax}label"]) + self.view.set_scale(self.current_view_props[f"{new_ax}scale"]) + else: + self.update_view() diff --git a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/view.py b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/view.py index c8924fb4bb1cbc769be71eb4a586ffe8a301e041..28dc20df1795b54041e1ad6930802dd3ad0f27b1 100644 --- a/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/view.py +++ b/qt/python/mantidqt/widgets/plotconfigdialog/axestabwidget/view.py @@ -25,11 +25,10 @@ class AxesTabWidgetView(QWidget): self.setAttribute(Qt.WA_DeleteOnClose, True) # Set validator for the axis limit spin boxes - for axis in ['x', 'y']: - for limit in ['upper', 'lower']: - line_edit = getattr(self, '%s%s_limit_line_edit' % (axis, limit)) - validator = QDoubleValidator() - line_edit.setValidator(validator) + for limit in ['upper', 'lower']: + line_edit = getattr(self, f'{limit}_limit_line_edit') + validator = QDoubleValidator() + line_edit.setValidator(validator) def populate_select_axes_combo_box(self, axes_names): self.select_axes_combo_box.addItems(axes_names) @@ -51,57 +50,29 @@ class AxesTabWidgetView(QWidget): def set_title(self, title): self.axes_title_line_edit.setText(title) - # X-Axis getters - def get_xlower_limit(self): - return float(self.xlower_limit_line_edit.text()) + def get_lower_limit(self): + return float(self.lower_limit_line_edit.text()) - def get_xupper_limit(self): - return float(self.xupper_limit_line_edit.text()) + def get_upper_limit(self): + return float(self.upper_limit_line_edit.text()) - def get_xlabel(self): - return self.xlabel_line_edit.text() + def get_label(self): + return self.label_line_edit.text() - def get_xscale(self): - return self.xscale_combo_box.currentText() + def get_scale(self): + return self.scale_combo_box.currentText() - # Y-Axis getters - def get_ylower_limit(self): - return float(self.ylower_limit_line_edit.text()) + def set_lower_limit(self, limit): + self.lower_limit_line_edit.setText(str(limit)) - def get_yupper_limit(self): - return float(self.yupper_limit_line_edit.text()) + def set_upper_limit(self, limit): + self.upper_limit_line_edit.setText(str(limit)) - def get_ylabel(self): - return self.ylabel_line_edit.text() + def set_label(self, label): + self.label_line_edit.setText(label) - def get_yscale(self): - return self.yscale_combo_box.currentText() + def set_scale(self, scale): + self.scale_combo_box.setCurrentText(scale.title()) - # X-Axis setters - def set_xlower_limit(self, limit): - self.xlower_limit_line_edit.setText(str(limit)) - - def set_xupper_limit(self, limit): - self.xupper_limit_line_edit.setText(str(limit)) - - def set_xlabel(self, label): - self.xlabel_line_edit.setText(label) - - def set_xscale(self, scale): - self.xscale_combo_box.setCurrentText(scale.title()) - - # Y-Axis setters - def set_ylower_limit(self, limit): - self.ylower_limit_line_edit.setText(str(limit)) - - def set_yupper_limit(self, limit): - self.yupper_limit_line_edit.setText(str(limit)) - - def set_ylabel(self, label): - self.ylabel_line_edit.setText(label) - - def set_yscale(self, scale): - self.yscale_combo_box.setCurrentText(scale.title()) - - def error_occurred(self, exception): - QMessageBox.critical(self, 'Error', exception) + def get_axis(self): + return self.axis_button_group.checkedButton().text()