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.

Files changed (80) hide show
  1. pymodaq/__init__.py +23 -4
  2. pymodaq/control_modules/daq_move.py +32 -73
  3. pymodaq/control_modules/daq_viewer.py +73 -98
  4. pymodaq/control_modules/daq_viewer_ui.py +2 -1
  5. pymodaq/control_modules/move_utility_classes.py +17 -7
  6. pymodaq/control_modules/utils.py +153 -5
  7. pymodaq/control_modules/viewer_utility_classes.py +31 -20
  8. pymodaq/dashboard.py +23 -5
  9. pymodaq/examples/tcp_client.py +97 -0
  10. pymodaq/extensions/__init__.py +4 -0
  11. pymodaq/extensions/bayesian/__init__.py +2 -0
  12. pymodaq/extensions/bayesian/bayesian_optimisation.py +673 -0
  13. pymodaq/extensions/bayesian/utils.py +403 -0
  14. pymodaq/extensions/daq_scan.py +4 -4
  15. pymodaq/extensions/daq_scan_ui.py +2 -1
  16. pymodaq/extensions/pid/pid_controller.py +12 -7
  17. pymodaq/extensions/pid/utils.py +9 -26
  18. pymodaq/extensions/utils.py +3 -0
  19. pymodaq/post_treatment/load_and_plot.py +42 -19
  20. pymodaq/resources/VERSION +1 -1
  21. pymodaq/resources/config_template.toml +9 -24
  22. pymodaq/resources/setup_plugin.py +1 -1
  23. pymodaq/utils/config.py +103 -5
  24. pymodaq/utils/daq_utils.py +35 -134
  25. pymodaq/utils/data.py +614 -95
  26. pymodaq/utils/enums.py +17 -1
  27. pymodaq/utils/factory.py +2 -2
  28. pymodaq/utils/gui_utils/custom_app.py +5 -2
  29. pymodaq/utils/gui_utils/dock.py +33 -4
  30. pymodaq/utils/gui_utils/utils.py +14 -1
  31. pymodaq/utils/h5modules/backends.py +9 -1
  32. pymodaq/utils/h5modules/data_saving.py +254 -57
  33. pymodaq/utils/h5modules/saving.py +1 -0
  34. pymodaq/utils/leco/__init__.py +25 -0
  35. pymodaq/utils/leco/daq_move_LECODirector.py +172 -0
  36. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +170 -0
  37. pymodaq/utils/leco/desktop.ini +2 -0
  38. pymodaq/utils/leco/director_utils.py +58 -0
  39. pymodaq/utils/leco/leco_director.py +88 -0
  40. pymodaq/utils/leco/pymodaq_listener.py +279 -0
  41. pymodaq/utils/leco/utils.py +41 -0
  42. pymodaq/utils/managers/action_manager.py +20 -6
  43. pymodaq/utils/managers/parameter_manager.py +6 -4
  44. pymodaq/utils/managers/roi_manager.py +63 -54
  45. pymodaq/utils/math_utils.py +1 -1
  46. pymodaq/utils/plotting/data_viewers/__init__.py +3 -1
  47. pymodaq/utils/plotting/data_viewers/base.py +286 -0
  48. pymodaq/utils/plotting/data_viewers/viewer.py +29 -202
  49. pymodaq/utils/plotting/data_viewers/viewer0D.py +94 -47
  50. pymodaq/utils/plotting/data_viewers/viewer1D.py +341 -174
  51. pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +1 -1
  52. pymodaq/utils/plotting/data_viewers/viewer2D.py +271 -181
  53. pymodaq/utils/plotting/data_viewers/viewerND.py +26 -22
  54. pymodaq/utils/plotting/items/crosshair.py +3 -3
  55. pymodaq/utils/plotting/items/image.py +2 -1
  56. pymodaq/utils/plotting/plotter/plotter.py +94 -0
  57. pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
  58. pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +134 -0
  59. pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +78 -0
  60. pymodaq/utils/plotting/utils/axes_viewer.py +1 -1
  61. pymodaq/utils/plotting/utils/filter.py +194 -147
  62. pymodaq/utils/plotting/utils/lineout.py +13 -11
  63. pymodaq/utils/plotting/utils/plot_utils.py +89 -12
  64. pymodaq/utils/scanner/__init__.py +0 -3
  65. pymodaq/utils/scanner/scan_config.py +1 -9
  66. pymodaq/utils/scanner/scan_factory.py +10 -36
  67. pymodaq/utils/scanner/scanner.py +3 -2
  68. pymodaq/utils/scanner/scanners/_1d_scanners.py +7 -5
  69. pymodaq/utils/scanner/scanners/_2d_scanners.py +36 -49
  70. pymodaq/utils/scanner/scanners/sequential.py +10 -4
  71. pymodaq/utils/scanner/scanners/tabular.py +10 -5
  72. pymodaq/utils/slicing.py +1 -1
  73. pymodaq/utils/tcp_ip/serializer.py +38 -5
  74. pymodaq/utils/tcp_ip/tcp_server_client.py +25 -17
  75. {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/METADATA +4 -2
  76. {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/RECORD +79 -63
  77. pymodaq/resources/config_scan_template.toml +0 -42
  78. {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/WHEEL +0 -0
  79. {pymodaq-4.1.5.dist-info → pymodaq-4.2.1.dist-info}/entry_points.txt +0 -0
  80. {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
- self.viewer0D.setVisible(len(data.shape) - len(data.nav_indexes) == 0)
667
- self.viewer1D.setVisible(len(data.shape) - len(data.nav_indexes) == 1)
668
- self.viewer2D.setVisible(len(data.shape) - len(data.nav_indexes) == 2)
669
- self.viewer1D.roi.setVisible(len(data.nav_indexes) != 0)
670
- self.viewer2D.roi.setVisible(len(data.nav_indexes) != 0)
671
- self._dock_navigation.setVisible(len(data.nav_indexes) != 0)
672
- nav_axes = data.get_nav_axes()
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(nav_axes) == 1)
676
- self.navigator2D.setVisible(len(nav_axes) == 2)
677
- self.axes_viewer.setVisible(len(data.nav_indexes) > 2)
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(nav_axes) == 2 and self.data_displayer.triangulation)
680
- self.navigator1D.setVisible(len(nav_axes) == 1 or len(nav_axes) > 2 or
681
- len(nav_axes) == 2 and not self.data_displayer.triangulation)
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].data])
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=''))