summaryrefslogtreecommitdiff
path: root/silx/gui/plot/ColorBar.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/plot/ColorBar.py')
-rw-r--r--silx/gui/plot/ColorBar.py117
1 files changed, 76 insertions, 41 deletions
diff --git a/silx/gui/plot/ColorBar.py b/silx/gui/plot/ColorBar.py
index 2db7b79..0941e82 100644
--- a/silx/gui/plot/ColorBar.py
+++ b/silx/gui/plot/ColorBar.py
@@ -1,7 +1,7 @@
# coding: utf-8
# /*##########################################################################
#
-# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+# Copyright (c) 2016-2018 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
@@ -27,14 +27,16 @@
__authors__ = ["H. Payno", "T. Vincent"]
__license__ = "MIT"
-__date__ = "15/02/2018"
+__date__ = "24/04/2018"
import logging
+import weakref
import numpy
+
from ._utils import ticklayout
-from .. import qt, icons
-from silx.gui.plot import Colormap
+from .. import qt
+from silx.gui import colors
_logger = logging.getLogger(__name__)
@@ -70,7 +72,7 @@ class ColorBarWidget(qt.QWidget):
def __init__(self, parent=None, plot=None, legend=None):
self._isConnected = False
- self._plot = None
+ self._plotRef = None
self._colormap = None
self._data = None
@@ -96,7 +98,7 @@ class ColorBarWidget(qt.QWidget):
def getPlot(self):
"""Returns the :class:`Plot` associated to this widget or None"""
- return self._plot
+ return None if self._plotRef is None else self._plotRef()
def setPlot(self, plot):
"""Associate a plot to the ColorBar
@@ -105,27 +107,38 @@ class ColorBarWidget(qt.QWidget):
If None will remove any connection with a previous plot.
"""
self._disconnectPlot()
- self._plot = plot
+ self._plotRef = None if plot is None else weakref.ref(plot)
self._connectPlot()
def _disconnectPlot(self):
"""Disconnect from Plot signals"""
- if self._plot is not None and self._isConnected:
+ plot = self.getPlot()
+ if plot is not None and self._isConnected:
self._isConnected = False
- self._plot.sigActiveImageChanged.disconnect(
+ plot.sigActiveImageChanged.disconnect(
self._activeImageChanged)
- self._plot.sigPlotSignal.disconnect(self._defaultColormapChanged)
+ plot.sigActiveScatterChanged.disconnect(
+ self._activeScatterChanged)
+ plot.sigPlotSignal.disconnect(self._defaultColormapChanged)
def _connectPlot(self):
"""Connect to Plot signals"""
- if self._plot is not None and not self._isConnected:
- activeImageLegend = self._plot.getActiveImage(just_legend=True)
- if activeImageLegend is None: # Show plot default colormap
+ plot = self.getPlot()
+ if plot is not None and not self._isConnected:
+ activeImageLegend = plot.getActiveImage(just_legend=True)
+ activeScatterLegend = plot._getActiveItem(
+ kind='scatter', just_legend=True)
+ if activeImageLegend is None and activeScatterLegend is None:
+ # Show plot default colormap
self._syncWithDefaultColormap()
- else: # Show active image colormap
+ elif activeImageLegend is not None: # Show active image colormap
self._activeImageChanged(None, activeImageLegend)
- self._plot.sigActiveImageChanged.connect(self._activeImageChanged)
- self._plot.sigPlotSignal.connect(self._defaultColormapChanged)
+ elif activeScatterLegend is not None: # Show active scatter colormap
+ self._activeScatterChanged(None, activeScatterLegend)
+
+ plot.sigActiveImageChanged.connect(self._activeImageChanged)
+ plot.sigActiveScatterChanged.connect(self._activeScatterChanged)
+ plot.sigPlotSignal.connect(self._defaultColormapChanged)
self._isConnected = True
def setVisible(self, isVisible):
@@ -196,36 +209,58 @@ class ColorBarWidget(qt.QWidget):
"""
return self.legend.getText()
- def _activeImageChanged(self, previous, legend):
- """Handle plot active curve changed"""
- if legend is None: # No active image, display no colormap
- self.setColormap(colormap=None)
- return
+ def _activeScatterChanged(self, previous, legend):
+ """Handle plot active scatter changed"""
+ plot = self.getPlot()
- # Sync with active image
- image = self._plot.getActiveImage().getData(copy=False)
+ # Do not handle active scatter while there is an image
+ if plot.getActiveImage() is not None:
+ return
- # RGB(A) image, display default colormap
- if image.ndim != 2:
+ if legend is None: # No active scatter, display no colormap
self.setColormap(colormap=None)
return
- # data image, sync with image colormap
- # do we need the copy here : used in the case we are changing
- # vmin and vmax but should have already be done by the plot
- self.setColormap(colormap=self._plot.getActiveImage().getColormap(),
- data=image)
+ # Sync with active scatter
+ activeScatter = plot._getActiveItem(kind='scatter')
+
+ self.setColormap(colormap=activeScatter.getColormap(),
+ data=activeScatter.getValueData(copy=False))
+
+ def _activeImageChanged(self, previous, legend):
+ """Handle plot active image changed"""
+ plot = self.getPlot()
+
+ if legend is None: # No active image, try with active scatter
+ activeScatterLegend = plot._getActiveItem(
+ kind='scatter', just_legend=True)
+ # No more active image, use active scatter if any
+ self._activeScatterChanged(None, activeScatterLegend)
+ else:
+ # Sync with active image
+ image = plot.getActiveImage().getData(copy=False)
+
+ # RGB(A) image, display default colormap
+ if image.ndim != 2:
+ self.setColormap(colormap=None)
+ return
+
+ # data image, sync with image colormap
+ # do we need the copy here : used in the case we are changing
+ # vmin and vmax but should have already be done by the plot
+ self.setColormap(colormap=plot.getActiveImage().getColormap(),
+ data=image)
def _defaultColormapChanged(self, event):
"""Handle plot default colormap changed"""
if (event['event'] == 'defaultColormapChanged' and
- self._plot.getActiveImage() is None):
+ self.getPlot().getActiveImage() is None):
# No active image, take default colormap update into account
self._syncWithDefaultColormap()
def _syncWithDefaultColormap(self, data=None):
"""Update colorbar according to plot default colormap"""
- self.setColormap(self._plot.getDefaultColormap(), data)
+ self.setColormap(self.getPlot().getDefaultColormap(), data)
def getColorScaleBar(self):
"""
@@ -316,9 +351,9 @@ class ColorScaleBar(qt.QWidget):
if colormap:
vmin, vmax = colormap.getColormapRange(data)
else:
- vmin, vmax = Colormap.DEFAULT_MIN_LIN, Colormap.DEFAULT_MAX_LIN
+ vmin, vmax = colors.DEFAULT_MIN_LIN, colors.DEFAULT_MAX_LIN
- norm = colormap.getNormalization() if colormap else Colormap.Colormap.LINEAR
+ norm = colormap.getNormalization() if colormap else colors.Colormap.LINEAR
self.tickbar = _TickBar(vmin=vmin,
vmax=vmax,
norm=norm,
@@ -503,7 +538,7 @@ class _ColorScale(qt.QWidget):
if colormap is None:
self.vmin, self.vmax = None, None
else:
- assert colormap.getNormalization() in Colormap.Colormap.NORMALIZATIONS
+ assert colormap.getNormalization() in colors.Colormap.NORMALIZATIONS
self.vmin, self.vmax = self._colormap.getColormapRange(data=data)
self._updateColorGradient()
self.update()
@@ -575,9 +610,9 @@ class _ColorScale(qt.QWidget):
vmin = self.vmin
vmax = self.vmax
- if colormap.getNormalization() == Colormap.Colormap.LINEAR:
+ if colormap.getNormalization() == colors.Colormap.LINEAR:
return vmin + (vmax - vmin) * value
- elif colormap.getNormalization() == Colormap.Colormap.LOGARITHM:
+ elif colormap.getNormalization() == colors.Colormap.LOGARITHM:
rpos = (numpy.log10(vmax) - numpy.log10(vmin)) * value + numpy.log10(vmin)
return numpy.power(10., rpos)
else:
@@ -706,9 +741,9 @@ class _TickBar(qt.QWidget):
# No range: no ticks
self.ticks = ()
self.subTicks = ()
- elif self._norm == Colormap.Colormap.LOGARITHM:
+ elif self._norm == colors.Colormap.LOGARITHM:
self._computeTicksLog(nticks)
- elif self._norm == Colormap.Colormap.LINEAR:
+ elif self._norm == colors.Colormap.LINEAR:
self._computeTicksLin(nticks)
else:
err = 'TickBar - Wrong normalization %s' % self._norm
@@ -765,9 +800,9 @@ class _TickBar(qt.QWidget):
def _getRelativePosition(self, val):
"""Return the relative position of val according to min and max value
"""
- if self._norm == Colormap.Colormap.LINEAR:
+ if self._norm == colors.Colormap.LINEAR:
return 1 - (val - self._vmin) / (self._vmax - self._vmin)
- elif self._norm == Colormap.Colormap.LOGARITHM:
+ elif self._norm == colors.Colormap.LOGARITHM:
return 1 - (numpy.log10(val) - numpy.log10(self._vmin)) / (numpy.log10(self._vmax) - numpy.log(self._vmin))
else:
raise ValueError('Norm is not recognized')