summaryrefslogtreecommitdiff
path: root/silx/gui/plot/ColorBar.py
diff options
context:
space:
mode:
authorPicca Frédéric-Emmanuel <picca@debian.org>2017-10-07 07:59:01 +0200
committerPicca Frédéric-Emmanuel <picca@debian.org>2017-10-07 07:59:01 +0200
commitbfa4dba15485b4192f8bbe13345e9658c97ecf76 (patch)
treefb9c6e5860881fbde902f7cbdbd41dc4a3a9fb5d /silx/gui/plot/ColorBar.py
parentf7bdc2acff3c13a6d632c28c4569690ab106eed7 (diff)
New upstream version 0.6.0+dfsg
Diffstat (limited to 'silx/gui/plot/ColorBar.py')
-rw-r--r--silx/gui/plot/ColorBar.py456
1 files changed, 265 insertions, 191 deletions
diff --git a/silx/gui/plot/ColorBar.py b/silx/gui/plot/ColorBar.py
index 93e3c36..8f4bde2 100644
--- a/silx/gui/plot/ColorBar.py
+++ b/silx/gui/plot/ColorBar.py
@@ -33,11 +33,8 @@ __date__ = "11/04/2017"
import logging
import numpy
from ._utils import ticklayout
-from ._utils import clipColormapLogRange
-
-
-from .. import qt
-from silx.gui.plot import Colors
+from .. import qt, icons
+from silx.gui.plot import Colormap
_logger = logging.getLogger(__name__)
@@ -66,12 +63,17 @@ class ColorBarWidget(qt.QWidget):
:param parent: See :class:`QWidget`
:param plot: PlotWidget the colorbar is attached to (optional)
- :param str legend: the label to set to the colormap
+ :param str legend: the label to set to the colorbar
"""
def __init__(self, parent=None, plot=None, legend=None):
- super(ColorBarWidget, self).__init__(parent)
+ self._isConnected = False
self._plot = None
+ self._viewAction = None
+ self._colormap = None
+ self._data = None
+
+ super(ColorBarWidget, self).__init__(parent)
self.__buildGUI()
self.setLegend(legend)
@@ -90,8 +92,6 @@ class ColorBarWidget(qt.QWidget):
self.layout().addWidget(self.legend)
self.layout().setSizeConstraint(qt.QLayout.SetMinAndMaxSize)
- self.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
- self.layout().setContentsMargins(0, 0, 0, 0)
def getPlot(self):
"""Returns the :class:`Plot` associated to this widget or None"""
@@ -100,46 +100,75 @@ class ColorBarWidget(qt.QWidget):
def setPlot(self, plot):
"""Associate a plot to the ColorBar
- :param plot: the plot to associate with the colorbar. If None will remove
- any connection with a previous plot.
+ :param plot: the plot to associate with the colorbar.
+ If None will remove any connection with a previous plot.
"""
- # removing previous plot if any
- if self._plot is not None:
- self._plot.sigActiveImageChanged.disconnect(self._activeImageChanged)
-
- # setting the new plot
+ self._disconnectPlot()
self._plot = plot
- if self._plot is not None:
+ self._connectPlot()
+
+ def _disconnectPlot(self):
+ """Disconnect from Plot signals"""
+ if self._plot is not None and self._isConnected:
+ self._isConnected = False
+ self._plot.sigActiveImageChanged.disconnect(
+ self._activeImageChanged)
+ self._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
+ self._syncWithDefaultColormap()
+ else: # Show active image colormap
+ self._activeImageChanged(None, activeImageLegend)
self._plot.sigActiveImageChanged.connect(self._activeImageChanged)
- self._activeImageChanged(self._plot.getActiveImage(just_legend=True))
+ self._plot.sigPlotSignal.connect(self._defaultColormapChanged)
+ self._isConnected = True
+
+ def showEvent(self, event):
+ self._connectPlot()
+ if self._viewAction is not None:
+ self._viewAction.setChecked(True)
+
+ def hideEvent(self, event):
+ self._disconnectPlot()
+ if self._viewAction is not None:
+ self._viewAction.setChecked(False)
def getColormap(self):
- """Return the colormap displayed in the colorbar as a dict.
+ """
+
+ :return: the :class:`.Colormap` colormap displayed in the colorbar.
- It returns None if no colormap is set.
- See :class:`silx.gui.plot.Plot` documentation for the description of the colormap
- dict description.
"""
- return self._colormap.copy()
+ return self.getColorScaleBar().getColormap()
- def setColormap(self, colormap):
+ def setColormap(self, colormap, data=None):
"""Set the colormap to be displayed.
- :param dict colormap: The colormap to apply on the ColorBarWidget
+ :param colormap: The colormap to apply on the
+ ColorBarWidget
+ :type colormap: :class:`.Colormap`
+ :param numpy.ndarray data: the data to display, needed if the colormap
+ require an autoscale
"""
+ self._data = data
+ self.getColorScaleBar().setColormap(colormap=colormap,
+ data=data)
+ if self._colormap is not None:
+ self._colormap.sigChanged.disconnect(self._colormapHasChanged)
self._colormap = colormap
- if self._colormap is None:
- return
-
- if self._colormap['normalization'] not in ('log', 'linear'):
- raise ValueError('Wrong normalization %s' % self._colormap['normalization'])
+ if self._colormap is not None:
+ self._colormap.sigChanged.connect(self._colormapHasChanged)
- if self._colormap['normalization'] is 'log':
- if self._colormap['vmin'] < 1. or self._colormap['vmax'] < 1.:
- _logger.warning('Log colormap with bound <= 1: changing bounds.')
- clipColormapLogRange(colormap)
-
- self.getColorScaleBar().setColormap(self._colormap)
+ def _colormapHasChanged(self):
+ """handler of the Colormap.sigChanged signal
+ """
+ assert self._colormap is not None
+ self.setColormap(colormap=self._colormap,
+ data=self._data)
def setLegend(self, legend):
"""Set the legend displayed along the colorbar
@@ -150,7 +179,7 @@ class ColorBarWidget(qt.QWidget):
self.legend.hide()
self.legend.setText("")
else:
- assert(type(legend) is str)
+ assert type(legend) is str
self.legend.show()
self.legend.setText(legend)
@@ -163,10 +192,10 @@ class ColorBarWidget(qt.QWidget):
"""
return self.legend.getText()
- def _activeImageChanged(self, legend):
+ def _activeImageChanged(self, previous, legend):
"""Handle plot active curve changed"""
- if legend is None: # No active image, display default colormap
- self._syncWithDefaultColormap()
+ if legend is None: # No active image, display no colormap
+ self.setColormap(colormap=None)
return
# Sync with active image
@@ -174,32 +203,25 @@ class ColorBarWidget(qt.QWidget):
# RGB(A) image, display default colormap
if image.ndim != 2:
- self._syncWithDefaultColormap()
+ 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
- cmap = self._plot.getActiveImage().getColormap().copy()
- if cmap['autoscale']:
- if cmap['normalization'] == 'log':
- data = image[
- numpy.logical_and(image > 0, numpy.isfinite(image))]
- else:
- data = image[numpy.isfinite(image)]
- cmap['vmin'], cmap['vmax'] = data.min(), data.max()
-
- self.setColormap(cmap)
+ self.setColormap(colormap=self._plot.getActiveImage().getColormap(),
+ data=image)
- def _defaultColormapChanged(self):
+ def _defaultColormapChanged(self, event):
"""Handle plot default colormap changed"""
- if self._plot.getActiveImage() is None:
+ if (event['event'] == 'defaultColormapChanged' and
+ self._plot.getActiveImage() is None):
# No active image, take default colormap update into account
self._syncWithDefaultColormap()
- def _syncWithDefaultColormap(self):
+ def _syncWithDefaultColormap(self, data=None):
"""Update colorbar according to plot default colormap"""
- self.setColormap(self._plot.getDefaultColormap())
+ self.setColormap(self._plot.getDefaultColormap(), data)
def getColorScaleBar(self):
"""
@@ -208,6 +230,21 @@ class ColorBarWidget(qt.QWidget):
and ticks"""
return self._colorScale
+ def getToggleViewAction(self):
+ """Returns a checkable action controlling this widget's visibility.
+
+ :rtype: QAction
+ """
+ if self._viewAction is None:
+ self._viewAction = qt.QAction(self)
+ self._viewAction.setText('Colorbar')
+ self._viewAction.setIcon(icons.getQIcon('colorbar'))
+ self._viewAction.setToolTip('Show/Hide the colorbar')
+ self._viewAction.setCheckable(True)
+ self._viewAction.setChecked(self.isVisible())
+ self._viewAction.toggled[bool].connect(self.setVisible)
+ return self._viewAction
+
class _VerticalLegend(qt.QLabel):
"""Display vertically the given text
@@ -251,12 +288,11 @@ class ColorScaleBar(qt.QWidget):
To run the following sample code, a QApplication must be initialized.
- >>> colormap={'name':'gray',
- ... 'normalization':'log',
- ... 'vmin':1,
- ... 'vmax':100000,
- ... 'autoscale':False
- ... }
+ >>> colormap = Colormap(name='gray',
+ ... norm='log',
+ ... vmin=1,
+ ... vmax=100000,
+ ... )
>>> colorscale = ColorScaleBar(parent=None,
... colormap=colormap )
>>> colorscale.show()
@@ -272,15 +308,8 @@ class ColorScaleBar(qt.QWidget):
"""The tick bar need a margin to display all labels at the correct place.
So the ColorScale should have the same margin in order for both to fit"""
- _MIN_LIM_SCI_FORM = -1000
- """Used for the min and max label to know when we should display it under
- the scientific form"""
-
- _MAX_LIM_SCI_FORM = 1000
- """Used for the min and max label to know when we should display it under
- the scientific form"""
-
- def __init__(self, parent=None, colormap=None, displayTicksValues=True):
+ def __init__(self, parent=None, colormap=None, data=None,
+ displayTicksValues=True):
super(ColorScaleBar, self).__init__(parent)
self.minVal = None
@@ -292,33 +321,41 @@ class ColorScaleBar(qt.QWidget):
# create the left side group (ColorScale)
self.colorScale = _ColorScale(colormap=colormap,
- parent=self,
- margin=ColorScaleBar._TEXT_MARGIN)
+ data=data,
+ parent=self,
+ margin=ColorScaleBar._TEXT_MARGIN)
+ if colormap:
+ vmin, vmax = colormap.getColormapRange(data)
+ else:
+ vmin, vmax = Colormap.DEFAULT_MIN_LIN, Colormap.DEFAULT_MAX_LIN
- self.tickbar = _TickBar(vmin=colormap['vmin'] if colormap else 0.0,
- vmax=colormap['vmax'] if colormap else 1.0,
- norm=colormap['normalization'] if colormap else 'linear',
- parent=self,
- displayValues=displayTicksValues,
- margin=ColorScaleBar._TEXT_MARGIN)
+ norm = colormap.getNormalization() if colormap else Colormap.Colormap.LINEAR
+ self.tickbar = _TickBar(vmin=vmin,
+ vmax=vmax,
+ norm=norm,
+ parent=self,
+ displayValues=displayTicksValues,
+ margin=ColorScaleBar._TEXT_MARGIN)
- self.layout().addWidget(self.tickbar, 1, 0)
- self.layout().addWidget(self.colorScale, 1, 1)
+ self.layout().addWidget(self.tickbar, 1, 0, 1, 1, qt.Qt.AlignRight)
+ self.layout().addWidget(self.colorScale, 1, 1, qt.Qt.AlignLeft)
self.layout().setContentsMargins(0, 0, 0, 0)
self.layout().setSpacing(0)
# max label
self._maxLabel = qt.QLabel(str(1.0), parent=self)
- self._maxLabel.setAlignment(qt.Qt.AlignHCenter)
- self._maxLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum)
- self.layout().addWidget(self._maxLabel, 0, 1)
+ self._maxLabel.setToolTip(str(0.0))
+ self.layout().addWidget(self._maxLabel, 0, 0, 1, 2, qt.Qt.AlignRight)
# min label
self._minLabel = qt.QLabel(str(0.0), parent=self)
- self._minLabel.setAlignment(qt.Qt.AlignHCenter)
- self._minLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum)
- self.layout().addWidget(self._minLabel, 2, 1)
+ self._minLabel.setToolTip(str(0.0))
+ self.layout().addWidget(self._minLabel, 2, 0, 1, 2, qt.Qt.AlignRight)
+
+ self.layout().setSizeConstraint(qt.QLayout.SetMinAndMaxSize)
+ self.layout().setColumnStretch(0, 1)
+ self.layout().setRowStretch(1, 1)
def getTickBar(self):
"""
@@ -334,19 +371,34 @@ class ColorScaleBar(qt.QWidget):
"""
return self.colorScale
- def setColormap(self, colormap):
+ def getColormap(self):
+ """
+
+ :returns: the colormap.
+ :rtype: :class:`.Colormap`
+ """
+ return self.colorScale.getColormap()
+
+ def setColormap(self, colormap, data=None):
"""Set the new colormap to be displayed
- :param dict colormap: the colormap to set
+ :param Colormap colormap: the colormap to set
+ :param numpy.ndarray data: the data to display, needed if the colormap
+ require an autoscale
"""
- if colormap is not None:
- self.colorScale.setColormap(colormap)
+ self.colorScale.setColormap(colormap, data)
- self.tickbar.update(vmin=colormap['vmin'],
- vmax=colormap['vmax'],
- norm=colormap['normalization'])
+ if colormap is not None:
+ vmin, vmax = colormap.getColormapRange(data)
+ norm = colormap.getNormalization()
+ else:
+ vmin, vmax = None, None
+ norm = None
- self._setMinMaxLabels(colormap['vmin'], colormap['vmax'])
+ self.tickbar.update(vmin=vmin,
+ vmax=vmax,
+ norm=norm)
+ self._setMinMaxLabels(vmin, vmax)
def setMinMaxVisible(self, val=True):
"""Change visibility of the min label and the max label
@@ -359,17 +411,29 @@ class ColorScaleBar(qt.QWidget):
def _updateMinMax(self):
"""Update the min and max label if we are in the case of the
configuration 'minMaxValueOnly'"""
- if self._minLabel is not None and self._maxLabel is not None:
- if self.minVal is not None:
- if ColorScaleBar._MIN_LIM_SCI_FORM <= self.minVal <= ColorScaleBar._MAX_LIM_SCI_FORM:
- self._minLabel.setText(str(self.minVal))
- else:
- self._minLabel.setText("{0:.0e}".format(self.minVal))
- if self.maxVal is not None:
- if ColorScaleBar._MIN_LIM_SCI_FORM <= self.maxVal <= ColorScaleBar._MAX_LIM_SCI_FORM:
- self._maxLabel.setText(str(self.maxVal))
- else:
- self._maxLabel.setText("{0:.0e}".format(self.maxVal))
+ if self.minVal is None:
+ text, tooltip = '', ''
+ else:
+ if self.minVal == 0 or 0 <= numpy.log10(abs(self.minVal)) < 7:
+ text = '%.7g' % self.minVal
+ else:
+ text = '%.2e' % self.minVal
+ tooltip = repr(self.minVal)
+
+ self._minLabel.setText(text)
+ self._minLabel.setToolTip(tooltip)
+
+ if self.maxVal is None:
+ text, tooltip = '', ''
+ else:
+ if self.maxVal == 0 or 0 <= numpy.log10(abs(self.maxVal)) < 7:
+ text = '%.7g' % self.maxVal
+ else:
+ text = '%.2e' % self.maxVal
+ tooltip = repr(self.maxVal)
+
+ self._maxLabel.setText(text)
+ self._maxLabel.setToolTip(tooltip)
def _setMinMaxLabels(self, minVal, maxVal):
"""Change the value of the min and max labels to be displayed.
@@ -400,12 +464,11 @@ class _ColorScale(qt.QWidget):
To run the following sample code, a QApplication must be initialized.
- >>> colormap={'name':'viridis',
- ... 'normalization':'log',
- ... 'vmin':1,
- ... 'vmax':100000,
- ... 'autoscale':False
- ... }
+ >>> colormap = Colormap(name='viridis',
+ ... norm='log',
+ ... vmin=1,
+ ... vmax=100000,
+ ... )
>>> colorscale = ColorScale(parent=None,
... colormap=colormap)
>>> colorscale.show()
@@ -423,83 +486,94 @@ class _ColorScale(qt.QWidget):
_NB_CONTROL_POINTS = 256
- def __init__(self, colormap, parent=None, margin=5):
+ def __init__(self, colormap, parent=None, margin=5, data=None):
qt.QWidget.__init__(self, parent)
- self.colormap = None
- self.setColormap(colormap)
+ self._colormap = None
+ self.margin = margin
+ self.setColormap(colormap, data)
self.setLayout(qt.QVBoxLayout())
- self.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
+ self.setSizePolicy(qt.QSizePolicy.Fixed, qt.QSizePolicy.Expanding)
# needed to get the mouse event without waiting for button click
self.setMouseTracking(True)
self.setMargin(margin)
self.setContentsMargins(0, 0, 0, 0)
- def setColormap(self, colormap):
+ self.setMinimumHeight(self._NB_CONTROL_POINTS // 2 + 2 * self.margin)
+ self.setFixedWidth(25)
+
+ def setColormap(self, colormap, data=None):
"""Set the new colormap to be displayed
:param dict colormap: the colormap to set
+ :param data: Optional data for which to compute colormap range.
"""
- if colormap is None:
- return
+ self._colormap = colormap
+ self.setEnabled(colormap is not None)
- if colormap['normalization'] not in ('log', 'linear'):
- raise ValueError("Unrecognized normalization, should be 'linear' or 'log'")
+ if colormap is None:
+ self.vmin, self.vmax = None, None
+ else:
+ assert colormap.getNormalization() in Colormap.Colormap.NORMALIZATIONS
+ self.vmin, self.vmax = self._colormap.getColormapRange(data=data)
+ self._updateColorGradient()
+ self.update()
- if colormap['normalization'] is 'log':
- if not (colormap['vmin'] > 0 and colormap['vmax'] > 0):
- raise ValueError('vmin and vmax should be positives')
- self.colormap = colormap
- self._computeColorPoints()
+ def getColormap(self):
+ """Returns the colormap
- def _computeColorPoints(self):
- """Compute the color points for the gradient
+ :rtype: :class:`.Colormap`
"""
- if self.colormap is None:
+ return None if self._colormap is None else self._colormap
+
+ def _updateColorGradient(self):
+ """Compute the color gradient"""
+ colormap = self.getColormap()
+ if colormap is None:
return
- vmin = self.colormap['vmin']
- vmax = self.colormap['vmax']
- steps = (vmax - vmin)/float(_ColorScale._NB_CONTROL_POINTS)
- self.ctrPoints = numpy.arange(vmin, vmax, steps)
- self.colorsCtrPts = Colors.applyColormapToData(self.ctrPoints,
- name=self.colormap['name'],
- normalization='linear',
- autoscale=self.colormap['autoscale'],
- vmin=vmin,
- vmax=vmax)
+ indices = numpy.linspace(0., 1., self._NB_CONTROL_POINTS)
+ colormapDisp = Colormap.Colormap(name=colormap.getName(),
+ normalization=Colormap.Colormap.LINEAR,
+ vmin=None,
+ vmax=None,
+ colors=colormap.getColormapLUT())
+ colors = colormapDisp.applyToData(indices)
+ self._gradient = qt.QLinearGradient(0, 1, 0, 0)
+ self._gradient.setCoordinateMode(qt.QGradient.StretchToDeviceMode)
+ self._gradient.setStops(
+ [(i, qt.QColor(*color)) for i, color in zip(indices, colors)]
+ )
def paintEvent(self, event):
""""""
- qt.QWidget.paintEvent(self, event)
- if self.colormap is None:
- return
-
- vmin = self.colormap['vmin']
- vmax = self.colormap['vmax']
-
painter = qt.QPainter(self)
- gradient = qt.QLinearGradient(0, 0, 0, self.rect().height() - 2*self.margin)
- for iPt, pt in enumerate(self.ctrPoints):
- colormapPosition = 1 - (pt-vmin) / (vmax-vmin)
- assert(colormapPosition >= 0.0)
- assert(colormapPosition <= 1.0)
- gradient.setColorAt(colormapPosition, qt.QColor(*(self.colorsCtrPts[iPt])))
+ if self.getColormap() is not None:
+ painter.setBrush(self._gradient)
+ penColor = self.palette().color(qt.QPalette.Active,
+ qt.QPalette.Foreground)
+ else:
+ penColor = self.palette().color(qt.QPalette.Disabled,
+ qt.QPalette.Foreground)
+ painter.setPen(penColor)
- painter.setBrush(gradient)
- painter.drawRect(
- qt.QRect(0, self.margin, self.width(), self.height() - 2.*self.margin))
+ painter.drawRect(qt.QRect(
+ 0,
+ self.margin,
+ self.width() - 1.,
+ self.height() - 2. * self.margin - 1.))
def mouseMoveEvent(self, event):
- """"""
- self.setToolTip(str(self.getValueFromRelativePosition(self._getRelativePosition(event.y()))))
+ tooltip = str(self.getValueFromRelativePosition(
+ self._getRelativePosition(event.y())))
+ qt.QToolTip.showText(event.globalPos(), tooltip, self)
super(_ColorScale, self).mouseMoveEvent(event)
def _getRelativePosition(self, yPixel):
"""yPixel : pixel position into _ColorScale widget reference
"""
# widgets are bottom-top referencial but we display in top-bottom referential
- return 1 - float(yPixel)/float(self.height() - 2*self.margin)
+ return 1. - (yPixel - self.margin) / float(self.height() - 2 * self.margin)
def getValueFromRelativePosition(self, value):
"""Return the value in the colorMap from a relative position in the
@@ -508,17 +582,22 @@ class _ColorScale(qt.QWidget):
:param value: float value in [0, 1]
:return: the value in [colormap['vmin'], colormap['vmax']]
"""
+ colormap = self.getColormap()
+ if colormap is None:
+ return
+
value = max(0.0, value)
value = min(value, 1.0)
- vmin = self.colormap['vmin']
- vmax = self.colormap['vmax']
- if self.colormap['normalization'] is 'linear':
+
+ vmin = self.vmin
+ vmax = self.vmax
+ if colormap.getNormalization() == Colormap.Colormap.LINEAR:
return vmin + (vmax - vmin) * value
- elif self.colormap['normalization'] is 'log':
+ elif colormap.getNormalization() == Colormap.Colormap.LOGARITHM:
rpos = (numpy.log10(vmax) - numpy.log10(vmin)) * value + numpy.log10(vmin)
return numpy.power(10., rpos)
else:
- err = "normalization type (%s) is not managed by the _ColorScale Widget" % self.colormap['normalization']
+ err = "normalization type (%s) is not managed by the _ColorScale Widget" % colormap['normalization']
raise ValueError(err)
def setMargin(self, margin):
@@ -529,6 +608,7 @@ class _ColorScale(qt.QWidget):
:param int margin: the margin to apply on the top and bottom.
"""
self.margin = margin
+ self.update()
class _TickBar(qt.QWidget):
@@ -536,7 +616,7 @@ class _TickBar(qt.QWidget):
To run the following sample code, a QApplication must be initialized.
- >>> bar = TickBar(1, 1000, norm='log', parent=None, displayValues=True)
+ >>> bar = _TickBar(1, 1000, norm='log', parent=None, displayValues=True)
>>> bar.show()
.. image:: img/tickbar.png
@@ -569,24 +649,19 @@ class _TickBar(qt.QWidget):
def __init__(self, vmin, vmax, norm, parent=None, displayValues=True,
nticks=None, margin=5):
super(_TickBar, self).__init__(parent)
+ self.margin = margin
+ self._nticks = None
+ self.ticks = ()
+ self.subTicks = ()
self._forcedDisplayType = None
self.ticksDensity = _TickBar.DEFAULT_TICK_DENSITY
self._vmin = vmin
self._vmax = vmax
- # TODO : should be grouped into a global function, called by all
- # logScale displayer to make sure we have the same behavior everywhere
- if self._vmin < 1. or self._vmax < 1.:
- _logger.warning(
- 'Log colormap with bound <= 1: changing bounds.')
- self._vmin, self._vmax = 1., 10.
-
self._norm = norm
self.displayValues = displayValues
self.setTicksNumber(nticks)
- self.setMargin(margin)
- self.setLayout(qt.QVBoxLayout())
self.setMargin(margin)
self.setContentsMargins(0, 0, 0, 0)
@@ -597,8 +672,8 @@ class _TickBar(qt.QWidget):
self._resetWidth()
def _resetWidth(self):
- self.width = _TickBar._WIDTH_DISP_VAL if self.displayValues else _TickBar._WIDTH_NO_DISP_VAL
- self.setFixedWidth(self.width)
+ width = self._WIDTH_DISP_VAL if self.displayValues else self._WIDTH_NO_DISP_VAL
+ self.setFixedWidth(width)
def update(self, vmin, vmax, norm):
self._vmin = vmin
@@ -623,7 +698,6 @@ class _TickBar(qt.QWidget):
optimal number of ticks from the tick density.
"""
self._nticks = nticks
- self.ticks = None
self.computeTicks()
qt.QWidget.update(self)
@@ -644,9 +718,13 @@ class _TickBar(qt.QWidget):
if nticks is None:
nticks = self._getOptimalNbTicks()
- if self._norm == 'log':
+ if self._vmin == self._vmax:
+ # No range: no ticks
+ self.ticks = ()
+ self.subTicks = ()
+ elif self._norm == Colormap.Colormap.LOGARITHM:
self._computeTicksLog(nticks)
- elif self._norm == 'linear':
+ elif self._norm == Colormap.Colormap.LINEAR:
self._computeTicksLin(nticks)
else:
err = 'TickBar - Wrong normalization %s' % self._norm
@@ -693,22 +771,19 @@ class _TickBar(qt.QWidget):
painter.setFont(font)
# paint ticks
- if self.ticks is not None:
- for val in self.ticks:
- self._paintTick(val, painter, majorTick=True)
-
- # paint subticks
- for val in self.subTicks:
- self._paintTick(val, painter, majorTick=False)
+ for val in self.ticks:
+ self._paintTick(val, painter, majorTick=True)
- qt.QWidget.paintEvent(self, event)
+ # paint subticks
+ for val in self.subTicks:
+ self._paintTick(val, painter, majorTick=False)
def _getRelativePosition(self, val):
"""Return the relative position of val according to min and max value
"""
- if self._norm == 'linear':
+ if self._norm == Colormap.Colormap.LINEAR:
return 1 - (val - self._vmin) / (self._vmax - self._vmin)
- elif self._norm == 'log':
+ elif self._norm == Colormap.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')
@@ -720,7 +795,7 @@ class _TickBar(qt.QWidget):
with a smaller width
"""
fm = qt.QFontMetrics(painter.font())
- viewportHeight = self.rect().height() - self.margin * 2
+ viewportHeight = self.rect().height() - self.margin * 2 - 1
relativePos = self._getRelativePosition(val)
height = viewportHeight * relativePos
height += self.margin
@@ -728,9 +803,9 @@ class _TickBar(qt.QWidget):
if majorTick is False:
lineWidth /= 2
- painter.drawLine(qt.QLine(self.width - lineWidth,
+ painter.drawLine(qt.QLine(self.width() - lineWidth,
height,
- self.width,
+ self.width(),
height))
if self.displayValues and majorTick is True:
@@ -774,7 +849,6 @@ class _TickBar(qt.QWidget):
:param QFont font: the font we want want to use durint the painting
"""
- assert(type(self._vmin) == type(self._vmax))
form = self._getStandardFormat()
fm = qt.QFontMetrics(font)