summaryrefslogtreecommitdiff
path: root/silx/gui/plot/items/complex.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/plot/items/complex.py')
-rw-r--r--silx/gui/plot/items/complex.py84
1 files changed, 56 insertions, 28 deletions
diff --git a/silx/gui/plot/items/complex.py b/silx/gui/plot/items/complex.py
index 0e492a0..abb64ad 100644
--- a/silx/gui/plot/items/complex.py
+++ b/silx/gui/plot/items/complex.py
@@ -1,7 +1,7 @@
# coding: utf-8
# /*##########################################################################
#
-# Copyright (c) 2017-2020 European Synchrotron Radiation Facility
+# Copyright (c) 2017-2021 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -184,18 +184,18 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn):
def setComplexMode(self, mode):
changed = super(ImageComplexData, self).setComplexMode(mode)
if changed:
+ self._valueDataChanged()
+
# Backward compatibility
self._updated(ItemChangedType.VISUALIZATION_MODE)
- # Send data updated as value returned by getData has changed
- self._updated(ItemChangedType.DATA)
-
# Update ColormapMixIn colormap
colormap = self._colormaps[self.getComplexMode()]
if colormap is not super(ImageComplexData, self).getColormap():
super(ImageComplexData, self).setColormap(colormap)
- self._setColormappedData(self.getData(copy=False), copy=False)
+ # Send data updated as value returned by getData has changed
+ self._updated(ItemChangedType.DATA)
return changed
def _setAmplitudeRangeInfo(self, max_=None, delta=2):
@@ -263,10 +263,32 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn):
'Image is not complex, converting it to complex to plot it.')
data = numpy.array(data, dtype=numpy.complex64)
- self._dataByModesCache = {}
- self._setColormappedData(self.getData(copy=False), copy=False)
+ # Compute current mode data and set colormap data
+ mode = self.getComplexMode()
+ dataForMode = self.__convertComplexData(data, self.getComplexMode())
+ self._dataByModesCache = {mode: dataForMode}
+
super().setData(data)
+ def _updated(self, event=None, checkVisibility=True):
+ # Synchronizes colormapped data if changed
+ # ItemChangedType.COMPLEX_MODE triggers ItemChangedType.DATA
+ # No need to handle it twice.
+ if event in (ItemChangedType.DATA, ItemChangedType.MASK):
+ # Color-mapped data is NOT the `getValueData` for some modes
+ if self.getComplexMode() in (
+ self.ComplexMode.AMPLITUDE_PHASE,
+ self.ComplexMode.LOG10_AMPLITUDE_PHASE):
+ data = self.getData(copy=False, mode=self.ComplexMode.PHASE)
+ mask = self.getMaskData(copy=False)
+ if mask is not None:
+ data = numpy.copy(data)
+ data[mask != 0] = numpy.nan
+ else:
+ data = self.getValueData(copy=False)
+ self._setColormappedData(data, copy=False)
+ super()._updated(event=event, checkVisibility=checkVisibility)
+
def getComplexData(self, copy=True):
"""Returns the image complex data
@@ -276,6 +298,31 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn):
"""
return super().getData(copy=copy)
+ def __convertComplexData(self, data, mode):
+ """Convert complex data to given mode.
+
+ :param numpy.ndarray data:
+ :param Union[ComplexMode,str] mode:
+ :rtype: numpy.ndarray of float
+ """
+ if mode is self.ComplexMode.PHASE:
+ return numpy.angle(data)
+ elif mode is self.ComplexMode.REAL:
+ return numpy.real(data)
+ elif mode is self.ComplexMode.IMAGINARY:
+ return numpy.imag(data)
+ elif mode in (self.ComplexMode.ABSOLUTE,
+ self.ComplexMode.LOG10_AMPLITUDE_PHASE,
+ self.ComplexMode.AMPLITUDE_PHASE):
+ return numpy.absolute(data)
+ elif mode is self.ComplexMode.SQUARE_AMPLITUDE:
+ return numpy.absolute(data) ** 2
+ else:
+ _logger.error(
+ 'Unsupported conversion mode: %s, fallback to absolute',
+ str(mode))
+ return numpy.absolute(data)
+
def getData(self, copy=True, mode=None):
"""Returns the image data corresponding to (current) mode.
@@ -295,27 +342,8 @@ class ImageComplexData(ImageBase, ColormapMixIn, ComplexMixIn):
mode = self.ComplexMode.from_value(mode)
if mode not in self._dataByModesCache:
- # Compute data for mode and store it in cache
- complexData = self.getComplexData(copy=False)
- if mode is self.ComplexMode.PHASE:
- data = numpy.angle(complexData)
- elif mode is self.ComplexMode.REAL:
- data = numpy.real(complexData)
- elif mode is self.ComplexMode.IMAGINARY:
- data = numpy.imag(complexData)
- elif mode in (self.ComplexMode.ABSOLUTE,
- self.ComplexMode.LOG10_AMPLITUDE_PHASE,
- self.ComplexMode.AMPLITUDE_PHASE):
- data = numpy.absolute(complexData)
- elif mode is self.ComplexMode.SQUARE_AMPLITUDE:
- data = numpy.absolute(complexData) ** 2
- else:
- _logger.error(
- 'Unsupported conversion mode: %s, fallback to absolute',
- str(mode))
- data = numpy.absolute(complexData)
-
- self._dataByModesCache[mode] = data
+ self._dataByModesCache[mode] = self.__convertComplexData(
+ self.getComplexData(copy=False), mode)
return numpy.array(self._dataByModesCache[mode], copy=copy)