Skip to content
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

Fix minus signs in WCSAxes in TeX mode #16406

Merged
merged 2 commits into from
May 11, 2024
Merged

Conversation

svank
Copy link
Contributor

@svank svank commented May 7, 2024

Description

This is a small fix to #15902. For a moment in that PR, repeated minus signs were trimmed from axis labels, and that still happens when using matplotlib's TeX mode (note the bottom y tick):

from astropy.wcs import WCS
import matplotlib.pyplot as plt
import numpy as np
wcs = WCS(naxis=2)
wcs.wcs.ctype = 'RA', 'DEC'
wcs.wcs.crpix = 25, 25

plt.rcParams['text.usetex'] = True
ax = plt.subplot(1, 1, 1, projection=wcs)
plt.imshow(np.zeros((50, 50)))

image

This is because minuses are still hyphens in TeX mode (they should be, because LaTeX will render them right, and it happens because formatter_locator._fix_minus only looks at the first character of each label, which is $ in TeX mode). But TickLabels.simplify_labels still expects a unicode minus, so it trims the hyphen.

This PR has TickLabels.simplify_labels expect hyphens in TeX mode, no matter the unicode_minus setting.

I added a test, but it's awkward because TeX tests are currently not run, pending #13326. If I force-enable TeX tests, the new test passes with this fix and fails without this fix:

=================================== FAILURES ===================================
__________________ test_simplify_labels_minus_sign[True-True] __________________

ignore_matplotlibrc = None, usetex = True, unicode_minus = True

    @pytest.mark.parametrize("usetex", [True, False])
    @pytest.mark.parametrize("unicode_minus", [True, False])
    def test_simplify_labels_minus_sign(ignore_matplotlibrc, usetex, unicode_minus):
        with mpl.rc_context(rc={"text.usetex": usetex, "axes.unicode_minus": unicode_minus}):
            ticklabels = TickLabels(None)
            expected_labels = []
            for i in [1, 2]:
                if usetex:
                    label = f"$-{i}$"
                elif unicode_minus:
                    label = f"\N{MINUS SIGN}{i}"
                else:
                    label = f"-{i}"
                ticklabels.add(axis='axis', world=0, angle=0, text=label, axis_displacement=0, data=(0, 0))
                expected_labels.append(label)
            ticklabels.simplify_labels()
>           assert ticklabels.text['axis'] == expected_labels
E           AssertionError: assert ['$-1$', '$2$'] == ['$-1$', '$-2$']
E             
E             At index 1 diff: '$2$' != '$-2$'
E             Use -v to get more diff

tests/test_misc.py:520: AssertionError
=========================== short test summary info ============================
FAILED tests/test_misc.py::test_simplify_labels_minus_sign[True-True] - AssertionError: assert ['$-1$', '$2$'] == ['$-1$', '$-2$']
=================== 1 failed, 33 passed, 1 skipped in 1.93s ====================

Copy link

github-actions bot commented May 7, 2024

Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.

  • Do the proposed changes actually accomplish desired goals?
  • Do the proposed changes follow the Astropy coding guidelines?
  • Are tests added/updated as required? If so, do they follow the Astropy testing guidelines?
  • Are docs added/updated as required? If so, do they follow the Astropy documentation guidelines?
  • Is rebase and/or squash necessary? If so, please provide the author with appropriate instructions. Also see instructions for rebase and squash.
  • Did the CI pass? If no, are the failures related? If you need to run daily and weekly cron jobs as part of the PR, please apply the "Extra CI" label. Codestyle issues can be fixed by the bot.
  • Is a change log needed? If yes, did the change log check pass? If no, add the "no-changelog-entry-needed" label. If this is a manual backport, use the "skip-changelog-checks" label unless special changelog handling is necessary.
  • Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied?
  • At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate "backport-X.Y.x" label(s) before merge.

Copy link
Contributor

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

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

Thank you for catching and fixing this and sorry I didn't think more about tex mode in my PR. I would expect the new test to live next to the one I added in #15902, or even better, extend the existing test through pytest.mark.parametrize. Any reason not to ?
(note that I'm currently working on fixing my own system where I just found that TeX is broken, so I couldn't run the test yet, but I'll report back)

@svank
Copy link
Contributor Author

svank commented May 7, 2024

No worries! I wasn't quite sure where to test this, but I guess I thought this test was covering TickLabels.simplify_labels whereas your new test was covering FormatterLocator.formatter---sort of unit testing different parts of the overall feature, so that's why I did it separately. I'm open to other ideas.

@pllim pllim added this to the v6.1.1 milestone May 7, 2024
@pllim pllim added Bug backport-v6.1.x on-merge: backport to v6.1.x labels May 7, 2024
@neutrinoceros
Copy link
Contributor

neutrinoceros commented May 7, 2024

No that's okay, you're right that you're testing a different bit of code, so it seems correct to have a separate test in hindsight. I was able to reprod and confirm that your patch fixed the problem locally. I'll do a detailed review now.
Out of curiosity, do you have any idea why, in your example, the minus sign is missing from the "-20°" label but not from the "-10°" one ?

angle=0,
text=label,
axis_displacement=0,
data=(0, 0),
Copy link
Contributor

Choose a reason for hiding this comment

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

I know we're not going to look at these labels, so overlaps don't really matter, but it's still bugging me. Can we make data depend on i ?

Comment on lines 515 to 520
if usetex:
label = f"$-{i}$"
elif unicode_minus:
label = f"\N{MINUS SIGN}{i}"
else:
label = f"-{i}"
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer we avoid ifs in the body of the test when we can use parametrization instead. What I'm suggesting here is to use a single @pytest.mark.parametrize decorator with three parameters: usetex, unicode_minus, and expected_labels. It be less dynamic but would isolate the test logic from the input/expectation definition.

with mpl.rc_context(
rc={"text.usetex": usetex, "axes.unicode_minus": unicode_minus}
):
ticklabels = TickLabels(None)
Copy link
Contributor

Choose a reason for hiding this comment

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

does this line also need to happen within the mpl.rc_context ?

@svank
Copy link
Contributor Author

svank commented May 8, 2024

Out of curiosity, do you have any idea why, in your example, the minus sign is missing from the "-20°" label but not from the "-10°" one ?

I think it's just coming from that function's role in separating out the common prefix and the varying part of each tick label. Without putting the right kind of minus sign in skippable_chars, the minus sign gets shown for the first tick that has it, and then trimmed from successive ones.

Thanks for your review comments! I should have addressed them all.

@svank svank force-pushed the ticks_and_latex branch 2 times, most recently from b69a20d to a959570 Compare May 8, 2024 03:05
Copy link
Contributor

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

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

I think it's just coming from that function's role in separating out the common prefix and the varying part of each tick label. Without putting the right kind of minus sign in skippable_chars, the minus sign gets shown for the first tick that has it, and then trimmed from successive ones.

thanks a bunch for this detailed explanation ! I think that this would be more obvious if they were more than 2 labels, so I suggest extending the test (it's a loop anyway) to use 4 or 5 of them.
After this round of review I think we'll be all set. Thank you !

data=(i, i),
)
expected_labels.append(label)
ticklabels.simplify_labels()
Copy link
Contributor

Choose a reason for hiding this comment

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

actually I expect this line would be the only one that needs to happen within the rc_context, or am I missing something ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, you're right!

rc={"text.usetex": usetex, "axes.unicode_minus": unicode_minus}
):
expected_labels = []
for i in [1, 2]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
for i in [1, 2]:
for i in range(1, 6):

@svank
Copy link
Contributor Author

svank commented May 11, 2024

Alright, I've updated the test again. Thanks for reviewing!

Copy link
Contributor

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

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

LGTM now, thanks again !

@astrofrog astrofrog merged commit 5191dff into astropy:main May 11, 2024
26 of 27 checks passed
meeseeksmachine pushed a commit to meeseeksmachine/astropy that referenced this pull request May 11, 2024
pllim added a commit that referenced this pull request May 13, 2024
…406-on-v6.1.x

Backport PR #16406 on branch v6.1.x (Fix minus signs in WCSAxes in TeX mode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants