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/ImageView.py | |
parent | f7bdc2acff3c13a6d632c28c4569690ab106eed7 (diff) |
New upstream version 0.6.0+dfsg
Diffstat (limited to 'silx/gui/plot/ImageView.py')
-rw-r--r-- | silx/gui/plot/ImageView.py | 157 |
1 files changed, 82 insertions, 75 deletions
diff --git a/silx/gui/plot/ImageView.py b/silx/gui/plot/ImageView.py index 780215e..803a2fc 100644 --- a/silx/gui/plot/ImageView.py +++ b/silx/gui/plot/ImageView.py @@ -34,12 +34,7 @@ Basic usage of :class:`ImageView` is through the following methods: default colormap to use and update the currently displayed image. - :meth:`ImageView.setImage` to update the displayed image. -The :class:`ImageView` uses :class:`PlotWindow` and also -exposes :class:`silx.gui.plot.Plot` API for further control -(plot title, axes labels, adding other images, ...). - -For an example of use, see the implementation of :class:`ImageViewMainWindow`, -and `example/imageview.py`. +For an example of use, see `imageview.py` in :ref:`sample-code`. """ from __future__ import division @@ -47,7 +42,7 @@ from __future__ import division __authors__ = ["T. Vincent"] __license__ = "MIT" -__date__ = "13/10/2016" +__date__ = "17/08/2017" import logging @@ -55,7 +50,8 @@ import numpy from .. import qt -from . import items, PlotWindow, PlotWidget, PlotActions +from . import items, PlotWindow, PlotWidget, actions +from .Colormap import Colormap from .Colors import cursorColorForColormap from .PlotTools import LimitsToolBar from .Profile import ProfileToolBar @@ -253,9 +249,13 @@ class ImageView(PlotWindow): Use :meth:`setImage` to control the displayed image. This class also provides the :class:`silx.gui.plot.Plot` API. + The :class:`ImageView` inherits from :class:`.PlotWindow` (which provides + the toolbars) and also exposes :class:`.PlotWidget` API for further + plot control (plot title, axes labels, aspect ratio, ...). + :param parent: The parent of this widget or None. :param backend: The backend to use for the plot (default: matplotlib). - See :class:`.Plot` for the list of supported backend. + See :class:`.PlotWidget` for the list of supported backend. :type backend: str or :class:`BackendBase.BackendBase` """ @@ -318,7 +318,7 @@ class ImageView(PlotWindow): self._histoHPlot = PlotWidget(backend=backend) self._histoHPlot.setInteractiveMode('zoom') - self._histoHPlot.setCallback(self._histoHPlotCB) + self._histoHPlot.sigPlotSignal.connect(self._histoHPlotCB) self._histoHPlot.getWidgetHandle().sizeHint = sizeHint self._histoHPlot.getWidgetHandle().minimumSizeHint = sizeHint @@ -326,39 +326,39 @@ class ImageView(PlotWindow): self.setInteractiveMode('zoom') # Color set in setColormap self.sigPlotSignal.connect(self._imagePlotCB) - self.sigSetYAxisInverted.connect(self._updateYAxisInverted) + self.getYAxis().sigInvertedChanged.connect(self._updateYAxisInverted) self.sigActiveImageChanged.connect(self._activeImageChangedSlot) self._histoVPlot = PlotWidget(backend=backend) self._histoVPlot.setInteractiveMode('zoom') - self._histoVPlot.setCallback(self._histoVPlotCB) + self._histoVPlot.sigPlotSignal.connect(self._histoVPlotCB) self._histoVPlot.getWidgetHandle().sizeHint = sizeHint self._histoVPlot.getWidgetHandle().minimumSizeHint = sizeHint self._radarView = RadarView() self._radarView.visibleRectDragged.connect(self._radarViewCB) - self._layout = qt.QGridLayout() - self._layout.addWidget(self.getWidgetHandle(), 0, 0) - self._layout.addWidget(self._histoVPlot.getWidgetHandle(), 0, 1) - self._layout.addWidget(self._histoHPlot.getWidgetHandle(), 1, 0) - self._layout.addWidget(self._radarView, 1, 1) + layout = qt.QGridLayout() + layout.addWidget(self.getWidgetHandle(), 0, 0) + layout.addWidget(self._histoVPlot.getWidgetHandle(), 0, 1) + layout.addWidget(self._histoHPlot.getWidgetHandle(), 1, 0) + layout.addWidget(self._radarView, 1, 1) - self._layout.setColumnMinimumWidth(0, self.IMAGE_MIN_SIZE) - self._layout.setColumnStretch(0, 1) - self._layout.setColumnMinimumWidth(1, self.HISTOGRAMS_HEIGHT) - self._layout.setColumnStretch(1, 0) + layout.setColumnMinimumWidth(0, self.IMAGE_MIN_SIZE) + layout.setColumnStretch(0, 1) + layout.setColumnMinimumWidth(1, self.HISTOGRAMS_HEIGHT) + layout.setColumnStretch(1, 0) - self._layout.setRowMinimumHeight(0, self.IMAGE_MIN_SIZE) - self._layout.setRowStretch(0, 1) - self._layout.setRowMinimumHeight(1, self.HISTOGRAMS_HEIGHT) - self._layout.setRowStretch(1, 0) + layout.setRowMinimumHeight(0, self.IMAGE_MIN_SIZE) + layout.setRowStretch(0, 1) + layout.setRowMinimumHeight(1, self.HISTOGRAMS_HEIGHT) + layout.setRowStretch(1, 0) - self._layout.setSpacing(0) - self._layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + layout.setContentsMargins(0, 0, 0, 0) centralWidget = qt.QWidget() - centralWidget.setLayout(self._layout) + centralWidget.setLayout(layout) self.setCentralWidget(centralWidget) def _dirtyCache(self): @@ -376,8 +376,8 @@ class ImageView(PlotWindow): scale = activeImage.getScale() height, width = data.shape - xMin, xMax = self.getGraphXLimits() - yMin, yMax = self.getGraphYLimits() + xMin, xMax = self.getXAxis().getLimits() + yMin, yMax = self.getYAxis().getLimits() # Convert plot area limits to image coordinates # and work in image coordinates (i.e., in pixels) @@ -440,8 +440,8 @@ class ImageView(PlotWindow): vOffset = 0.1 * (vMax - vMin) if vOffset == 0.: vOffset = 1. - self._histoHPlot.setGraphYLimits(vMin - vOffset, - vMax + vOffset) + self._histoHPlot.getYAxis().setLimits(vMin - vOffset, + vMax + vOffset) coords = numpy.arange(2 * histoVVisibleData.size) yCoords = (coords + 1) // 2 + subsetYMin @@ -458,8 +458,8 @@ class ImageView(PlotWindow): vOffset = 0.1 * (vMax - vMin) if vOffset == 0.: vOffset = 1. - self._histoVPlot.setGraphXLimits(vMin - vOffset, - vMax + vOffset) + self._histoVPlot.getXAxis().setLimits(vMin - vOffset, + vMax + vOffset) else: self._dirtyCache() self._histoHPlot.remove(kind='curve') @@ -472,8 +472,8 @@ class ImageView(PlotWindow): Takes care of y coordinate conversion. """ - xMin, xMax = self.getGraphXLimits() - yMin, yMax = self.getGraphYLimits() + xMin, xMax = self.getXAxis().getLimits() + yMin, yMax = self.getYAxis().getLimits() self._radarView.setVisibleRect(xMin, yMin, xMax - xMin, yMax - yMin) # Plots event listeners @@ -499,6 +499,9 @@ class ImageView(PlotWindow): data[y][x]) elif eventDict['event'] == 'limitsChanged': + self._updateHistogramsLimits() + + def _updateHistogramsLimits(self): # Do not handle histograms limitsChanged while # updating their limits from here. self._updatingLimits = True @@ -506,15 +509,14 @@ class ImageView(PlotWindow): # Refresh histograms self._updateHistograms() - # could use eventDict['xdata'], eventDict['ydata'] instead - xMin, xMax = self.getGraphXLimits() - yMin, yMax = self.getGraphYLimits() + xMin, xMax = self.getXAxis().getLimits() + yMin, yMax = self.getYAxis().getLimits() # Set horizontal histo limits - self._histoHPlot.setGraphXLimits(xMin, xMax) + self._histoHPlot.getXAxis().setLimits(xMin, xMax) # Set vertical histo limits - self._histoVPlot.setGraphYLimits(yMin, yMax) + self._histoVPlot.getYAxis().setLimits(yMin, yMax) self._updateRadarView() @@ -542,9 +544,9 @@ class ImageView(PlotWindow): elif eventDict['event'] == 'limitsChanged': if (not self._updatingLimits and - eventDict['xdata'] != self.getGraphXLimits()): + eventDict['xdata'] != self.getXAxis().getLimits()): xMin, xMax = eventDict['xdata'] - self.setGraphXLimits(xMin, xMax) + self.getXAxis().setLimits(xMin, xMax) def _histoVPlotCB(self, eventDict): """Callback for vertical histogram plot events.""" @@ -568,9 +570,9 @@ class ImageView(PlotWindow): elif eventDict['event'] == 'limitsChanged': if (not self._updatingLimits and - eventDict['ydata'] != self.getGraphYLimits()): + eventDict['ydata'] != self.getYAxis().getLimits()): yMin, yMax = eventDict['ydata'] - self.setGraphYLimits(yMin, yMax) + self.getYAxis().setLimits(yMin, yMax) def _radarViewCB(self, left, top, width, height): """Slot for radar view visible rectangle changes.""" @@ -582,9 +584,9 @@ class ImageView(PlotWindow): """Sync image, vertical histogram and radar view axis orientation.""" if inverted is None: # Do not perform this when called from plot signal - inverted = self.isYAxisInverted() + inverted = self.getYAxis().isInverted() - self._histoVPlot.setYAxisInverted(inverted) + self._histoVPlot.getYAxis().setInverted(inverted) # Use scale to invert radarView # RadarView default Y direction is from top to bottom @@ -643,7 +645,7 @@ class ImageView(PlotWindow): self._radarView.visibleRectDragged.disconnect(self._radarViewCB) self._radarView = radarView self._radarView.visibleRectDragged.connect(self._radarViewCB) - self._layout.addWidget(self._radarView, 1, 1) + self.centralWidget().layout().addWidget(self._radarView, 1, 1) self._updateYAxisInverted() @@ -693,42 +695,46 @@ class ImageView(PlotWindow): :param numpy.ndarray colors: Only used if name is None. Custom colormap colors as Nx3 or Nx4 RGB or RGBA arrays """ - cmapDict = self.getDefaultColormap() + cmap = self.getDefaultColormap() + + if isinstance(colormap, Colormap): + # Replace colormap + cmap = colormap + + self.setDefaultColormap(cmap) + + # Update active image colormap + activeImage = self.getActiveImage() + if isinstance(activeImage, items.ColormapMixIn): + activeImage.setColormap(cmap) - if isinstance(colormap, dict): + elif isinstance(colormap, dict): # Support colormap parameter as a dict assert normalization is None assert autoscale is None assert vmin is None assert vmax is None assert colors is None - for key, value in colormap.items(): - cmapDict[key] = value + cmap._setFromDict(colormap) else: if colormap is not None: - cmapDict['name'] = colormap + cmap.setName(colormap) if normalization is not None: - cmapDict['normalization'] = normalization - if autoscale is not None: - cmapDict['autoscale'] = autoscale - if vmin is not None: - cmapDict['vmin'] = vmin - if vmax is not None: - cmapDict['vmax'] = vmax + cmap.setNormalization(normalization) + if autoscale: + cmap.setVRange(None, None) + else: + if vmin is not None: + cmap.setVMin(vmin) + if vmax is not None: + cmap.setVMax(vmax) if colors is not None: - cmapDict['colors'] = colors + cmap.setColormapLUT(colors) - cursorColor = cursorColorForColormap(cmapDict['name']) + cursorColor = cursorColorForColormap(cmap.getName()) self.setInteractiveMode('zoom', color=cursorColor) - self.setDefaultColormap(cmapDict) - - # Update active image colormap - activeImage = self.getActiveImage() - if isinstance(activeImage, items.ColormapMixIn): - activeImage.setColormap(self.getColormap()) - def setImage(self, image, origin=(0, 0), scale=(1., 1.), copy=True, reset=True): """Set the image to display. @@ -768,7 +774,7 @@ class ImageView(PlotWindow): legend=self._imageLegend, origin=origin, scale=scale, colormap=self.getColormap(), - replace=False) + replace=False, resetzoom=False) self.setActiveImage(self._imageLegend) self._updateHistograms() @@ -779,6 +785,8 @@ class ImageView(PlotWindow): if reset: self.resetZoom() + else: + self._updateHistogramsLimits() # ImageViewMainWindow ######################################################### @@ -793,8 +801,8 @@ class ImageViewMainWindow(ImageView): super(ImageViewMainWindow, self).__init__(parent, backend) self.setWindowFlags(qt.Qt.Window) - self.setGraphXLabel('X') - self.setGraphYLabel('Y') + self.getXAxis().setLabel('X') + self.getYAxis().setLabel('Y') self.setGraphTitle('Image') # Add toolbars and status bar @@ -814,11 +822,10 @@ class ImageViewMainWindow(ImageView): menu.addSeparator() menu.addAction(self.resetZoomAction) menu.addAction(self.colormapAction) - menu.addAction(PlotActions.KeepAspectRatioAction(self, self)) - menu.addAction(PlotActions.YAxisInvertedAction(self, self)) + menu.addAction(actions.control.KeepAspectRatioAction(self, self)) + menu.addAction(actions.control.YAxisInvertedAction(self, self)) menu = self.menuBar().addMenu('Profile') - menu.addAction(self.profile.browseAction) menu.addAction(self.profile.hLineAction) menu.addAction(self.profile.vLineAction) menu.addAction(self.profile.lineAction) |