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

Skip to content

Revert datetime usetex ticklabels to use default tex font. #22361

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
Mar 29, 2022

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Jan 30, 2022

PR Summary

with {\fontfamily{\familydefault}\selectfont ...}, instead of using
math and selectively escaping parts of the string.

Note that this is only possible now that tex strings are passed "all at
once" to the tex process (#22360) rather than "one line at a time", because if
breaking at "\n" as previously done, then the braces of the tex
command above would become unbalanced (and lines other than the first
would not see the \selectfont).

The main difference in rendering is that hyphens (e.g. in YY-MM-DD) are
now rendered as plain hyphens rather than minus signs, but some googling
suggests that this is in fact correct (see e.g. ctan datetime2 or
isodate packages). Also, month names are now rendered with serif, but
that seems more consistent with day and years which are also serifed
(and which were the original source of all these issues).

See also the script below, which reproduces the various issues raised
over the years:

from datetime import datetime, timedelta
from matplotlib.dates import ConciseDateFormatter, DateFormatter
import matplotlib.pyplot as plt
import numpy as np

plt.rcdefaults(); plt.rcParams['text.usetex'] = True
fig, axs = plt.subplots(4, constrained_layout=True, figsize=(12, 4))
t0 = datetime.now()
ts = [t0 + i * timedelta(days=1) for i in range(10)]
axs[0].plot(ts, range(10))
axs[1].plot(ts, range(10))
axs[1].xaxis.set_major_formatter(ConciseDateFormatter(axs[1].xaxis.get_major_locator()))
ts = [t0 + i * timedelta(seconds=6) for i in range(100)]
axs[2].plot(ts, range(100))
axs[3].xaxis.set_major_formatter(DateFormatter('%d/%m\n%Y'))

plt.show()

test

Fixes #22350. Goes on top of #22359 and then #22360.

PR Checklist

Tests and Styling

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (install flake8-docstrings and run flake8 --docstring-convention=all).

Documentation

  • New features are documented, with examples if plot related.
  • New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).

ret_text = '$\\mathdefault{' + ret_text + '}$'
ret_text = ret_text.replace('$\\mathdefault{}$', '')
return ret_text
return r"{\fontfamily{\familydefault}\selectfont " + text + "}"
Copy link
Member

Choose a reason for hiding this comment

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

My matplotlib/latex integration ignorance is vast, but why do we need to do all the font selection here? (I guess I'm really asking why this needs to wrapped at all)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because tick formatters can only set the ticklabel text, but not the ticklabel font (and moreover the way latex integration is set up right now, we don't even respect the font setting on Text object, but only the global rcParams["font.family"], which is something that we should fix too...

So forcing the font via tex commands is using a big hammer to just go around all these limitations.

Copy link
Member

Choose a reason for hiding this comment

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

But I mean, why isn't the default latex font acceptable? If I just put "23-Dec-2022" in a Latex document, that looks fine?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See #2294 (comment): this is because we default to forcing non-math to sans-serif, which looks inconsistent with the serif numeric ticks. I agree with your point at #22350 (comment) that defaulting to sans-serif tex may not have been the best choice, but changing that would be somewhat trickier.

Copy link
Member

@jklymak jklymak left a comment

Choose a reason for hiding this comment

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

LGTM...

with `{\fontfamily{\familydefault}\selectfont ...}`, instead of using
math and selectively escaping parts of the string.

Note that this is only possible now that tex strings are passed "all at
once" to the tex process rather than "one line at a time", because if
breaking at `"\n"` as previously done, then the braces of the tex
command above would become unbalanced (and lines other than the first
would not see the `\selectfont`).

The main difference in rendering is that hyphens (e.g. in YY-MM-DD) are
now rendered as plain hyphens rather than minus signs, but some googling
suggests that this is in fact correct (see e.g. ctan datetime2 or
isodate packages).  Also, month names are now rendered with serif, but
that seems more consistent with day and years which are also serifed
(and which were the original source of all these issues).

See also the script below, which reproduces the various issues raised
over the years:
```python
from datetime import datetime, timedelta
from matplotlib.dates import ConciseDateFormatter, DateFormatter
import matplotlib.pyplot as plt
import numpy as np

plt.rcdefaults(); plt.rcParams['text.usetex'] = True
fig, axs = plt.subplots(4, constrained_layout=True, figsize=(12, 4))
t0 = datetime.now()
ts = [t0 + i * timedelta(days=1) for i in range(10)]
axs[0].plot(ts, range(10))
axs[1].plot(ts, range(10))
axs[1].xaxis.set_major_formatter(ConciseDateFormatter(axs[1].xaxis.get_major_locator()))
ts = [t0 + i * timedelta(seconds=6) for i in range(100)]
axs[2].plot(ts, range(100))
axs[3].xaxis.set_major_formatter(DateFormatter('%d/%m\n%Y'))

plt.show()
```
@anntzer
Copy link
Contributor Author

anntzer commented Mar 29, 2022

Now ready to go.

@timhoffm timhoffm added this to the v3.6.0 milestone Mar 29, 2022
@timhoffm timhoffm merged commit c98411e into matplotlib:main Mar 29, 2022
@timhoffm
Copy link
Member

@anntzer do you consider this a bug fix that should be backported to 3.5.x?

@anntzer
Copy link
Contributor Author

anntzer commented Mar 29, 2022

Probably not, given the amount of stuff that would need to be backported...

@anntzer anntzer deleted the datetex branch March 29, 2022 21:39
QuLogic added a commit to QuLogic/matplotlib that referenced this pull request Sep 29, 2022
This reverts commit c98411e, reversing
changes made to ccf5115.
QuLogic added a commit to QuLogic/matplotlib that referenced this pull request Sep 29, 2022
This reverts commit c98411e, reversing
changes made to ccf5115.
kostyafarber pushed a commit to kostyafarber/matplotlib that referenced this pull request Oct 4, 2022
j1642 pushed a commit to j1642/matplotlib that referenced this pull request Oct 7, 2022
melissawm pushed a commit to melissawm/matplotlib that referenced this pull request Dec 19, 2022
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.

[Bug]: text.usetex Vs. DateFormatter
4 participants