Skip to content
Snippets Groups Projects
Commit 264760d8 authored by Phil Colebrooke's avatar Phil Colebrooke
Browse files

Re #28464 add functionality for switching between axes and z-axis

parent c8e81acb
No related merge requests found
......@@ -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)
......@@ -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>
......@@ -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()
......@@ -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()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment