diff --git a/doc/api/api_changes/2015-03-14-SSH.rst b/doc/api/api_changes/2015-03-14-SSH.rst new file mode 100644 index 000000000000..902d0e766f24 --- /dev/null +++ b/doc/api/api_changes/2015-03-14-SSH.rst @@ -0,0 +1,16 @@ +``matplotlib.ticker.LinearLocator`` algorithm update +``````````````````````````` + +The ``matplotlib.ticker.LinearLocator`` is used to define the range and location +of tickmarks of a plot when the user wants a exact number of ticks. +``LinearLocator`` thus differs from the default locator ``MaxNLocator``, which +does not necessarily return the exact user requested number of ticks. + +The view range algorithm in ``matplotlib.ticker.LinearLocator`` has been +changed so that more convenient tick location are chosen. The new algorithm +returns a plot view range that is a multiple of the user requested number of +ticks. This ensures tick marks to be located at whole integers more +constistently. For example, when both y-axis of a``twinx`` plot use +``matplotlib.ticker.LinearLocator`` with the same number of ticks, the grids of +both axis will be properly aligned at convenient tick locations. + diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index c11bb9c3af33..5c1d7c94c08f 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -3780,7 +3780,8 @@ def twinx(self): create a twin of Axes for generating a plot with a sharex x-axis but independent y axis. The y-axis of self will have ticks on left and the returned axes will have ticks on the - right. + right. To ensure tick marks of both axis align, see + :class:`~matplotlib.ticker.LinearLocator` .. note:: For those who are 'picking' artists while using twinx, pick diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index 231a5f3193a0..552c9d7cffbd 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -1231,10 +1231,11 @@ def view_limits(self, vmin, vmax): vmax += 1 if rcParams['axes.autolimit_mode'] == 'round_numbers': - exponent, remainder = _divmod(math.log10(vmax - vmin), 1) + exponent, remainder = _divmod(math.log10(vmax - vmin), + math.log10(max([self.numticks-1, 1]))) if remainder < 0.5: exponent -= 1 - scale = 10 ** (-exponent) + scale = max([self.numticks-1, 1]) ** (-exponent) vmin = math.floor(scale * vmin) / scale vmax = math.ceil(scale * vmax) / scale