summaryrefslogtreecommitdiff
path: root/silx/gui/plot/PlotWidget.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/plot/PlotWidget.py')
-rw-r--r--silx/gui/plot/PlotWidget.py130
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()):