diff options
Diffstat (limited to 'silx/gui/plot/PlotWidget.py')
-rw-r--r-- | silx/gui/plot/PlotWidget.py | 130 |
1 files changed, 79 insertions, 51 deletions
diff --git a/silx/gui/plot/PlotWidget.py b/silx/gui/plot/PlotWidget.py index 8fd5a5e..5bf2b59 100644 --- a/silx/gui/plot/PlotWidget.py +++ b/silx/gui/plot/PlotWidget.py @@ -175,7 +175,7 @@ from __future__ import division __authors__ = ["V.A. Sole", "T. Vincent"] __license__ = "MIT" -__date__ = "30/08/2017" +__date__ = "18/10/2017" from collections import OrderedDict, namedtuple @@ -612,8 +612,7 @@ class PlotWidget(qt.QMainWindow): if (kind == 'curve' and not self.getAllCurves(just_legend=True, withhidden=True)): - self._colorIndex = 0 - self._styleIndex = 0 + self._resetColorAndStyle() self.notify('contentChanged', action='remove', kind=kind, legend=legend) @@ -780,6 +779,9 @@ class PlotWidget(qt.QMainWindow): # Check if curve was previously active wasActive = self.getActiveCurve(just_legend=True) == legend + if replace: + self._resetColorAndStyle() + # Create/Update curve object curve = self.getCurve(legend) mustBeAdded = curve is None @@ -2319,7 +2321,7 @@ class PlotWidget(qt.QMainWindow): flag = bool(flag) self._backend.setKeepDataAspectRatio(flag=flag) self._setDirtyPlot() - self.resetZoom() + self._forceResetZoom() self.notify('setKeepDataAspectRatio', state=flag) def getGraphGrid(self): @@ -2431,6 +2433,10 @@ class PlotWidget(qt.QMainWindow): """ return Colormap.getSupportedColormaps() + def _resetColorAndStyle(self): + self._colorIndex = 0 + self._styleIndex = 0 + def _getColorAndStyle(self): color = self.colorList[self._colorIndex] style = self._styleList[self._styleIndex] @@ -2614,6 +2620,66 @@ class PlotWidget(qt.QMainWindow): self._backend.replot() self._dirty = False # reset dirty flag + def _forceResetZoom(self, dataMargins=None): + """Reset the plot limits to the bounds of the data and redraw the plot. + + This method forces a reset zoom and does not check axis autoscale. + + Extra margins can be added around the data inside the plot area + (see :meth:`setDataMargins`). + Margins are given as one ratio of the data range per limit of the + data (xMin, xMax, yMin and yMax limits). + For log scale, extra margins are applied in log10 of the data. + + :param dataMargins: Ratios of margins to add around the data inside + the plot area for each side (default: no margins). + :type dataMargins: A 4-tuple of float as (xMin, xMax, yMin, yMax). + """ + if dataMargins is None: + dataMargins = self._defaultDataMargins + + # Get data range + ranges = self.getDataRange() + xmin, xmax = (1., 100.) if ranges.x is None else ranges.x + ymin, ymax = (1., 100.) if ranges.y is None else ranges.y + if ranges.yright is None: + ymin2, ymax2 = None, None + else: + ymin2, ymax2 = ranges.yright + + # Add margins around data inside the plot area + newLimits = list(_utils.addMarginsToLimits( + dataMargins, + self._xAxis._isLogarithmic(), + self._yAxis._isLogarithmic(), + xmin, xmax, ymin, ymax, ymin2, ymax2)) + + if self.isKeepDataAspectRatio(): + # Use limits with margins to keep ratio + xmin, xmax, ymin, ymax = newLimits[:4] + + # Compute bbox wth figure aspect ratio + plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:] + plotRatio = plotHeight / plotWidth + + if plotRatio > 0.: + dataRatio = (ymax - ymin) / (xmax - xmin) + if dataRatio < plotRatio: + # Increase y range + ycenter = 0.5 * (ymax + ymin) + yrange = (xmax - xmin) * plotRatio + newLimits[2] = ycenter - 0.5 * yrange + newLimits[3] = ycenter + 0.5 * yrange + + elif dataRatio > plotRatio: + # Increase x range + xcenter = 0.5 * (xmax + xmin) + xrange_ = (ymax - ymin) / plotRatio + newLimits[0] = xcenter - 0.5 * xrange_ + newLimits[1] = xcenter + 0.5 * xrange_ + + self.setLimits(*newLimits) + def resetZoom(self, dataMargins=None): """Reset the plot limits to the bounds of the data and redraw the plot. @@ -2631,9 +2697,6 @@ class PlotWidget(qt.QMainWindow): the plot area for each side (default: no margins). :type dataMargins: A 4-tuple of float as (xMin, xMax, yMin, yMax). """ - if dataMargins is None: - dataMargins = self._defaultDataMargins - xLimits = self._xAxis.getLimits() yLimits = self._yAxis.getLimits() y2Limits = self._yRightAxis.getLimits() @@ -2641,52 +2704,19 @@ class PlotWidget(qt.QMainWindow): xAuto = self._xAxis.isAutoScale() yAuto = self._yAxis.isAutoScale() + # With log axes, autoscale if limits are <= 0 + # This avoids issues with toggling log scale with matplotlib 2.1.0 + if self._xAxis.getScale() == self._xAxis.LOGARITHMIC and xLimits[0] <= 0: + xAuto = True + if self._yAxis.getScale() == self._yAxis.LOGARITHMIC and (yLimits[0] <= 0 or y2Limits[0] <= 0): + yAuto = True + if not xAuto and not yAuto: _logger.debug("Nothing to autoscale") else: # Some axes to autoscale + self._forceResetZoom(dataMargins=dataMargins) - # Get data range - ranges = self.getDataRange() - xmin, xmax = (1., 100.) if ranges.x is None else ranges.x - ymin, ymax = (1., 100.) if ranges.y is None else ranges.y - if ranges.yright is None: - ymin2, ymax2 = None, None - else: - ymin2, ymax2 = ranges.yright - - # Add margins around data inside the plot area - newLimits = list(_utils.addMarginsToLimits( - dataMargins, - self._xAxis._isLogarithmic(), - self._yAxis._isLogarithmic(), - xmin, xmax, ymin, ymax, ymin2, ymax2)) - - if self.isKeepDataAspectRatio(): - # Use limits with margins to keep ratio - xmin, xmax, ymin, ymax = newLimits[:4] - - # Compute bbox wth figure aspect ratio - plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:] - plotRatio = plotHeight / plotWidth - - if plotRatio > 0.: - dataRatio = (ymax - ymin) / (xmax - xmin) - if dataRatio < plotRatio: - # Increase y range - ycenter = 0.5 * (ymax + ymin) - yrange = (xmax - xmin) * plotRatio - newLimits[2] = ycenter - 0.5 * yrange - newLimits[3] = ycenter + 0.5 * yrange - - elif dataRatio > plotRatio: - # Increase x range - xcenter = 0.5 * (xmax + xmin) - xrange_ = (ymax - ymin) / plotRatio - newLimits[0] = xcenter - 0.5 * xrange_ - newLimits[1] = xcenter + 0.5 * xrange_ - - self.setLimits(*newLimits) - + # Restore limits for axis not in autoscale if not xAuto and yAuto: self.setGraphXLimits(*xLimits) elif xAuto and not yAuto: @@ -2696,8 +2726,6 @@ class PlotWidget(qt.QMainWindow): if yLimits is not None: self.setGraphYLimits(yLimits[0], yLimits[1], axis='left') - self._setDirtyPlot() - if (xLimits != self._xAxis.getLimits() or yLimits != self._yAxis.getLimits() or y2Limits != self._yRightAxis.getLimits()): |