diff options
author | Picca Frédéric-Emmanuel <picca@debian.org> | 2017-10-07 07:59:01 +0200 |
---|---|---|
committer | Picca Frédéric-Emmanuel <picca@debian.org> | 2017-10-07 07:59:01 +0200 |
commit | bfa4dba15485b4192f8bbe13345e9658c97ecf76 (patch) | |
tree | fb9c6e5860881fbde902f7cbdbd41dc4a3a9fb5d /silx/gui/plot/ColorBar.py | |
parent | f7bdc2acff3c13a6d632c28c4569690ab106eed7 (diff) |
New upstream version 0.6.0+dfsg
Diffstat (limited to 'silx/gui/plot/ColorBar.py')
-rw-r--r-- | silx/gui/plot/ColorBar.py | 456 |
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) |