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/backends/BackendMatplotlib.py | |
parent | f7bdc2acff3c13a6d632c28c4569690ab106eed7 (diff) |
New upstream version 0.6.0+dfsg
Diffstat (limited to 'silx/gui/plot/backends/BackendMatplotlib.py')
-rw-r--r-- | silx/gui/plot/backends/BackendMatplotlib.py | 104 |
1 files changed, 78 insertions, 26 deletions
diff --git a/silx/gui/plot/backends/BackendMatplotlib.py b/silx/gui/plot/backends/BackendMatplotlib.py index f9e60d5..59e753e 100644 --- a/silx/gui/plot/backends/BackendMatplotlib.py +++ b/silx/gui/plot/backends/BackendMatplotlib.py @@ -28,7 +28,7 @@ from __future__ import division __authors__ = ["V.A. Sole", "T. Vincent, H. Payno"] __license__ = "MIT" -__date__ = "18/01/2017" +__date__ = "16/08/2017" import logging @@ -41,7 +41,9 @@ _logger = logging.getLogger(__name__) from ... import qt -from ._matplotlib import FigureCanvasQTAgg +# First of all init matplotlib and set its backend +from ..matplotlib import Colormap as MPLColormap +from ..matplotlib import FigureCanvasQTAgg import matplotlib from matplotlib.container import Container from matplotlib.figure import Figure @@ -51,9 +53,8 @@ from matplotlib.backend_bases import MouseEvent from matplotlib.lines import Line2D from matplotlib.collections import PathCollection, LineCollection -from .ModestImage import ModestImage +from ..matplotlib.ModestImage import ModestImage from . import BackendBase -from .. import Colors from .._utils import FLOAT32_MINPOS @@ -75,6 +76,7 @@ class BackendMatplotlib(BackendBase.BackendBase): # This attribute is used to ensure consistent values returned # when getting the limits at the expense of a replot self._dirtyLimits = True + self._axesDisplayed = True self.fig = Figure() self.fig.set_facecolor("w") @@ -83,6 +85,16 @@ class BackendMatplotlib(BackendBase.BackendBase): self.ax2 = self.ax.twinx() self.ax2.set_label("right") + # disable the use of offsets + try: + self.ax.get_yaxis().get_major_formatter().set_useOffset(False) + self.ax.get_xaxis().get_major_formatter().set_useOffset(False) + self.ax2.get_yaxis().get_major_formatter().set_useOffset(False) + self.ax2.get_xaxis().get_major_formatter().set_useOffset(False) + except: + _logger.warning('Cannot disabled axes offsets in %s ' \ + % matplotlib.__version__) + # critical for picking!!!! self.ax2.set_zorder(0) self.ax2.set_autoscaley_on(True) @@ -102,10 +114,6 @@ class BackendMatplotlib(BackendBase.BackendBase): self._graphCursor = tuple() self.matplotlibVersion = matplotlib.__version__ - self.setGraphXLimits(0., 100.) - self.setGraphYLimits(0., 100., axis='right') - self.setGraphYLimits(0., 100., axis='left') - self._enableAxis('right', False) # Add methods @@ -142,7 +150,7 @@ class BackendMatplotlib(BackendBase.BackendBase): errorbarColor = color # On Debian 7 at least, Nx1 array yerr does not seems supported - if (yerror is not None and yerror.ndim == 2 and + if (isinstance(yerror, numpy.ndarray) and yerror.ndim == 2 and yerror.shape[1] == 1 and len(x) != 1): yerror = numpy.ravel(yerror) @@ -226,17 +234,17 @@ class BackendMatplotlib(BackendBase.BackendBase): # Add support for transparent colormap for uint8 data with # colormap with 256 colors, linear norm, [0, 255] range if matplotlib.__version__ < '1.2.0': - if (len(data.shape) == 2 and colormap['name'] is None and - 'colors' in colormap): - colors = numpy.array(colormap['colors'], copy=False) + if (len(data.shape) == 2 and colormap.getName() is None and + colormap.getColormapLUT() is not None): + colors = colormap.getColormapLUT() if (colors.shape[-1] == 4 and not numpy.all(numpy.equal(colors[3], 255))): # This is a transparent colormap if (colors.shape == (256, 4) and - colormap['normalization'] == 'linear' and - not colormap['autoscale'] and - colormap['vmin'] == 0 and - colormap['vmax'] == 255 and + colormap.getNormalization() == 'linear' and + not colormap.isAutoscale() and + colormap.getVMin() == 0 and + colormap.getVMax() == 255 and data.dtype == numpy.uint8): # Supported case, convert data to RGBA data = colors[data.reshape(-1)].reshape( @@ -264,7 +272,7 @@ class BackendMatplotlib(BackendBase.BackendBase): else: # Convert colormap argument to matplotlib colormap - scalarMappable = Colors.getMPLScalarMappable(colormap, data) + scalarMappable = MPLColormap.getScalarMappable(colormap, data) # try as data image = imageClass(self.ax, @@ -440,7 +448,10 @@ class BackendMatplotlib(BackendBase.BackendBase): item._infoText.remove() item._infoText = None self._overlays.discard(item) - item.remove() + try: + item.remove() + except ValueError: + pass # Already removed e.g., in set[X|Y]AxisLogarithmic # Interaction methods @@ -591,10 +602,16 @@ class BackendMatplotlib(BackendBase.BackendBase): # Graph axes def setXAxisLogarithmic(self, flag): + if matplotlib.__version__ >= "2.0.0": + self.ax.cla() + self.ax2.cla() self.ax2.set_xscale('log' if flag else 'linear') self.ax.set_xscale('log' if flag else 'linear') def setYAxisLogarithmic(self, flag): + if matplotlib.__version__ >= "2.0.0": + self.ax.cla() + self.ax2.cla() self.ax2.set_yscale('log' if flag else 'linear') self.ax.set_yscale('log' if flag else 'linear') @@ -649,6 +666,29 @@ class BackendMatplotlib(BackendBase.BackendBase): return (bbox.bounds[0] * dpi, bbox.bounds[1] * dpi, bbox.bounds[2] * dpi, bbox.bounds[3] * dpi) + def setAxesDisplayed(self, displayed): + """Display or not the axes. + + :param bool displayed: If `True` axes are displayed. If `False` axes + are not anymore visible and the margin used for them is removed. + """ + BackendBase.BackendBase.setAxesDisplayed(self, displayed) + if displayed: + # show axes and viewbox rect + self.ax.set_axis_on() + self.ax2.set_axis_on() + # set the default margins + self.ax.set_position([.15, .15, .75, .75]) + self.ax2.set_position([.15, .15, .75, .75]) + else: + # hide axes and viewbox rect + self.ax.set_axis_off() + self.ax2.set_axis_off() + # remove external margins + self.ax.set_position([0, 0, 1, 1]) + self.ax2.set_position([0, 0, 1, 1]) + self._plot._setDirtyPlot() + class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): """QWidget matplotlib backend using a QtAgg canvas. @@ -682,6 +722,11 @@ class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): self.mpl_connect('motion_notify_event', self._onMouseMove) self.mpl_connect('scroll_event', self._onMouseWheel) + def contextMenuEvent(self, event): + """Override QWidget.contextMenuEvent to implement the context menu""" + # Makes sure it is overridden (issue with PySide) + BackendBase.BackendBase.contextMenuEvent(self, event) + def postRedisplay(self): self._sigPostRedisplay.emit() @@ -738,18 +783,12 @@ class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): self._picked.append({'kind': 'image', 'legend': label[9:]}) else: # it's a curve, item have no picker for now - if isinstance(event.artist, PathCollection): - data = event.artist.get_offsets()[event.ind, :] - xdata, ydata = data[:, 0], data[:, 1] - elif isinstance(event.artist, Line2D): - xdata = event.artist.get_xdata()[event.ind] - ydata = event.artist.get_ydata()[event.ind] - else: + if not isinstance(event.artist, (PathCollection, Line2D)): _logger.info('Unsupported artist, ignored') return self._picked.append({'kind': 'curve', 'legend': label, - 'xdata': xdata, 'ydata': ydata}) + 'indices': event.ind}) def pickItems(self, x, y): self._picked = [] @@ -776,9 +815,22 @@ class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): def draw(self): """Override canvas draw method to support faster draw of overlays.""" if self._plot._getDirtyPlot(): # Need a full redraw + # Store previous limits + xLimits = self.ax.get_xbound() + yLimits = self.ax.get_ybound() + yRightLimits = self.ax2.get_ybound() + FigureCanvasQTAgg.draw(self) self._background = None # Any saved background is dirty + # Check if limits changed due to a resize of the widget + if xLimits != self.ax.get_xbound(): + self._plot.getXAxis()._emitLimitsChanged() + if yLimits != self.ax.get_ybound(): + self._plot.getYAxis(axis='left')._emitLimitsChanged() + if yRightLimits != self.ax2.get_ybound(): + self._plot.getYAxis(axis='left')._emitLimitsChanged() + if (self._overlays or self._graphCursor or self._plot._getDirtyPlot() == 'overlay'): # There are overlays or crosshair, or they is just no more overlays |