Skip to content

FIX: always use at least 2 ticks and recompute #5772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 25, 2016

Conversation

tacaswell
Copy link
Member

For extreme aspect-ratio plots the auto ntick logic would decide that
no ticks will fit, leading to divide by 0 issue.

  • This changes the logic in Axis.get_tick_space to have a floor of 1.
  • also does not cache the number of ticks so that if the on-screen
    aspect ratio changes the number of ticks will update correctly.

I tried to add a test for this, but something about the testing framework is causing trouble

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.set_xlim(0, 1000)
fig.canvas.draw()
print(ax.yaxis.get_major_locator()())
print(ax.xaxis.get_major_locator()())
assert len(ax.yaxis.get_major_locator()()) == 2
ax.set_ylim(0, 1000)
fig.canvas.draw()
assert len(ax.yaxis.get_major_locator()()) > 2

runs correctly as a script for me and interactively, but as part of the test suite give 6 ticks in the first case.

@tacaswell tacaswell added this to the next major release (2.0) milestone Dec 31, 2015
@mdboom
Copy link
Member

mdboom commented Dec 31, 2015

Tests in the test suite have a different figure size. You can set the size manually when creating the figure, however.

@tacaswell
Copy link
Member Author

duh, rcparams for the tests use 'classic' so this functionality is turned off!

@WeatherGod
Copy link
Member

Test failure:

ImageComparisonFailure: images not close: /home/travis/build/matplotlib/matplotlib/result_images/test_axes_grid1/inset_locator.png vs. /home/travis/build/matplotlib/matplotlib/result_images/test_axes_grid1/inset_locator-expected.png (RMS 2.177)

@tacaswell
Copy link
Member Author

I can reproduce the inset locator failure locally, looking into it now.

@tacaswell
Copy link
Member Author

The issue with the inset locator seems to be that as previously implemented the axis's estimate of how many ticks it should have was computed once and then saved.

The way that the inset axes works (if you step through this line at a time) is that the figure-space size of the axes follows the x/y limits at a fixed ratio to the screen-space of the same range in the main axes. Thus, when the inset axes is created it is 'big' in that it has limits of [0, 1] at 6x zoom -> about half the size of the host axes and so it concludes that it needs a whole bunch of ticks and remembers that.

One of the changes in this PR makes it so that the number of ticks is recomputed every time, thus many fewer ticks are used when the axes is small (even though the text is all turned off).

The simplest solution is to change the test code to not use the auto tick count in the test.

Also, kicking my self for merging the PR where this test got added for not asking Mike to change to 'viridis' for the color map.

@tacaswell
Copy link
Member Author

I think this is ready for review.

@@ -2004,7 +2004,7 @@ def get_tick_space(self):
# is no more than 3:1
size = tick.label1.get_size() * 3
size *= np.cos(np.deg2rad(tick.label1.get_rotation()))
self._tick_space = np.floor(length / size)
return np.floor(length / size)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we're no longer caching the calculation? This could be somewhat expensive to do every time. If not too expensive, we should remove the if self._tick_space (and the self._tick_space member) altogether. If it is, maybe we just need to properly invalidate this value using the stale infrastructure (which will be traitlets sometime in the near future)?

@tacaswell
Copy link
Member Author

@jenshnielsen Finally made the last change to this, it should be ready to go

@jenshnielsen
Copy link
Member

Looks good to me. I think the changes to test_axes_grid1 should be implemented in the example that this is based on too i.e. inset_locator_demo2.py and possibly others

For extreme aspect-ratio plots the auto ntick logic would decide that
no ticks will fit, leading to divide by 0 issue.

 - In ticker ensure there is always at least on bin
 - Axis do not cache the number of ticks so that if the on-screen
   aspect ratio changes the number of ticks will update correctly.
Do not let the ticks in the inset adjust based on spacing of text which
is not visible.

The issue with the inset locator seems to be that as previously
implemented the axis's estimate of how many ticks it should have was
computed once and then saved.

The way that the inset axes works (if you step through this line at a
time) is that the figure-space size of the axes follows the x/y limits
at a fixed ratio to the screen-space of the same range in the main
axes. Thus, when the inset axes is created it is 'big' in that it has
limits of [0, 1] at 6x zoom -> about half the size of the host axes and
so it concludes that it needs a whole bunch of ticks and remembers that.

One of the changes in this PR makes it so that the number of ticks is
recomputed every time, thus many fewer ticks are used when the axes is
small (even though the text is all turned off).
In the inset axes (which will not have tick labels) fix the number
of ticks instead of letting auto-ticker pick the number of ticks.
@tacaswell
Copy link
Member Author

@jenshnielsen examples updated.

@jenshnielsen
Copy link
Member

cool I will review and merge asap

jenshnielsen added a commit that referenced this pull request Jan 25, 2016
FIX: always use at least 2 ticks and recompute
@jenshnielsen jenshnielsen merged commit 7cea22c into matplotlib:v2.x Jan 25, 2016
@tacaswell tacaswell deleted the min_nticks branch April 11, 2016 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants