Description
Inspecting the code of matplotlib.ticker.LinearLocator
matplotlib/lib/matplotlib/ticker.py
Line 1161 in 7d1a7c2
you can see that the view limits are chosen such that the difference between vmin and vmax is an interger multiple of scale, which is itself a power of 10. Therefore, the range will be nicely divisible when divided by 10 (11 tickmarks).
matplotlib/lib/matplotlib/ticker.py
Line 1213 in 7d1a7c2
Therefore, the view_limits function determines the limits assuming there are 11 ticks. This assumption is implicit in two lines:
matplotlib/lib/matplotlib/ticker.py
Line 1224 in 7d1a7c2
matplotlib/lib/matplotlib/ticker.py
Line 1227 in 7d1a7c2
Code is repeated here:
exponent, remainder = divmod(math.log10(vmax - vmin), 1)
if remainder < 0.5:
exponent -= 1
scale = 10 ** (-exponent)
vmin = math.floor(scale * vmin) / scale
vmax = math.ceil(scale * vmax) / scale
Since we know the number of ticks, from self.num_ticks
, we can generalize the current algorithm to be better suited for any number of ticks. Suggested generalized algorithm:
exponent, remainder = divmod(math.log10(vmax - vmin), math.log10(self.num_ticks-1))
if remainder < 0.5:
exponent -= 1
scale = (self.num_ticks-1) ** (-exponent)
vmin = math.floor(scale * vmin) / scale
vmax = math.ceil(scale * vmax) / scale
This generalized expression reduces to the current form when self.num_ticks==11
(which is the current default). For other cases, here is an example:
when num_ticks = 10, vmin = 20, vmax=90
Current algorithm returns vmin = 20, vmax=90, corresponding to ticks spaced by 7.77778.
The proposed algorithm returns vmin = 18, vmax = 90, corresponding to ticks spaced by 8.
Is this something worth doing? The patch is trivial -- just changing two lines of code. I can turn this in to a pull request to illustrate if it is helpful.