8000 matplotlib.ticker.LinearLocator view_limits algorithm improvement? · Issue #6142 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

< 8000 div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;">
Skip to content
matplotlib.ticker.LinearLocator view_limits algorithm improvement? #6142
Closed
@maqifrnswa

Description

@maqifrnswa

Inspecting the code of matplotlib.ticker.LinearLocator

class LinearLocator(Locator):

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).

def view_limits(self, vmin, vmax):

Therefore, the view_limits function determines the limits assuming there are 11 ticks. This assumption is implicit in two lines:

exponent, remainder = divmod(math.log10(vmax - vmin), 1)

scale = 10 ** (-exponent)

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0