diff options
author | Picca Frédéric-Emmanuel <picca@debian.org> | 2017-11-25 16:55:20 +0100 |
---|---|---|
committer | Picca Frédéric-Emmanuel <picca@debian.org> | 2017-11-25 16:55:20 +0100 |
commit | e19c96eff0c310c06c4f268c8b80cb33bd08996f (patch) | |
tree | f2b4a365ed899be04766f3937bcc2d58d22be065 /silx/gui/plot/backends | |
parent | bfa4dba15485b4192f8bbe13345e9658c97ecf76 (diff) |
New upstream version 0.6.1+dfsg
Diffstat (limited to 'silx/gui/plot/backends')
-rw-r--r-- | silx/gui/plot/backends/BackendMatplotlib.py | 134 |
1 files changed, 93 insertions, 41 deletions
diff --git a/silx/gui/plot/backends/BackendMatplotlib.py b/silx/gui/plot/backends/BackendMatplotlib.py index 59e753e..b41f20e 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__ = "16/08/2017" +__date__ = "18/10/2017" import logging @@ -306,6 +306,14 @@ class BackendMatplotlib(BackendBase.BackendBase): ystep = 1 if scale[1] >= 0. else -1 data = data[::ystep, ::xstep] + if matplotlib.__version__ < "2.1": + # matplotlib 1.4.2 do not support float128 + dtype = data.dtype + if dtype.kind == "f" and dtype.itemsize >= 16: + _logger.warning("Your matplotlib version do not support " + "float128. Data converted to floa64.") + data = data.astype(numpy.float64) + image.set_data(data) self.ax.add_artist(image) @@ -602,16 +610,32 @@ class BackendMatplotlib(BackendBase.BackendBase): # Graph axes def setXAxisLogarithmic(self, flag): - if matplotlib.__version__ >= "2.0.0": - self.ax.cla() - self.ax2.cla() + # Workaround for matplotlib 2.1.0 when one tries to set an axis + # to log scale with both limits <= 0 + # In this case a draw with positive limits is needed first + if flag and matplotlib.__version__ >= '2.1.0': + xlim = self.ax.get_xlim() + if xlim[0] <= 0 and xlim[1] <= 0: + self.ax.set_xlim(1, 10) + self.draw() + 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() + # Workaround for matplotlib 2.1.0 when one tries to set an axis + # to log scale with both limits <= 0 + # In this case a draw with positive limits is needed first + if flag and matplotlib.__version__ >= '2.1.0': + redraw = False + for axis in (self.ax, self.ax2): + ylim = axis.get_ylim() + if ylim[0] <= 0 and ylim[1] <= 0: + axis.set_ylim(1, 10) + redraw = True + if redraw: + self.draw() + self.ax2.set_yscale('log' if flag else 'linear') self.ax.set_yscale('log' if flag else 'linear') @@ -700,12 +724,12 @@ class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): """Signal handling automatic asynchronous replot""" def __init__(self, plot, parent=None): - self._insideResizeEventMethod = False - BackendMatplotlib.__init__(self, plot, parent) FigureCanvasQTAgg.__init__(self, self.fig) self.setParent(parent) + self._limitsBeforeResize = None + FigureCanvasQTAgg.setSizePolicy( self, qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) FigureCanvasQTAgg.updateGeometry(self) @@ -806,55 +830,83 @@ class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib): # replot control def resizeEvent(self, event): - self._insideResizeEventMethod = True - # Need to dirty the whole plot on resize. - self._plot._setDirtyPlot() + # Store current limits + self._limitsBeforeResize = ( + self.ax.get_xbound(), self.ax.get_ybound(), self.ax2.get_ybound()) + FigureCanvasQTAgg.resizeEvent(self, event) - self._insideResizeEventMethod = False + if self.isKeepDataAspectRatio() or self._overlays or self._graphCursor: + # This is needed with matplotlib 1.5.x and 2.0.x + self._plot._setDirtyPlot() + + def _drawOverlays(self): + """Draw overlays if any.""" + if self._overlays or self._graphCursor: + # There is some overlays or crosshair + + # This assume that items are only on left/bottom Axes + for item in self._overlays: + self.ax.draw_artist(item) + + for item in self._graphCursor: + self.ax.draw_artist(item) 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() + """Overload draw + It performs a full redraw (including overlays) of the plot. + It also resets background and emit limits changed signal. + + This is directly called by matplotlib for widget resize. + """ + # Starting with mpl 2.1.0, toggling autoscale raises a ValueError + # in some situations. See #1081, #1136, #1163, + if matplotlib.__version__ >= "2.0.0": + try: + FigureCanvasQTAgg.draw(self) + except ValueError as err: + _logger.debug( + "ValueError caught while calling FigureCanvasQTAgg.draw: " + "'%s'", err) + else: FigureCanvasQTAgg.draw(self) - self._background = None # Any saved background is dirty - # Check if limits changed due to a resize of the widget + if self._overlays or self._graphCursor: + # Save background + self._background = self.copy_from_bbox(self.fig.bbox) + else: + self._background = None # Reset background + + # Check if limits changed due to a resize of the widget + if self._limitsBeforeResize is not None: + xLimits, yLimits, yRightLimits = self._limitsBeforeResize + self._limitsBeforeResize = None + 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 + self._plot.getYAxis(axis='right')._emitLimitsChanged() - # Specific case: called from resizeEvent: - # avoid store/restore background, just draw the overlay - if not self._insideResizeEventMethod: - if self._background is None: # First store the background - self._background = self.copy_from_bbox(self.fig.bbox) + self._drawOverlays() - self.restore_region(self._background) - - # This assume that items are only on left/bottom Axes - for item in self._overlays: - self.ax.draw_artist(item) + def replot(self): + BackendMatplotlib.replot(self) - for item in self._graphCursor: - self.ax.draw_artist(item) + dirtyFlag = self._plot._getDirtyPlot() + if dirtyFlag == 'overlay': + # Only redraw overlays using fast rendering path + if self._background is None: + self._background = self.copy_from_bbox(self.fig.bbox) + self.restore_region(self._background) + self._drawOverlays() self.blit(self.fig.bbox) - def replot(self): - BackendMatplotlib.replot(self) - self.draw() + elif dirtyFlag: # Need full redraw + self.draw() + # cursor |