Skip to content

Commit

Permalink
Merge pull request #3279 from t20100/stackview
Browse files Browse the repository at this point in the history
silx.gui.plot.Stackview: Replaced `setColormap` `autoscale` argument by `scaleColormapRangeToStack` method
  • Loading branch information
payno authored Nov 25, 2020
2 parents dd90eb3 + bd0389c commit aff5a05
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 35 deletions.
66 changes: 32 additions & 34 deletions silx/gui/plot/StackView.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2018 European Synchrotron Radiation Facility
# Copyright (c) 2016-2020 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
Expand Down Expand Up @@ -548,15 +548,8 @@ def setStack(self, stack, perspective=None, reset=True, calibrations=None):
perspective_changed = True
self.setPerspective(perspective)

# This call to setColormap redefines the meaning of autoscale
# for 3D volume: take global min/max rather than frame min/max
if self.__autoscaleCmap:
# note: there is no real autoscale in the stack widget, it is more
# like a hack computing stack min and max
colormap = self.getColormap()
_vmin, _vmax = colormap.getColormapRange(data=self._stack)
colormap.setVRange(_vmin, _vmax)
self.setColormap(colormap=colormap)
self.scaleColormapRangeToStack()

# init plot
self._stackItem.setStackData(self.__transposed_view, 0, copy=False)
Expand Down Expand Up @@ -791,6 +784,22 @@ def getColormap(self):
# specifying a special colormap
return self._plot.getDefaultColormap()

def scaleColormapRangeToStack(self):
"""Scale colormap range according to current stack data.
If no stack has been set through :meth:`setStack`, this has no effect.
The range scaling mode is given by current :class:`Colormap`'s
:meth:`Colormap.getAutoscaleMode`.
"""
stack = self.getStack(copy=False, returnNumpyArray=True)
if stack is None:
return # No-op

colormap = self.getColormap()
vmin, vmax = colormap.getColormapRange(data=stack[0])
colormap.setVRange(vmin=vmin, vmax=vmax)

def setColormap(self, colormap=None, normalization=None,
autoscale=None, vmin=None, vmax=None, colors=None):
"""Set the colormap and update active image.
Expand Down Expand Up @@ -860,31 +869,14 @@ def setColormap(self, colormap=None, normalization=None,
vmax=vmax,
colors=colors)

# Patch: since we don't apply this colormap to a single 2D data but
# a 2D stack we have to deal manually with vmin, vmax
if autoscale is None:
# set default
autoscale = False
elif autoscale and is_dataset(self._stack):
# h5py dataset has no min()/max() methods
raise RuntimeError(
"Cannot auto-scale colormap for a h5py dataset")
else:
autoscale = autoscale
self.__autoscaleCmap = autoscale

if autoscale and (self._stack is not None):
_vmin, _vmax = _colormap.getColormapRange(data=self._stack)
_colormap.setVRange(vmin=_vmin, vmax=_vmax)
else:
if vmin is None and self._stack is not None:
_colormap.setVMin(self._stack.min())
else:
_colormap.setVMin(vmin)
if vmax is None and self._stack is not None:
_colormap.setVMax(self._stack.max())
else:
_colormap.setVMax(vmax)
if autoscale is not None:
deprecated_warning(
type_='function',
name='setColormap',
reason='autoscale argument is replaced by a method',
replacement='scaleColormapRangeToStack',
since_version='0.14')
self.__autoscaleCmap = bool(autoscale)

cursorColor = cursorColorForColormap(_colormap.getName())
self._plot.setInteractiveMode('zoom', color=cursorColor)
Expand All @@ -896,6 +888,12 @@ def setColormap(self, colormap=None, normalization=None,
if isinstance(activeImage, items.ColormapMixIn):
activeImage.setColormap(self.getColormap())

if self.__autoscaleCmap:
# scaleColormapRangeToStack needs to be called **after**
# setDefaultColormap so getColormap returns the right colormap
self.scaleColormapRangeToStack()


@deprecated(replacement="getPlotWidget", since_version="0.13")
def getPlot(self):
return self.getPlotWidget()
Expand Down
15 changes: 14 additions & 1 deletion silx/gui/plot/test/testStackView.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2019 European Synchrotron Radiation Facility
# Copyright (c) 2016-2020 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
Expand Down Expand Up @@ -60,6 +60,19 @@ def tearDown(self):
del self.stackview
super(TestStackView, self).tearDown()

def testScaleColormapRangeToStack(self):
"""Test scaleColormapRangeToStack"""
self.stackview.setStack(self.mystack)
self.stackview.setColormap("viridis")
colormap = self.stackview.getColormap()

# Colormap autoscale to image
self.assertEqual(colormap.getVRange(), (None, None))
self.stackview.scaleColormapRangeToStack()

# Colormap range set according to stack range
self.assertEqual(colormap.getVRange(), (self.mystack.min(), self.mystack.max()))

def testSetStack(self):
self.stackview.setStack(self.mystack)
self.stackview.setColormap("viridis", autoscale=True)
Expand Down

0 comments on commit aff5a05

Please sign in to comment.