Skip to content

Commit

Permalink
Fix log plots (#121)
Browse files Browse the repository at this point in the history
* Make menu plots respect logarithmic_intensity and display_title configuration

* Add tests
  • Loading branch information
rosswhitfield committed Nov 29, 2023
1 parent 1cc7cbe commit 234aad7
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/shiver/views/plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@


@manage_workspace_names
def do_1d_plot(workspaces, display_name, intensity_limits=None, log_scale=False):
def do_1d_plot(workspaces, display_name, intensity_limits=None, log_scale=False, errors=False, overplot=False):
"""Create an 1D plot for the provided workspace"""
fig = plot_md_ws_from_names(workspaces, False, False)
fig = plot_md_ws_from_names(workspaces, errors, overplot)
min_limit = intensity_limits["min"] if intensity_limits is not None and "min" in intensity_limits else None
max_limit = intensity_limits["max"] if intensity_limits is not None and "max" in intensity_limits else None

Expand Down
44 changes: 31 additions & 13 deletions src/shiver/views/workspace_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
from shiver.presenters.polarized import PolarizedPresenter
from shiver.models.polarized import PolarizedModel

from shiver.configuration import get_data

from .invalid_styles import INVALID_QLISTWIDGET
from .plots import do_colorfill_plot, do_slice_viewer, plot_md_ws_from_names
from .plots import do_colorfill_plot, do_slice_viewer, do_1d_plot
from .workspace_icons import IconLegend, get_icon

Frame = Enum("Frame", {"None": 1000, "QSample": 1001, "QLab": 1002, "HKL": 1003})
Expand Down Expand Up @@ -654,6 +656,10 @@ def __init__(self, parent=None):
self.save_script_callback = None
self.plot_callback = None

def get_display_name_and_intensity_limits(self, selected_ws, ndims):
"""get the display name and intensity limits"""
return self.parent().parent().get_plot_data(selected_ws, ndims)

def contextMenu(self, pos): # pylint: disable=invalid-name
"""right-click event handler"""
selected_ws = self.itemAt(pos)
Expand All @@ -665,30 +671,42 @@ def contextMenu(self, pos): # pylint: disable=invalid-name

menu = QMenu(self)

log_scale = get_data("main_tab.plot", "logarithmic_intensity")
display_name, intensity_limits = self.get_display_name_and_intensity_limits(selected_ws, ndims)

if ndims == 1:
plot = QAction("Plot 1D")
plot.triggered.connect(partial(self.plot_1d, selected_ws, False, False))

plot.triggered.connect(
partial(self.plot_1d, selected_ws, display_name, intensity_limits, log_scale, False, False)
)
menu.addAction(plot)

overplot = QAction("Overplot 1D")
overplot.triggered.connect(partial(self.plot_1d, selected_ws, False, True))
overplot.triggered.connect(
partial(self.plot_1d, selected_ws, display_name, intensity_limits, log_scale, False, True)
)
menu.addAction(overplot)

plot_err = QAction("Plot 1D with errors")
plot_err.triggered.connect(partial(self.plot_1d, selected_ws, True, False))
plot_err.triggered.connect(
partial(self.plot_1d, selected_ws, display_name, intensity_limits, log_scale, True, False)
)
menu.addAction(plot_err)

overplot_err = QAction("Overplot 1D with errors")
overplot_err.triggered.connect(partial(self.plot_1d, selected_ws, True, True))
overplot_err.triggered.connect(
partial(self.plot_1d, selected_ws, display_name, intensity_limits, log_scale, True, True)
)
menu.addAction(overplot_err)
elif ndims == 2:
colorfill = QAction("Plot colorfill")
colorfill.triggered.connect(partial(self.plot_2d, selected_ws))
colorfill.triggered.connect(partial(self.plot_2d, selected_ws, display_name, intensity_limits, log_scale))
menu.addAction(colorfill)

if ndims > 1:
sliceviewer = QAction("Show Slice Viewer")
sliceviewer.triggered.connect(partial(self.plot_slice_viewer, selected_ws))
sliceviewer.triggered.connect(partial(self.plot_slice_viewer, selected_ws, intensity_limits, log_scale))
menu.addAction(sliceviewer)

menu.addSeparator()
Expand Down Expand Up @@ -720,17 +738,17 @@ def add_ws(self, name, ws_type, frame, ndims):
if ws_type == self.ws_type and name != "None":
self.addItem(QListWidgetItem(name, type=ndims))

def plot_1d(self, name, errors, overplot):
def plot_1d(self, name, display_name, intensity_limits, log_scale, errors, overplot):
"""method to do 1D plots"""
plot_md_ws_from_names([name], errors, overplot)
do_1d_plot([name], display_name, intensity_limits, log_scale, errors, overplot)

def plot_2d(self, name):
def plot_2d(self, name, display_name, intensity_limits, log_scale):
"""method to do 2D plots"""
do_colorfill_plot([name])
do_colorfill_plot([name], display_name, intensity_limits, log_scale)

def plot_slice_viewer(self, name):
def plot_slice_viewer(self, name, intensity_limits, log_scale):
"""method to open sliceviewer"""
do_slice_viewer([name], self)
do_slice_viewer([name], self, intensity_limits, log_scale)

def save_script(self, name):
"""method to handle the saving of script"""
Expand Down
66 changes: 64 additions & 2 deletions tests/views/test_mdh_workspaces.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""UI tests for the MDH list tables"""
from functools import partial
import pytest
from qtpy.QtWidgets import QApplication, QMenu, QFileDialog, QLineEdit
from qtpy.QtCore import Qt, QTimer
from qtpy.QtGui import QContextMenuEvent
Expand All @@ -24,6 +25,11 @@ def test_mdh_workspaces_menu(qtbot):
qtbot.addWidget(mdh_table)
mdh_table.show()

def mock_call(ws_name, ndims):
return f"{ws_name}: {ndims}", {"min": None, "max": None}

mdh_table.get_display_name_and_intensity_limits = mock_call

mdh_table.add_ws("mdh1", "mdh", "HKL", 1)
mdh_table.add_ws("mdh2", "mdh", "HKL", 2)
mdh_table.add_ws("mdh3", "mdh", "HKL", 3)
Expand Down Expand Up @@ -122,9 +128,23 @@ def delete_callback(name):
qtbot.wait(100)


def test_mdh_plotting_1d(qtbot):
@pytest.mark.parametrize(
"user_conf_file",
[
"""
[main_tab.plot]
display_title = name_only
logarithmic_intensity = True
"""
],
indirect=True,
)
def test_mdh_plotting_1d(qtbot, user_conf_file, monkeypatch):
"""Tests the 1D plotting"""

# mock get_oncat_url, client_id and use_notes info
monkeypatch.setattr("shiver.configuration.CONFIG_PATH_FILE", user_conf_file)

# Create workspaces in mantid, needed for plots
CreateMDHistoWorkspace(
Dimensionality=4,
Expand All @@ -139,6 +159,12 @@ def test_mdh_plotting_1d(qtbot):
)

mdh_table = MDHList()

def mock_call(ws_name, ndims):
return f"{ws_name}: {ndims}", {"min": None, "max": None}

mdh_table.get_display_name_and_intensity_limits = mock_call

qtbot.addWidget(mdh_table)
mdh_table.show()

Expand All @@ -162,6 +188,8 @@ def test_mdh_plotting_1d(qtbot):

assert len(figure.axes) == 1
assert len(figure.axes[0].lines) == 1
assert figure.axes[0].get_yscale() == "log"
assert figure.axes[0].get_title() == "Plot 1D: 1"

# Select "Overplot 1D"
QTimer.singleShot(100, partial(handle_menu, qtbot, mdh_table, 2))
Expand All @@ -172,6 +200,8 @@ def test_mdh_plotting_1d(qtbot):
qtbot.wait(500)

assert len(figure.axes[0].lines) == 2
assert figure.axes[0].get_yscale() == "log"
assert figure.axes[0].get_title() == "Plot 1D: 1"

qtbot.wait(100)

Expand All @@ -188,6 +218,8 @@ def test_mdh_plotting_1d(qtbot):

assert len(figure2.axes) == 1
assert len(figure2.axes[0].lines) == 1
assert figure.axes[0].get_yscale() == "log"
assert figure.axes[0].get_title() == "Plot 1D: 1"

# Select "Overplot 1D with Errors"
QTimer.singleShot(100, partial(handle_menu, qtbot, mdh_table, 4))
Expand All @@ -200,8 +232,22 @@ def test_mdh_plotting_1d(qtbot):
assert len(figure2.axes[0].lines) == 2


def test_mdh_plotting_2d(qtbot):
@pytest.mark.parametrize(
"user_conf_file",
[
"""
[main_tab.plot]
display_title = name_only
logarithmic_intensity = True
"""
],
indirect=True,
)
def test_mdh_plotting_2d(qtbot, user_conf_file, monkeypatch):
"""Tests the 2D plotting, colorfill plot or sliceviewer"""

# mock get_oncat_url, client_id and use_notes info
monkeypatch.setattr("shiver.configuration.CONFIG_PATH_FILE", user_conf_file)
CreateMDHistoWorkspace(
Dimensionality=4,
Extents="-10,10,-1,1,-1,1,-2,2",
Expand All @@ -215,6 +261,12 @@ def test_mdh_plotting_2d(qtbot):
)

mdh_table = MDHList()

def mock_call(ws_name, ndims):
return f"{ws_name}: {ndims}", {"min": None, "max": None}

mdh_table.get_display_name_and_intensity_limits = mock_call

qtbot.addWidget(mdh_table)
mdh_table.show()

Expand All @@ -238,6 +290,8 @@ def test_mdh_plotting_2d(qtbot):
figure = plt.gcf()
assert len(figure.axes) == 2 # pcolormesh and colorbar
assert figure.axes[0].pcolormesh
assert figure.axes[0].get_title() == "Plot 2D: 2"
assert figure.axes[1].get_yscale() == "log"

# sliceviewer
QTimer.singleShot(100, partial(handle_menu, qtbot, mdh_table, 2))
Expand All @@ -251,6 +305,8 @@ def test_mdh_plotting_2d(qtbot):
slice_viewer = mdh_table.findChild(SliceViewerView)
assert slice_viewer is not None
assert slice_viewer.isVisible()
assert slice_viewer.data_view.colorbar.norm.currentText() == "Log"

slice_viewer.close()


Expand All @@ -270,6 +326,12 @@ def test_mdh_plotting_3d(qtbot):
)

mdh_table = MDHList()

def mock_call(ws_name, ndims):
return f"{ws_name}: {ndims}", {"min": None, "max": None}

mdh_table.get_display_name_and_intensity_limits = mock_call

qtbot.addWidget(mdh_table)
mdh_table.show()

Expand Down

0 comments on commit 234aad7

Please sign in to comment.