Skip to content

Commit

Permalink
Merge pull request #76 from PaNOSC-ViNYL/show_instrument_fix
Browse files Browse the repository at this point in the history
Mcdisplay issue and plotting fix
  • Loading branch information
mads-bertelsen authored Dec 1, 2023
2 parents 0e64e0e + c3485c9 commit 65aa945
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 33 deletions.
2 changes: 1 addition & 1 deletion mcstasscript/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.0.63"
__version__ = "0.0.64"
13 changes: 3 additions & 10 deletions mcstasscript/helper/plot_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,10 @@ def _handle_kwargs(data_list, **kwargs):
"""
Handle kwargs when list of McStasData objects given.
Returns figsize and data_list
Returns data_list
figsize has a default value, but can be changed with keyword argument
data_list is turned into a list if it isn't already
event data is removed as it can't be plotted directly
Any kwargs can be given as a list, in that case apply them to given
to the corresponding index.
Expand Down Expand Up @@ -301,11 +301,4 @@ def _handle_kwargs(data_list, **kwargs):
# Remove option from kwargs
del kwargs[option]

if "figsize" in kwargs:
figsize = kwargs["figsize"]
if isinstance(figsize, list):
figsize = (figsize[0], figsize[1])
else:
figsize = (13, 7)

return figsize, data_list
return data_list
12 changes: 9 additions & 3 deletions mcstasscript/interface/instr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2639,14 +2639,20 @@ def show_instrument(self, format="webgl", width=800, height=450, new_tab=False):
+ "="
+ str(val)) # parameter value

package_path = self._run_settings["package_path"]
bin_path = os.path.join(package_path, "bin", "")

if format == "webgl":
executable = "mcdisplay-webgl"
elif format == "window":
executable = "mcdisplay"

# Platform dependent, check both package_path and bin
executable_path = self._run_settings["executable_path"]
bin_path = os.path.join(executable_path, executable)

if not os.path.isfile(bin_path):
# Take bin in package path into account
package_path = self._run_settings["package_path"]
bin_path = os.path.join(package_path, "bin", "")

dir_name_original = self.name + "_mcdisplay"
dir_name = dir_name_original
index = 0
Expand Down
55 changes: 47 additions & 8 deletions mcstasscript/interface/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,17 @@ def make_plot(data_list, **kwargs):
subplot.
"""

figsize, data_list = _handle_kwargs(data_list, **kwargs)
data_list = _handle_kwargs(data_list, **kwargs)

if "figsize" in kwargs:
figsize = kwargs["figsize"]
if isinstance(figsize, list):
figsize = (figsize[0], figsize[1])
else:
figsize = (13, 7)

for data in data_list:
fig, ax0 = plt.subplots(figsize=figsize)
fig, ax0 = plt.subplots(figsize=figsize, tight_layout=True)
_plot_fig_ax(data, fig, ax0, **kwargs)

if "filename" in kwargs:
Expand All @@ -45,14 +52,39 @@ def make_sub_plot(data_list, **kwargs):
subplot.
"""

figsize, data_list = _handle_kwargs(data_list, **kwargs)
data_list = _handle_kwargs(data_list, **kwargs)

number_of_plots = len(data_list)

# Find reasonable grid size for the number of plots
dim2 = math.ceil(math.sqrt(number_of_plots))
dim1 = math.ceil(number_of_plots / dim2)
special_cases = {
1: (1, 1),
4: (2, 2),
}

if number_of_plots in special_cases:
dim1 = special_cases[number_of_plots][0]
dim2 = special_cases[number_of_plots][0]
else:
if number_of_plots < 3:
dim2 = number_of_plots
dim1 = 1
else:
dim2 = 3
dim1 = math.ceil(number_of_plots / dim2)

if "figsize" in kwargs:
figsize = kwargs["figsize"]
if isinstance(figsize, list):
figsize = (figsize[0], figsize[1])
else:
# Adjust figure size after number of plots
figsize = (1 + dim2*4, 0.5 + 3.0*dim1)
if dim1 == 1 and dim2 == 1:
# Single plots can be a bit larger
figsize = (7, 5)

fig, axs = plt.subplots(dim1, dim2, figsize=figsize)
fig, axs = plt.subplots(dim1, dim2, figsize=figsize, tight_layout=True)
axs = np.array(axs)
ax = axs.reshape(-1)

Expand Down Expand Up @@ -88,7 +120,14 @@ def make_animation(data_list, **kwargs):
"""

figsize, data_list = _handle_kwargs(data_list, **kwargs)
data_list = _handle_kwargs(data_list, **kwargs)

if "figsize" in kwargs:
figsize = kwargs["figsize"]
if isinstance(figsize, list):
figsize = (figsize[0], figsize[1])
else:
figsize = (13, 7)

if "fps" in kwargs:
period_in_ms = 1000 / kwargs["fps"]
Expand Down Expand Up @@ -137,7 +176,7 @@ def make_animation(data_list, **kwargs):
kwargs["fixed_minimum_value"] = minimum_value
kwargs["fixed_maximum_value"] = maximum_value

fig, ax0 = plt.subplots(figsize=figsize)
fig, ax0 = plt.subplots(figsize=figsize, tight_layout=True)
im = _plot_fig_ax(data_list[0], fig, ax0, **kwargs)

def animate_2D(index):
Expand Down
Empty file.
3 changes: 2 additions & 1 deletion mcstasscript/tests/test_Instr.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def setup_instr_with_path():
with WorkInTestDir() as handler:
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
dummy_path = os.path.join(THIS_DIR, "dummy_mcstas")
instrument = McStas_instr("test_instrument", package_path=dummy_path)
instrument = McStas_instr("test_instrument",
package_path=dummy_path, executable_path=dummy_path)

return instrument

Expand Down
46 changes: 36 additions & 10 deletions mcstasscript/tests/test_Plotter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import unittest
import unittest.mock

import matplotlib
matplotlib.use('Agg')

import numpy as np
import matplotlib.pyplot as plt
Expand All @@ -8,6 +12,7 @@
from mcstasscript.interface.plotter import _find_min_max_I
from mcstasscript.interface.plotter import _handle_kwargs
from mcstasscript.interface.plotter import _plot_fig_ax
from mcstasscript.interface.plotter import make_plot, make_sub_plot, make_animation


def get_dummy_MetaDataBinned_1d():
Expand Down Expand Up @@ -537,34 +542,55 @@ def test_handle_kwargs_bottom_lim(self):
self.assertEqual(dummy_data1.plot_options.custom_ylim_bottom, True)
self.assertEqual(dummy_data2.plot_options.custom_ylim_bottom, True)

def test_handle_kwargs_figsize_default(self):
@unittest.mock.patch("matplotlib.pyplot.subplots")
def test_handle_kwargs_figsize_default(self, mock_subplots):
"""
Tests handle_kwargs delivers default figsize
"""

# Ensures subplots returns a tuple with two objects
mock_fig = unittest.mock.MagicMock()
mock_ax = unittest.mock.MagicMock()
mock_subplots.return_value = (mock_fig, mock_ax)

# Actual test
dummy_data = get_dummy_McStasDataBinned_2d()
retrived_figsize, data_list = _handle_kwargs(dummy_data)
self.assertEqual(retrived_figsize, (13, 7))
make_plot(dummy_data)
mock_subplots.assert_called_with(figsize=(13, 7), tight_layout=True)

def test_handle_kwargs_figsize_tuple(self):
@unittest.mock.patch("matplotlib.pyplot.subplots")
def test_handle_kwargs_figsize_tuple(self, mock_subplots):
"""
Tests handle_kwargs with figsize keyword argument, here
using tuple as input
"""

# Ensures subplots returns a tuple with two objects
mock_fig = unittest.mock.MagicMock()
mock_ax = unittest.mock.MagicMock()
mock_subplots.return_value = (mock_fig, mock_ax)

# Actual test
dummy_data = get_dummy_McStasDataBinned_2d()
found_figsize, data_list = _handle_kwargs(dummy_data, figsize=(5, 9))
self.assertEqual(found_figsize, (5, 9))
make_plot(dummy_data, figsize=(5, 9))
mock_subplots.assert_called_with(figsize=(5, 9), tight_layout=True)

def test_handle_kwargs_figsize_list(self):
@unittest.mock.patch("matplotlib.pyplot.subplots")
def test_handle_kwargs_figsize_list(self, mock_subplots):
"""
Tests handle_kwargs with figsize keyword argument, here
using tuple as input
"""

# Ensures subplots returns a tuple with two objects
mock_fig = unittest.mock.MagicMock()
mock_ax = unittest.mock.MagicMock()
mock_subplots.return_value = (mock_fig, mock_ax)

# Actual test
dummy_data = get_dummy_McStasDataBinned_2d()
found_figsize, data_list = _handle_kwargs(dummy_data, figsize=[5, 9])
self.assertEqual(found_figsize, (5, 9))
make_plot(dummy_data, figsize=[5, 9])
mock_subplots.assert_called_with(figsize=(5, 9), tight_layout=True)

def test_handle_kwargs_single_element_to_list(self):
"""
Expand All @@ -574,7 +600,7 @@ def test_handle_kwargs_single_element_to_list(self):

dummy_data = get_dummy_McStasDataBinned_2d()
self.assertFalse(isinstance(dummy_data, list))
figsize, data_list = _handle_kwargs(dummy_data)
data_list = _handle_kwargs(dummy_data)
self.assertTrue(isinstance(data_list, list))

def test_plot_function_1D_normal(self):
Expand Down
3 changes: 3 additions & 0 deletions mcstasscript/tests/test_plot_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import io
import numpy as np

import matplotlib
matplotlib.use('Agg') # Set the backend to Agg

from mcstasscript.jb_interface.plot_interface import PlotInterface
from mcstasscript.jb_interface.plot_interface import LogCheckbox
from mcstasscript.jb_interface.plot_interface import ColormapDropdown
Expand Down
3 changes: 3 additions & 0 deletions mcstasscript/tests/test_simulation_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import unittest.mock
import ipywidgets as widgets

import matplotlib
matplotlib.use('Agg') # Set the backend to Agg

from mcstasscript.jb_interface.simulation_interface import SimInterface
from mcstasscript.jb_interface.simulation_interface import ParameterWidget
from mcstasscript.jb_interface.widget_helpers import parameter_has_default
Expand Down

0 comments on commit 65aa945

Please sign in to comment.