summaryrefslogtreecommitdiff
path: root/silx/gui/plot/StackView.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/plot/StackView.py')
-rw-r--r--silx/gui/plot/StackView.py134
1 files changed, 63 insertions, 71 deletions
diff --git a/silx/gui/plot/StackView.py b/silx/gui/plot/StackView.py
index 7e4c389..cb7ece1 100644
--- a/silx/gui/plot/StackView.py
+++ b/silx/gui/plot/StackView.py
@@ -78,6 +78,7 @@ import silx
from silx.gui import qt
from .. import icons
from . import items, PlotWindow, actions
+from .items.image import ImageStack
from ..colors import Colormap
from ..colors import cursorColorForColormap
from .tools import LimitsToolBar
@@ -90,6 +91,7 @@ from silx.io.nxdata import save_NXdata
from silx.utils.array_like import DatasetView, ListOfImages
from silx.math import calibration
from silx.utils.deprecation import deprecated_warning
+from silx.utils.deprecation import deprecated
import h5py
from silx.io.utils import is_dataset
@@ -185,7 +187,11 @@ class StackView(qt.QMainWindow):
self._perspective = 0
"""Orthogonal dimension (depth) in :attr:`_stack`"""
- self.__imageLegend = '__StackView__image' + str(id(self))
+ self._stackItem = ImageStack()
+ """Hold the item displaying the stack"""
+ imageLegend = '__StackView__image' + str(id(self))
+ self._stackItem.setName(imageLegend)
+
self.__autoscaleCmap = False
"""Flag to disable/enable colormap auto-scaling
based on the min/max values of the entire 3D volume"""
@@ -215,6 +221,7 @@ class StackView(qt.QMainWindow):
copy=copy, save=save, print_=print_,
control=control, position=position,
roi=False, mask=mask)
+ self._plot.addItem(self._stackItem)
self._plot.getIntensityHistogramAction().setVisible(True)
self.sigInteractiveModeChanged = self._plot.sigInteractiveModeChanged
self.sigActiveImageChanged = self._plot.sigActiveImageChanged
@@ -225,9 +232,9 @@ class StackView(qt.QMainWindow):
self._addColorBarAction()
- self._plot.profile = Profile3DToolBar(parent=self._plot,
- stackview=self)
- self._plot.addToolBar(self._plot.profile)
+ self._profileToolBar = Profile3DToolBar(parent=self._plot,
+ stackview=self)
+ self._plot.addToolBar(self._profileToolBar)
self._plot.getXAxis().setLabel('Columns')
self._plot.getYAxis().setLabel('Rows')
self._plot.sigPlotSignal.connect(self._plotCallback)
@@ -255,9 +262,7 @@ class StackView(qt.QMainWindow):
# clear profile lines when the perspective changes (plane browsed changed)
self.__planeSelection.sigPlaneSelectionChanged.connect(
- self._plot.profile.getProfilePlot().clear)
- self.__planeSelection.sigPlaneSelectionChanged.connect(
- self._plot.profile.clearProfile)
+ self._profileToolBar.clearProfile)
def _saveImageStack(self, plot, filename, nameFilter):
"""Save all images from the stack into a volume.
@@ -293,7 +298,7 @@ class StackView(qt.QMainWindow):
Emit :attr:`valueChanged` signal, with (x, y, value) tuple of the
cursor location in the plot."""
if eventDict['event'] == 'mouseMoved':
- activeImage = self._plot.getActiveImage()
+ activeImage = self.getActiveImage()
if activeImage is not None:
data = activeImage.getData()
height, width = data.shape
@@ -386,6 +391,12 @@ class StackView(qt.QMainWindow):
self._browser.setRange(0, self.__transposed_view.shape[0] - 1)
self._browser.setValue(0)
+ # Update the item structure
+ self._stackItem.setStackData(self.__transposed_view, 0, copy=False)
+ self._stackItem.setColormap(self.getColormap())
+ self._stackItem.setOrigin(self._getImageOrigin())
+ self._stackItem.setScale(self._getImageScale())
+
def __updateFrameNumber(self, index):
"""Update the current image.
@@ -394,11 +405,9 @@ class StackView(qt.QMainWindow):
if self.__transposed_view is None:
# no data set
return
- self._plot.addImage(self.__transposed_view[index, :, :],
- origin=self._getImageOrigin(),
- scale=self._getImageScale(),
- legend=self.__imageLegend,
- resetzoom=False)
+
+ self._stackItem.setStackPosition(index)
+
self._updateTitle()
self.sigFrameChanged.emit(index)
@@ -506,7 +515,7 @@ class StackView(qt.QMainWindow):
:param calibrations: Sequence of 3 calibration objects for each axis.
These objects can be a subclass of :class:`AbstractCalibration`,
or 2-tuples *(a, b)* where *a* is the y-intercept and *b* is the
- slope of a linear calibration (:math:`x \mapsto a + b x`)
+ slope of a linear calibration (:math:`x \\mapsto a + b x`)
"""
if stack is None:
self.clear()
@@ -550,14 +559,18 @@ class StackView(qt.QMainWindow):
self.setColormap(colormap=colormap)
# init plot
- self._plot.addImage(self.__transposed_view[0, :, :],
- legend=self.__imageLegend,
- colormap=self.getColormap(),
- origin=self._getImageOrigin(),
- scale=self._getImageScale(),
- replace=True,
- resetzoom=False)
- self._plot.setActiveImage(self.__imageLegend)
+ self._stackItem.setStackData(self.__transposed_view, 0, copy=False)
+ self._stackItem.setColormap(self.getColormap())
+ self._stackItem.setOrigin(self._getImageOrigin())
+ self._stackItem.setScale(self._getImageScale())
+ self._stackItem.setVisible(True)
+
+ # Put back the item in the plot in case it was cleared
+ exists = self._plot.getImage(self._stackItem.getName())
+ if exists is None:
+ self._plot.addItem(self._stackItem)
+
+ self._plot.setActiveImage(self._stackItem.getName())
self.__updatePlotLabels()
self._updateTitle()
@@ -586,14 +599,11 @@ class StackView(qt.QMainWindow):
:return: 3D stack and parameters.
:rtype: (numpy.ndarray, dict)
"""
- image = self._plot.getActiveImage()
- if image is None:
+ if self._stack is None:
return None
- if isinstance(image, items.ColormapMixIn):
- colormap = image.getColormap()
- else:
- colormap = None
+ image = self._stackItem
+ colormap = image.getColormap()
params = {
'info': image.getInfo(),
@@ -637,7 +647,7 @@ class StackView(qt.QMainWindow):
:return: 3D stack and parameters.
:rtype: (numpy.ndarray, dict)
"""
- image = self._plot.getActiveImage()
+ image = self.getActiveImage()
if image is None:
return None
@@ -882,11 +892,15 @@ class StackView(qt.QMainWindow):
self._plot.setDefaultColormap(_colormap)
# Update active image colormap
- activeImage = self._plot.getActiveImage()
+ activeImage = self.getActiveImage()
if isinstance(activeImage, items.ColormapMixIn):
activeImage.setColormap(self.getColormap())
+ @deprecated(replacement="getPlotWidget", since_version="0.13")
def getPlot(self):
+ return self.getPlotWidget()
+
+ def getPlotWidget(self):
"""Return the :class:`PlotWidget`.
This gives access to advanced plot configuration options.
@@ -898,20 +912,6 @@ class StackView(qt.QMainWindow):
"""
return self._plot
- def getProfileWindow1D(self):
- """Plot window used to display 1D profile curve.
-
- :return: :class:`Plot1D`
- """
- return self._plot.profile.getProfileWindow1D()
-
- def getProfileWindow2D(self):
- """Plot window used to display 2D profile image.
-
- :return: :class:`Plot2D`
- """
- return self._plot.profile.getProfileWindow2D()
-
def setOptionVisible(self, isVisible):
"""
Set the visibility of the browsing options.
@@ -924,10 +924,8 @@ class StackView(qt.QMainWindow):
# proxies to PlotWidget or PlotWindow methods
def getProfileToolbar(self):
"""Profile tools attached to this plot
-
- See :class:`silx.gui.plot.Profile.Profile3DToolBar`
"""
- return self._plot.profile
+ return self._profileToolBar
def getGraphTitle(self):
"""Return the plot main title as a str.
@@ -1046,23 +1044,11 @@ class StackView(qt.QMainWindow):
# kind of private methods, but needed by Profile
def getActiveImage(self, just_legend=False):
- """Returns the currently active image object.
-
- It returns None in case of not having an active image.
-
- This method is a simple proxy to the legacy :class:`PlotWidget` method
- of the same name. Using the object oriented approach is now
- preferred::
-
- stackview.getPlot().getActiveImage()
-
- :param bool just_legend: True to get the legend of the image,
- False (the default) to get the image data and info.
- Note: :class:`StackView` uses the same legend for all frames.
- :return: legend or image object
- :rtype: str or list or None
+ """Returns the stack image object.
"""
- return self._plot.getActiveImage(just_legend=just_legend)
+ if just_legend:
+ return self._stackItem.getName()
+ return self._stackItem
def getColorBarAction(self):
"""Returns the action managing the visibility of the colorbar.
@@ -1085,11 +1071,15 @@ class StackView(qt.QMainWindow):
"""
self._plot.setInteractiveMode(*args, **kwargs)
+ @deprecated(replacement="addShape", since_version="0.13")
def addItem(self, *args, **kwargs):
+ self.addShape(*args, **kwargs)
+
+ def addShape(self, *args, **kwargs):
"""
- See :meth:`Plot.Plot.addItem`
+ See :meth:`Plot.Plot.addShape`
"""
- self._plot.addItem(*args, **kwargs)
+ self._plot.addShape(*args, **kwargs)
class PlanesWidget(qt.QWidget):
@@ -1210,13 +1200,15 @@ class StackViewMainWindow(StackView):
menu.addAction(actions.control.YAxisInvertedAction(self._plot, self))
menu = self.menuBar().addMenu('Profile')
- menu.addAction(self._plot.profile.hLineAction)
- menu.addAction(self._plot.profile.vLineAction)
- menu.addAction(self._plot.profile.lineAction)
+ profileToolBar = self._profileToolBar
+ menu.addAction(profileToolBar.hLineAction)
+ menu.addAction(profileToolBar.vLineAction)
+ menu.addAction(profileToolBar.lineAction)
+ menu.addAction(profileToolBar.crossAction)
+ menu.addSeparator()
+ menu.addAction(profileToolBar._editor)
menu.addSeparator()
- menu.addAction(self._plot.profile.clearAction)
- self._plot.profile.profile3dAction.computeProfileIn2D()
- menu.addMenu(self._plot.profile.profile3dAction.menu())
+ menu.addAction(profileToolBar.clearAction)
# Connect to StackView's signal
self.valueChanged.connect(self._statusBarSlot)