pymodaq 4.1.5__py3-none-any.whl → 4.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +23 -4
- pymodaq/control_modules/daq_move.py +32 -73
- pymodaq/control_modules/daq_viewer.py +73 -98
- pymodaq/control_modules/daq_viewer_ui.py +2 -1
- pymodaq/control_modules/move_utility_classes.py +17 -7
- pymodaq/control_modules/utils.py +153 -5
- pymodaq/control_modules/viewer_utility_classes.py +31 -20
- pymodaq/dashboard.py +23 -5
- pymodaq/examples/tcp_client.py +97 -0
- pymodaq/extensions/__init__.py +4 -0
- pymodaq/extensions/bayesian/__init__.py +2 -0
- pymodaq/extensions/bayesian/bayesian_optimisation.py +673 -0
- pymodaq/extensions/bayesian/utils.py +403 -0
- pymodaq/extensions/daq_scan.py +4 -4
- pymodaq/extensions/daq_scan_ui.py +2 -1
- pymodaq/extensions/pid/pid_controller.py +12 -7
- pymodaq/extensions/pid/utils.py +9 -26
- pymodaq/extensions/utils.py +3 -0
- pymodaq/post_treatment/load_and_plot.py +42 -19
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/config_template.toml +9 -24
- pymodaq/resources/setup_plugin.py +1 -1
- pymodaq/utils/config.py +103 -5
- pymodaq/utils/daq_utils.py +35 -134
- pymodaq/utils/data.py +614 -95
- pymodaq/utils/enums.py +17 -1
- pymodaq/utils/factory.py +2 -2
- pymodaq/utils/gui_utils/custom_app.py +5 -2
- pymodaq/utils/gui_utils/dock.py +33 -4
- pymodaq/utils/gui_utils/utils.py +14 -1
- pymodaq/utils/h5modules/backends.py +9 -1
- pymodaq/utils/h5modules/data_saving.py +254 -57
- pymodaq/utils/h5modules/saving.py +1 -0
- pymodaq/utils/leco/__init__.py +25 -0
- pymodaq/utils/leco/daq_move_LECODirector.py +172 -0
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +170 -0
- pymodaq/utils/leco/desktop.ini +2 -0
- pymodaq/utils/leco/director_utils.py +58 -0
- pymodaq/utils/leco/leco_director.py +88 -0
- pymodaq/utils/leco/pymodaq_listener.py +279 -0
- pymodaq/utils/leco/utils.py +41 -0
- pymodaq/utils/managers/action_manager.py +20 -6
- pymodaq/utils/managers/parameter_manager.py +6 -4
- pymodaq/utils/managers/roi_manager.py +63 -54
- pymodaq/utils/math_utils.py +1 -1
- pymodaq/utils/plotting/data_viewers/__init__.py +3 -1
- pymodaq/utils/plotting/data_viewers/base.py +286 -0
- pymodaq/utils/plotting/data_viewers/viewer.py +29 -202
- pymodaq/utils/plotting/data_viewers/viewer0D.py +94 -47
- pymodaq/utils/plotting/data_viewers/viewer1D.py +341 -174
- pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +1 -1
- pymodaq/utils/plotting/data_viewers/viewer2D.py +271 -181
- pymodaq/utils/plotting/data_viewers/viewerND.py +26 -22
- pymodaq/utils/plotting/items/crosshair.py +3 -3
- pymodaq/utils/plotting/items/image.py +2 -1
- pymodaq/utils/plotting/plotter/plotter.py +94 -0
- pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
- pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +134 -0
- pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +78 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +1 -1
- pymodaq/utils/plotting/utils/filter.py +194 -147
- pymodaq/utils/plotting/utils/lineout.py +13 -11
- pymodaq/utils/plotting/utils/plot_utils.py +89 -12
- pymodaq/utils/scanner/__init__.py +0 -3
- pymodaq/utils/scanner/scan_config.py +1 -9
- pymodaq/utils/scanner/scan_factory.py +10 -36
- pymodaq/utils/scanner/scanner.py +3 -2
- pymodaq/utils/scanner/scanners/_1d_scanners.py +7 -5
- pymodaq/utils/scanner/scanners/_2d_scanners.py +36 -49
- pymodaq/utils/scanner/scanners/sequential.py +10 -4
- pymodaq/utils/scanner/scanners/tabular.py +10 -5
- pymodaq/utils/slicing.py +1 -1
- pymodaq/utils/tcp_ip/serializer.py +38 -5
- pymodaq/utils/tcp_ip/tcp_server_client.py +25 -17
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/METADATA +4 -2
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/RECORD +79 -63
- pymodaq/resources/config_scan_template.toml +0 -42
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/WHEEL +0 -0
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/entry_points.txt +0 -0
- {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -178,21 +178,21 @@ class UniformDataDisplayer(BaseDataDisplayer):
|
|
|
178
178
|
)
|
|
179
179
|
if len(sig_axis_limits) == 1:
|
|
180
180
|
self._viewer1D.roi.setPos((float(np.mean(sig_axis_limits[0]) -
|
|
181
|
-
np.abs(np.diff(sig_axis_limits[0])) / 3),
|
|
181
|
+
np.abs(np.diff(sig_axis_limits[0]))[0] / 3),
|
|
182
182
|
float(np.mean(sig_axis_limits[0]) +
|
|
183
|
-
np.abs(np.diff(sig_axis_limits[0])) / 3))
|
|
183
|
+
np.abs(np.diff(sig_axis_limits[0]))[0] / 3))
|
|
184
184
|
)
|
|
185
185
|
if len(sig_axis_limits) == 2:
|
|
186
186
|
scaled_axes = np.array(self._viewer2D.view.unscale_axis(np.array(sig_axis_limits[1]),
|
|
187
187
|
np.array(sig_axis_limits[0])))
|
|
188
188
|
|
|
189
189
|
self._viewer2D.roi.setSize(
|
|
190
|
-
float(np.diff(scaled_axes[0])) / 3,
|
|
191
|
-
float(np.diff(scaled_axes[1])) / 3)
|
|
190
|
+
float(np.diff(scaled_axes[0])[0]) / 3,
|
|
191
|
+
float(np.diff(scaled_axes[1])[0]) / 3)
|
|
192
192
|
|
|
193
193
|
self._viewer2D.roi.setPos(
|
|
194
|
-
float(np.mean(scaled_axes[0])) - float(np.diff(scaled_axes[0])) / 6,
|
|
195
|
-
float(np.mean(scaled_axes[1])) - float(np.diff(scaled_axes[1])) / 6)
|
|
194
|
+
float(np.mean(scaled_axes[0])) - float(np.diff(scaled_axes[0])[0]) / 6,
|
|
195
|
+
float(np.mean(scaled_axes[1])) - float(np.diff(scaled_axes[1])[0]) / 6)
|
|
196
196
|
|
|
197
197
|
def updated_nav_integration(self):
|
|
198
198
|
""" Means the ROI select of the 2D viewer has been moved """
|
|
@@ -286,7 +286,7 @@ class UniformDataDisplayer(BaseDataDisplayer):
|
|
|
286
286
|
try:
|
|
287
287
|
navigator_data = None
|
|
288
288
|
if len(data.axes_manager.sig_shape) == 0: # signal data is 0D
|
|
289
|
-
navigator_data = data
|
|
289
|
+
navigator_data = data.deepcopy()
|
|
290
290
|
|
|
291
291
|
elif len(data.axes_manager.sig_shape) == 1: # signal data is 1D
|
|
292
292
|
indx, indy = data.get_axis_from_index(data.sig_indexes[0])[0].find_indexes((x, y))
|
|
@@ -660,25 +660,29 @@ class ViewerND(ParameterManager, ActionManager, ViewerBase):
|
|
|
660
660
|
axes=[Axis(data=z, index=0, label='z_axis', units='zunits')])
|
|
661
661
|
self._show_data(dataraw, force_update=True)
|
|
662
662
|
|
|
663
|
-
def update_widget_visibility(self, data: DataRaw = None
|
|
663
|
+
def update_widget_visibility(self, data: DataRaw = None,
|
|
664
|
+
nav_indexes:Tuple[int] = None):
|
|
664
665
|
if data is None:
|
|
665
666
|
data = self._data
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
self.
|
|
669
|
-
self.viewer1D.
|
|
670
|
-
self.viewer2D.
|
|
671
|
-
self.
|
|
672
|
-
|
|
667
|
+
if nav_indexes is None:
|
|
668
|
+
nav_indexes = data.nav_indexes
|
|
669
|
+
self.viewer0D.setVisible(len(data.shape) - len(nav_indexes) == 0)
|
|
670
|
+
self.viewer1D.setVisible(len(data.shape) - len(nav_indexes) == 1)
|
|
671
|
+
self.viewer2D.setVisible(len(data.shape) - len(nav_indexes) == 2)
|
|
672
|
+
self.viewer1D.roi.setVisible(len(nav_indexes) != 0)
|
|
673
|
+
self.viewer2D.roi.setVisible(len(nav_indexes) != 0)
|
|
674
|
+
self._dock_navigation.setVisible(len(nav_indexes) != 0)
|
|
675
|
+
#nav_axes = data.get_nav_axes()
|
|
673
676
|
|
|
674
677
|
if data.distribution.name == 'uniform':
|
|
675
|
-
self.navigator1D.setVisible(len(
|
|
676
|
-
self.navigator2D.setVisible(len(
|
|
677
|
-
self.axes_viewer.setVisible(len(
|
|
678
|
+
self.navigator1D.setVisible(len(nav_indexes) == 1)
|
|
679
|
+
self.navigator2D.setVisible(len(nav_indexes) == 2)
|
|
680
|
+
self.axes_viewer.setVisible(len(nav_indexes) > 2)
|
|
678
681
|
else:
|
|
679
|
-
self.navigator2D.setVisible(len(
|
|
680
|
-
self.navigator1D.setVisible(len(
|
|
681
|
-
len(
|
|
682
|
+
self.navigator2D.setVisible(len(nav_indexes) == 2 and self.data_displayer.triangulation)
|
|
683
|
+
self.navigator1D.setVisible(len(nav_indexes) == 1 or len(nav_indexes) > 2 or
|
|
684
|
+
len(nav_indexes) == 2 and
|
|
685
|
+
not self.data_displayer.triangulation)
|
|
682
686
|
|
|
683
687
|
def update_filters(self, processor: DataProcessorFactory):
|
|
684
688
|
self.get_action('filters').clear()
|
|
@@ -705,7 +709,7 @@ class ViewerND(ParameterManager, ActionManager, ViewerBase):
|
|
|
705
709
|
def reshape_data(self):
|
|
706
710
|
_nav_indexes = [int(index) for index in
|
|
707
711
|
self.settings.child('data_shape_settings', 'navigator_axes').value()['selected']]
|
|
708
|
-
self.update_widget_visibility()
|
|
712
|
+
self.update_widget_visibility(nav_indexes=_nav_indexes)
|
|
709
713
|
self.data_displayer.update_nav_indexes(_nav_indexes)
|
|
710
714
|
|
|
711
715
|
def connect_things(self):
|
|
@@ -10,7 +10,7 @@ class Crosshair(pg.GraphicsObject):
|
|
|
10
10
|
crosshair_dragged = Signal(float, float, name='crosshair_dragged')
|
|
11
11
|
# signal used to pass crosshair position to other methods
|
|
12
12
|
|
|
13
|
-
def __init__(self, plotitem, orientation='both'):
|
|
13
|
+
def __init__(self, plotitem, orientation='both', pen=None):
|
|
14
14
|
super().__init__()
|
|
15
15
|
|
|
16
16
|
if hasattr(plotitem, 'plotitem'):
|
|
@@ -30,8 +30,8 @@ class Crosshair(pg.GraphicsObject):
|
|
|
30
30
|
self.vline_visible = False
|
|
31
31
|
self.hline_visible = True
|
|
32
32
|
|
|
33
|
-
self.vLine = pg.InfiniteLine(angle=90, movable=True)
|
|
34
|
-
self.hLine = pg.InfiniteLine(angle=0, movable=True)
|
|
33
|
+
self.vLine = pg.InfiniteLine(angle=90, movable=True, pen=pen)
|
|
34
|
+
self.hLine = pg.InfiniteLine(angle=0, movable=True, pen=pen)
|
|
35
35
|
|
|
36
36
|
self.plotitem.addItem(self.vLine, ignoreBounds=True)
|
|
37
37
|
self.plotitem.addItem(self.hLine, ignoreBounds=True)
|
|
@@ -8,12 +8,13 @@ from qtpy import QtCore, QtGui
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class PymodaqImage(pg.ImageItem):
|
|
11
|
-
def __init__(self, image=None, **kargs):
|
|
11
|
+
def __init__(self, image=None, pen='r', **kargs):
|
|
12
12
|
super().__init__(image, **kargs)
|
|
13
13
|
self.flipud = False
|
|
14
14
|
self.fliplr = False
|
|
15
15
|
self.rotate90 = False
|
|
16
16
|
self.rescale = None
|
|
17
|
+
self.opts = {'pen': pen}
|
|
17
18
|
|
|
18
19
|
def get_val_at(self, xy):
|
|
19
20
|
"""
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Standard imports
|
|
2
|
+
import typing
|
|
3
|
+
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from importlib import import_module
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Callable, List, Union
|
|
7
|
+
|
|
8
|
+
# 3rd party imports
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
# project imports
|
|
12
|
+
from pymodaq.utils.abstract import abstract_attribute
|
|
13
|
+
from pymodaq.utils.logger import set_logger, get_module_name
|
|
14
|
+
|
|
15
|
+
from pymodaq.utils.factory import ObjectFactory
|
|
16
|
+
|
|
17
|
+
if typing.TYPE_CHECKING:
|
|
18
|
+
from pymodaq.utils.data import DataWithAxes, DataDim
|
|
19
|
+
from pymodaq.utils.plotting.data_viewers import Viewer0D, Viewer1D, Viewer2D, ViewerND
|
|
20
|
+
|
|
21
|
+
logger = set_logger(get_module_name(__file__))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def register_plotter(parent_module_name: str = 'pymodaq.utils.plotting.plotter'):
|
|
25
|
+
plotters = []
|
|
26
|
+
try:
|
|
27
|
+
plotter_module = import_module(f'{parent_module_name}.plotters')
|
|
28
|
+
|
|
29
|
+
plotter_path = Path(plotter_module.__path__[0])
|
|
30
|
+
|
|
31
|
+
for file in plotter_path.iterdir():
|
|
32
|
+
if file.is_file() and 'py' in file.suffix and file.stem != '__init__':
|
|
33
|
+
try:
|
|
34
|
+
plotters.append(import_module(f'.{file.stem}', plotter_module.__name__))
|
|
35
|
+
except ModuleNotFoundError:
|
|
36
|
+
pass
|
|
37
|
+
except ModuleNotFoundError:
|
|
38
|
+
pass
|
|
39
|
+
finally:
|
|
40
|
+
return plotters
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class PlotterBase(metaclass=ABCMeta):
|
|
44
|
+
"""Base class for a plotter. """
|
|
45
|
+
|
|
46
|
+
backend: str = abstract_attribute()
|
|
47
|
+
def __init__(self):
|
|
48
|
+
"""Abstract Exporter Constructor"""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def plot(self, data, *args, **kwargs) -> None:
|
|
53
|
+
"""Abstract method to plot data object with a given backend"""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class PlotterFactory(ObjectFactory):
|
|
58
|
+
"""Factory class registering and storing interactive plotter"""
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def register(cls) -> Callable:
|
|
62
|
+
""" To be used as a decorator
|
|
63
|
+
|
|
64
|
+
Register in the class registry a new plotter class using its 2 identifiers: backend and
|
|
65
|
+
data_dim
|
|
66
|
+
"""
|
|
67
|
+
def inner_wrapper(wrapped_class: PlotterBase) -> Callable:
|
|
68
|
+
if cls.__name__ not in cls._builders:
|
|
69
|
+
cls._builders[cls.__name__] = {}
|
|
70
|
+
key = wrapped_class.backend
|
|
71
|
+
|
|
72
|
+
if key not in cls._builders[cls.__name__]:
|
|
73
|
+
cls._builders[cls.__name__][key] = wrapped_class
|
|
74
|
+
else:
|
|
75
|
+
logger.warning(f'The {cls.__name__}/{key} builder is already registered.'
|
|
76
|
+
f' Replacing it')
|
|
77
|
+
return wrapped_class
|
|
78
|
+
|
|
79
|
+
return inner_wrapper
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def create(cls, key, **kwargs) -> PlotterBase:
|
|
83
|
+
builder = cls._builders[cls.__name__].get(key)
|
|
84
|
+
if not builder:
|
|
85
|
+
raise ValueError(key)
|
|
86
|
+
return builder(**kwargs)
|
|
87
|
+
|
|
88
|
+
def get(self, backend: str, **kwargs):
|
|
89
|
+
return self.create(backend, **kwargs)
|
|
90
|
+
|
|
91
|
+
def backends(self) -> List[str]:
|
|
92
|
+
"""Returns the list of plotter backends, main identifier of a given plotter"""
|
|
93
|
+
return sorted(list(self.builders[self.__class__.__name__].keys()))
|
|
94
|
+
|
|
File without changes
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from typing import List, Tuple, Any, TYPE_CHECKING, Union
|
|
2
|
+
import sys
|
|
3
|
+
import datetime
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from qtpy import QtWidgets
|
|
7
|
+
|
|
8
|
+
from pymodaq.utils.logger import set_logger, get_module_name
|
|
9
|
+
from pymodaq.utils import config as configmod
|
|
10
|
+
from pymodaq.utils.data import DataDim, DataWithAxes, DataToExport
|
|
11
|
+
from pymodaq.utils import daq_utils as utils
|
|
12
|
+
from pymodaq.utils.plotting.plotter.plotter import PlotterBase, PlotterFactory
|
|
13
|
+
|
|
14
|
+
from matplotlib import pyplot as plt
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
logger = set_logger(get_module_name(__file__))
|
|
20
|
+
config = configmod.Config()
|
|
21
|
+
|
|
22
|
+
PLOT_COLORS = utils.plot_colors.copy()
|
|
23
|
+
PLOT_COLORS.remove((255, 255, 255)) # remove white color as plotted on white background
|
|
24
|
+
PLOT_COLORS = [(np.array(color) / 255).tolist() for color in PLOT_COLORS] # translation to matplotlib
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@PlotterFactory.register()
|
|
28
|
+
class Plotter(PlotterBase):
|
|
29
|
+
backend = 'matplotlib'
|
|
30
|
+
|
|
31
|
+
def __init__(self, **_ignored):
|
|
32
|
+
super().__init__()
|
|
33
|
+
self.n_lines = 1
|
|
34
|
+
self.n_columns = 1
|
|
35
|
+
self.ind_line = 0
|
|
36
|
+
self.ind_column = 0
|
|
37
|
+
|
|
38
|
+
def plot(self, data: Union[DataWithAxes, DataToExport], *args, viewer=None,
|
|
39
|
+
**kwargs) -> plt.Figure:
|
|
40
|
+
fig = plt.figure()
|
|
41
|
+
|
|
42
|
+
if isinstance(data, DataWithAxes):
|
|
43
|
+
self.n_columns = len(data) if data.dim.name == 'Data2D' else 1
|
|
44
|
+
self.plot_dwa(data, *args, **kwargs)
|
|
45
|
+
elif isinstance(data, DataToExport):
|
|
46
|
+
self.n_columns = max([len(dwa) if dwa.dim.name == 'Data2D' else 1 for dwa in data])
|
|
47
|
+
self.n_lines = len(data)
|
|
48
|
+
self.plot_dte(data, *args, **kwargs)
|
|
49
|
+
plt.tight_layout()
|
|
50
|
+
fig.suptitle(f'{data.name} taken the {datetime.datetime.fromtimestamp(data.timestamp)}')
|
|
51
|
+
return fig
|
|
52
|
+
|
|
53
|
+
def plot_dwa(self, dwa: DataWithAxes, *args, **kwargs):
|
|
54
|
+
if dwa.dim.name == 'Data1D':
|
|
55
|
+
if len(dwa.axes) == 0:
|
|
56
|
+
dwa.create_missing_axes()
|
|
57
|
+
self.ind_column = 0
|
|
58
|
+
self.plot1D(dwa, *args, **kwargs)
|
|
59
|
+
elif dwa.dim.name == 'Data2D':
|
|
60
|
+
if len(dwa.axes) < 2:
|
|
61
|
+
dwa.create_missing_axes()
|
|
62
|
+
self.plot2D(dwa, *args, **kwargs)
|
|
63
|
+
|
|
64
|
+
def plot_dte(self, dte: DataToExport, *args, **kwargs):
|
|
65
|
+
for ind in range(len(dte)):
|
|
66
|
+
self.ind_line = ind
|
|
67
|
+
self.plot_dwa(dte[ind], *args, **kwargs)
|
|
68
|
+
|
|
69
|
+
def plot1D(self, dwa: DataWithAxes, *args, **kwargs):
|
|
70
|
+
plt.subplot(self.n_lines, self.n_columns,
|
|
71
|
+
(self.n_columns * self.ind_line) + 1)
|
|
72
|
+
for ind_data, data_array in enumerate(dwa):
|
|
73
|
+
plt.plot(dwa.axes[0].get_data(), data_array, *args, color=PLOT_COLORS[ind_data],
|
|
74
|
+
**kwargs)
|
|
75
|
+
if dwa.errors is not None:
|
|
76
|
+
plt.fill_between(dwa.axes[0].get_data(), data_array - dwa.get_error(ind_data),
|
|
77
|
+
data_array + dwa.get_error(ind_data), *args,
|
|
78
|
+
color=PLOT_COLORS[ind_data] + [0.3], **kwargs)
|
|
79
|
+
plt.legend(dwa.labels)
|
|
80
|
+
#plt.title(f'{dwa.name}')
|
|
81
|
+
plt.xlabel(f'{dwa.axes[0].label} ({dwa.axes[0].units})')
|
|
82
|
+
plt.ylabel(dwa.name)
|
|
83
|
+
|
|
84
|
+
def plot2D(self, dwa: DataWithAxes, *args, **kwargs):
|
|
85
|
+
xaxis = dwa.get_axis_from_index(1)[0]
|
|
86
|
+
yaxis = dwa.get_axis_from_index(0)[0]
|
|
87
|
+
|
|
88
|
+
x = xaxis.get_data()
|
|
89
|
+
y = yaxis.get_data()
|
|
90
|
+
for ind_plot, dwa_array in enumerate(dwa):
|
|
91
|
+
self.ind_column = ind_plot
|
|
92
|
+
plt.subplot(self.n_lines, self.n_columns,
|
|
93
|
+
(self.n_columns * self.ind_line) + ind_plot + 1)
|
|
94
|
+
X, Y = np.meshgrid(x, y)
|
|
95
|
+
plt.pcolormesh(X, Y, dwa_array, *args, **kwargs)
|
|
96
|
+
plt.title(f'{dwa.name}/{dwa.labels[ind_plot]}')
|
|
97
|
+
plt.xlabel(f'{xaxis.label} ({xaxis.units})')
|
|
98
|
+
plt.ylabel(f'{yaxis.label} ({yaxis.units})')
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# if __name__ == '__main__':
|
|
102
|
+
# from pymodaq.utils import data as data_mod
|
|
103
|
+
# import numpy as np
|
|
104
|
+
# from pymodaq.utils.math_utils import gauss1D, gauss2D
|
|
105
|
+
# from pymodaq.utils.plotting.plotter.plotter import PlotterFactory
|
|
106
|
+
# plotter_factory = PlotterFactory()
|
|
107
|
+
#
|
|
108
|
+
# x = np.linspace(0, 100, 101)
|
|
109
|
+
# y = np.linspace(0, 100, 101)
|
|
110
|
+
# y1 = gauss2D(x, 50, 20, y, 40, 7)
|
|
111
|
+
#
|
|
112
|
+
#
|
|
113
|
+
# QtWidgets.QApplication.processEvents()
|
|
114
|
+
# dwa = data_mod.DataRaw('mydata', data=[y1, y1, y1],
|
|
115
|
+
# axes=[data_mod.Axis('xaxis', 'x units', data=x, index=0,
|
|
116
|
+
# spread_order=0),
|
|
117
|
+
# data_mod.Axis('yaxis', 'y units', data=y, index=1,
|
|
118
|
+
# spread_order=0)
|
|
119
|
+
# ],
|
|
120
|
+
# labels=['MAG', 'PHASE'],
|
|
121
|
+
# nav_indexes=())
|
|
122
|
+
# dte = dwa.as_dte('mydte')
|
|
123
|
+
# dwa_mean = dwa.mean()
|
|
124
|
+
# dwa_mean.name = 'mean'
|
|
125
|
+
# dwa_mean_2 = dwa.mean(1)
|
|
126
|
+
# dwa_mean_2.name = 'mean2'
|
|
127
|
+
# dte.append(dwa_mean)
|
|
128
|
+
# dte.append(dwa_mean_2)
|
|
129
|
+
#
|
|
130
|
+
# fig = dwa.plot('matplotlib')
|
|
131
|
+
# fig.savefig('myplot.png')
|
|
132
|
+
#
|
|
133
|
+
# fig2 = dte.plot('matplotlib')
|
|
134
|
+
# fig2.savefig('mydte.png')
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from typing import List, Tuple, Any, TYPE_CHECKING, Union
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from qtpy import QtWidgets
|
|
5
|
+
|
|
6
|
+
from pymodaq.utils.logger import set_logger, get_module_name
|
|
7
|
+
from pymodaq.utils import config as configmod
|
|
8
|
+
from pymodaq.utils.gui_utils.utils import start_qapplication
|
|
9
|
+
from pymodaq.utils.plotting.plotter.plotter import PlotterBase, PlotterFactory
|
|
10
|
+
from pymodaq.utils.data import DataWithAxes, DataToExport
|
|
11
|
+
from pymodaq.utils.plotting.data_viewers import (Viewer1D, Viewer2D, ViewerND, ViewerDispatcher,
|
|
12
|
+
Viewer0D, ViewersEnum)
|
|
13
|
+
from pymodaq.utils.plotting.data_viewers.viewer import ViewerBase, viewer_factory
|
|
14
|
+
from pymodaq.utils.gui_utils.dock import DockArea
|
|
15
|
+
|
|
16
|
+
logger = set_logger(get_module_name(__file__))
|
|
17
|
+
config = configmod.Config()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@PlotterFactory.register()
|
|
21
|
+
class Plotter(PlotterBase):
|
|
22
|
+
backend = 'qt'
|
|
23
|
+
|
|
24
|
+
def __init__(self, **_ignored):
|
|
25
|
+
super().__init__()
|
|
26
|
+
|
|
27
|
+
def plot(self, data: Union[DataWithAxes, DataToExport], viewer=None, **kwargs) -> ViewerBase:
|
|
28
|
+
do_exit = False
|
|
29
|
+
qapp = QtWidgets.QApplication.instance()
|
|
30
|
+
if qapp is None:
|
|
31
|
+
do_exit = True
|
|
32
|
+
qapp = start_qapplication()
|
|
33
|
+
|
|
34
|
+
if viewer is None:
|
|
35
|
+
if isinstance(data, DataToExport):
|
|
36
|
+
widget = DockArea()
|
|
37
|
+
viewer = ViewerDispatcher(widget, title=data.name)
|
|
38
|
+
else:
|
|
39
|
+
widget = QtWidgets.QWidget()
|
|
40
|
+
viewer_enum = ViewersEnum.get_viewers_enum_from_data(data)
|
|
41
|
+
viewer = viewer_factory.get(viewer_enum.name, parent=widget)
|
|
42
|
+
widget.show()
|
|
43
|
+
|
|
44
|
+
if viewer is not None:
|
|
45
|
+
viewer.show_data(data, **kwargs)
|
|
46
|
+
if isinstance(viewer, Viewer1D):
|
|
47
|
+
if not viewer.is_action_checked('errors'):
|
|
48
|
+
viewer.get_action('errors').trigger()
|
|
49
|
+
QtWidgets.QApplication.processEvents()
|
|
50
|
+
|
|
51
|
+
if do_exit:
|
|
52
|
+
sys.exit(qapp.exec())
|
|
53
|
+
return viewer
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if __name__ == '__main__':
|
|
57
|
+
from pymodaq.utils import data as data_mod
|
|
58
|
+
import numpy as np
|
|
59
|
+
from pymodaq.utils.math_utils import gauss1D
|
|
60
|
+
from pymodaq.utils.plotting.plotter.plotter import PlotterFactory
|
|
61
|
+
|
|
62
|
+
qapp = start_qapplication()
|
|
63
|
+
|
|
64
|
+
plotter_factory = PlotterFactory()
|
|
65
|
+
|
|
66
|
+
x = np.random.randint(201, size=201)
|
|
67
|
+
y1 = gauss1D(x, 75, 25)
|
|
68
|
+
y2 = gauss1D(x, 120, 50, 2)
|
|
69
|
+
|
|
70
|
+
QtWidgets.QApplication.processEvents()
|
|
71
|
+
dwa = data_mod.DataRaw('mydata', data=[y1, y2],
|
|
72
|
+
axes=[data_mod.Axis('myaxis', 'units', data=x, index=0,
|
|
73
|
+
spread_order=0)],
|
|
74
|
+
nav_indexes=())
|
|
75
|
+
|
|
76
|
+
dwa.plot('qt')
|
|
77
|
+
dwa.as_dte('mydte').plot('qt')
|
|
78
|
+
sys.exit(qapp.exec())
|
|
@@ -44,7 +44,7 @@ class AxesViewer(QtCore.QObject):
|
|
|
44
44
|
|
|
45
45
|
for ind in range(len(axes)):
|
|
46
46
|
self.nav_axes_viewers[ind].roi_line_signal.connect(self._emit_nav_signal)
|
|
47
|
-
self.nav_axes_viewers[ind].show_data([axes[ind].
|
|
47
|
+
self.nav_axes_viewers[ind].show_data([axes[ind].get_data()])
|
|
48
48
|
self.nav_axes_viewers[ind].set_axis_label(dict(orientation='bottom',
|
|
49
49
|
label='Scan index',
|
|
50
50
|
units=''))
|