Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Factor out & improve accuracy of derivatives calculations in axisartist. #24509

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 1 commit into from
Dec 13, 2022

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Nov 19, 2022

grid_helper_curvelinear and floating_axes, which can both draw axes that are neither horizontal nor vertical, need to compute the derivatives of the data-coords-to-screen-coords transform (actually, of data-coords-to-data-coords-of-intermediate-horizontal/vertical-axes) to get the angles at which to draw the axes labels, ticks and ticklabels.

Factor out this calculation into a _value_and_jacobian helper. Instead of selecting the step size as some fraction of
lat_factor/lon_factor/delta_extremes, use the square root of machine precision epsilon, which is standard and (approximately) optimal for non-centered numerical differentiation (see e.g.
scipy.optimize.approx_fprime, or the Wikipedia article on numerical differentiation) -- and also happens to avoid introducing an extra paremeter into _value_and_jacobian.

Also lift some calculations out of get_tick_iterators (it doesn't really matter whether they are done inside or outside of get_tick_iterators, but dedenting the block is always nice).

The increases in tolerances arise because the calculations of the derivatives actually become more precise; for example, printing the angle returned by get_axislabel_pos_angle and running test_polar_box shows that previously the axes labels were drawn at angles of (45+1e-11) and 45.135 degrees, whereas they are now drawn at exactly 45 degrees. These tolerances (0.27/0.12) are actually still very small; e.g. removing the text.kerning_factor backcompat setting would require bumping the tolerance to more than 5.

PR Summary

PR Checklist

Documentation and Tests

  • Has pytest style unit tests (and pytest passes)
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • New plotting related features are documented with examples.

Release Notes

  • New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

@anntzer
Copy link
Contributor Author

anntzer commented Nov 21, 2022

Good catch, I assumed that the rest of the code always ensures xmin<=xmax, ymin<=ymax, but there's actually test_curvelinear3 which tests the case ymin>ymax; I'm not sure how robust the rest of the codebase is to handle that but I added some sorted() calls to handle that here.

grid_helper_curvelinear and floating_axes, which can both draw axes that
are neither horizontal nor vertical, need to compute the derivatives of
the data-coords-to-screen-coords transform (actually, of
data-coords-to-data-coords-of-intermediate-horizontal/vertical-axes) to
get the angles at which to draw the axes labels, ticks and ticklabels.

Factor out this calculation into a _value_and_jacobian helper.  Instead
of selecting the step size as some fraction of
lat_factor/lon_factor/delta_extremes, use the square root of machine
precision epsilon, which is standard and (approximately) optimal for
non-centered numerical differentiation (see e.g.
scipy.optimize.approx_fprime, or the Wikipedia article on numerical
differentiation) -- and also happens to avoid introducing an extra
paremeter into _value_and_jacobian.

Also lift some calculations out of get_tick_iterators (it doesn't really
matter whether they are done inside or outside of get_tick_iterators,
but dedenting the block is always nice).

The increases in tolerances arise because the calculations of the
derivatives actually become *more* precise; for example, printing the
angle returned by get_axislabel_pos_angle and running test_polar_box
shows that previously the axes labels were drawn at angles of
(45+1e-11) and 45.135 degrees, whereas they are now drawn at exactly 45
degrees.  These tolerances (0.27/0.12) are actually still very small;
e.g. removing the text.kerning_factor backcompat setting would require
bumping the tolerance to more than 5.
@timhoffm timhoffm merged commit 3067dad into matplotlib:main Dec 13, 2022
@anntzer anntzer deleted the vj branch December 13, 2022 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants