Skip to content

Support units for the third \genfrac argument #22171

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

oscargus
Copy link
Member

@oscargus oscargus commented Jan 9, 2022

PR Summary

Closes #19001.

This also means that it is rather easy to support units for other things.

One doubt though: I couldn't figure out the standard unit in mathtext. Right now, I have assumed pt, but I suspect it may not be correct. I'll update with a test once I know the answer... However, as I have local test errors on image comparisons (for pdf), I am not convinced that the tests will pass. These are the ones I currently get:

FAILED test_mathtext.py::test_mathtext_rendering[pdf-mathtext-dejavusans-72] - matplotlib.testing.exceptions.ImageComparisonFailure: images not close (RMS 2.524):
FAILED test_mathtext.py::test_mathtext_rendering[pdf-mathtext-dejavusans-77] - matplotlib.testing.exceptions.ImageComparisonFailure: images not close (RMS 2.524):
FAILED test_mathtext.py::test_mathtext_rendering[pdf-mathtext-dejavuserif-20] - matplotlib.testing.exceptions.ImageComparisonFailure: images not close (RMS 1.785):
FAILED test_mathtext.py::test_mathtext_rendering[pdf-mathtext-dejavuserif-33] - matplotlib.testing.exceptions.ImageComparisonFailure: images not close (RMS 1.785):
FAILED test_mathtext.py::test_mathtext_rendering[pdf-mathtext-dejavuserif-36] - matplotlib.testing.exceptions.ImageComparisonFailure: images not close (RMS 1.785):
FAILED test_mathtext.py::test_mathtext_rendering[pdf-mathtext-dejavuserif-37] - matplotlib.testing.exceptions.ImageComparisonFailure: images not close (RMS 1.785):
FAILED test_mathtext.py::test_mathtext_rendering[pdf-mathtext-dejavuserif-75] - matplotlib.testing.exceptions.ImageComparisonFailure: images not close (RMS 2.524):

Is there a "better" way to generate test images that are more likely to pass on the CI?

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).
  • [N/A] 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).

'cm': 7227/254,
'in': 7227/100,
'ex': 35271/8192,
'em': 655361/65536,
Copy link
Contributor

Choose a reason for hiding this comment

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

ex and em are probably not fixed values as they should(?) depend on the actual font being used, e.g. whether we're in a mathbf or a mathcal or whatnot. OTOH we don't necessarily need to support them for now?

'in': 7227/100,
'ex': 35271/8192,
'em': 655361/65536,
'mu': 7227/2540000,
Copy link
Contributor

Choose a reason for hiding this comment

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

I can't find a ref for mu, nc, nd as standard tex units, perhaps you can link their definition? (as a comment here at least, not in the code)

Copy link
Member Author

Choose a reason for hiding this comment

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

I used some stack exchange thread combined with other sources, but cannot seem to find where I got ex and em from now. I agree with that they shouldn't be there though (just added what was there without really thinking about the meaning).

Here are some better sources:
https://en.wikibooks.org/wiki/LaTeX/Lengths
https://latexref.xyz/Units-of-length.html

(And here is a good discussion why ex and em are bad choices: https://tex.stackexchange.com/questions/4239/which-measurement-units-should-one-use-in-latex
)

Copy link
Member Author

Choose a reason for hiding this comment

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

@anntzer
Copy link
Contributor

anntzer commented Jan 13, 2022

I agree that the "reference unit" should be clarified, it's not clear to me either. Also note that TeX basically operates in a world of 72.27dpi (aka 72 "big points per inch") exactly whereas we don't, so I'm not sure if we can have correct physical dimensions (in, cm, mm, etc., e.g. a height of 1cm should occupy half of a figure that is 2cm tall -- by the way this would be a good example to post in this thread to show that the sizes are indeed correct) and correct point-based dimensions (e.g. a height of 12pt should occupy whatever that means wrt. text of font size 12). (I'm not sure I have a good answer, but probably the design choices will need to be made explicit.)

@QuLogic QuLogic changed the title mathtext now supports units for the third \genfrac argument Support units for the third \genfrac argument Jan 14, 2022
@jklymak jklymak marked this pull request as ready for review January 17, 2022 12:17
@jklymak
Copy link
Member

jklymak commented Jan 17, 2022

Ooops sorry marked ready for review by accident

WRT em and ex I think they are perfectly reasonable units, particularly for the fraction line which you may think would thicken or thin relative to the font size.

@oscargus
Copy link
Member Author

WRT em and ex

Yes, they are reasonable as such. The problem is that they are not static, so one will then need to figure out for each font what the appropriate scale factor is. Unless I find a "simple" solution for that (maybe @anntzer knows how one can query this), I do not think it will be included in this PR.

Reading up a bit more on https://tex.stackexchange.com/questions/4239/which-measurement-units-should-one-use-in-latex it says

 Bringhurst says: (2.1.1) "1 em is a distance equal to the type size", so you can be more certain than "usually consider".

This would make it a bit easier at least by using the font size as the em scale factor.

For ex one may have to measure though.

@oscargus oscargus marked this pull request as draft January 17, 2022 13:08
@oscargus
Copy link
Member Author

I have removed ex and added proper support for em (based on pt being used and the statement "1 em is a distance equal to the type size".

Now I have problem generating \genfrac with usetex=True for comparison, but I seem to recall that the results were matching pretty well. Will try to solve that and provide some examples.

@oscargus
Copy link
Member Author

oscargus commented Jan 30, 2022

Forgot about amsmath...

Here are some examples:
image

Rendered with mathtext and latex respectively. As far as I can tell, the current scaling matches the LaTeX rendering if nothing else. The size of the bar is stated in numerator and denominator.

Then, the bug in #22172 is manifested. I have a small hack for that leading to:
image

Not sure if I should include that? It seems like the approach in #20627 is fundamentally better (since it actually considers how LaTeX does it, not just the result of playing around), but that currently doesn't seem to handle wide bars (which may not really be a problem).

@oscargus oscargus marked this pull request as ready for review January 30, 2022 11:04
@oscargus oscargus added this to the v3.6.0 milestone Mar 25, 2022
@tfpf
Copy link
Contributor

tfpf commented May 8, 2022

#20627 has been replaced by #22852, which does it the same way LaTeX does (i.e. with font constants and with the thickness of the line taken into account).

@@ -2004,6 +2006,10 @@ def __init__(self):

p.float_literal <<= Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)")
p.int_literal <<= Regex("[-+]?[0-9]+")
p.unit <<= Regex("(pt|mm|cm|in|em|mu|"
"sp|bp|dd|pc|nc|nd|cc)")
p.float_with_wo_unit <<= Group((p.float_literal + p.unit) |
Copy link
Contributor

Choose a reason for hiding this comment

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

what's "wo"?

@@ -2004,6 +2006,10 @@ def __init__(self):

p.float_literal <<= Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)")
p.int_literal <<= Regex("[-+]?[0-9]+")
p.unit <<= Regex("(pt|mm|cm|in|em|mu|"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can get rid of the grouping parentheses, which should be marginally more efficient.

@anntzer
Copy link
Contributor

anntzer commented May 21, 2022

If I understand correctly, this makes the old "unitless" genfrac use points (= pixels), and then defines units using tex's ratios (1in=72pt, etc.), which means that a 1in thickness will not actually be e.g. 1/3 of a 3in figure unless working at 72dpi: try e.g.

from pylab import *
rcParams["text.latex.preamble"] = r"\usepackage{amsmath}"
figure(figsize=(3, 3), dpi=100).text(.5, .5, r"$\genfrac{}{}{1in}{1}{a}{b}$", size=24, usetex=False)
figure(figsize=(3, 3), dpi=100).text(.5, .5, r"$\genfrac{}{}{1in}{1}{a}{b}$", size=24, usetex=True)

I'm not sure that's really what we want (basically #22171 (comment))? The parser does have dpi information available (get_state().dpi); perhaps it should scale physical units accordingly instead? (I'm not actually sure, but asking for a 1in thick rule and getting something else is a bit annoying?) In any case the behavior we decide on should be documented in the comments, at least.

This also clearly displays the #22172 bug (but I understand that #22852 is working on that) and there's also a vertical alignment problem (which also seems fixed bu #22852?).

@oscargus
Copy link
Member Author

But that, somehow, creates a problem already now? I'm not saying that this is the way to go, but I am quite sure that it is not introducing any new issues? Except that maybe one do expect a certain result as one can state the units and the previous "unitless" one, there were really no expectations (except that possibly one would guess it was points).

But you are probably correct that ideally one should take the dpi into consideration.

@anntzer
Copy link
Contributor

anntzer commented May 24, 2022

The new issue is that someone could write \genfrac...{1cm}... and not get what they expected (which I would argue is worse than erroring out -- at least in that case you know the feature is not supported).

@oscargus
Copy link
Member Author

and not get what they expected

Fair point.

Assuming that I manage to solve that part, should we also change the default to mean points? (Which I still sort of guess that most people assume it means?)

@anntzer
Copy link
Contributor

anntzer commented May 25, 2022

I don't really think you can change the default behavior here?

@jklymak
Copy link
Member

jklymak commented Jun 23, 2022

@oscargus what is the status here? I've moved to draft, but feel free to move back. If @tfpf is good with this, I can review based on their review, and hopefully @anntzer can provide a second review.

@jklymak jklymak marked this pull request as draft June 23, 2022 08:00
@oscargus
Copy link
Member Author

@oscargus what is the status here?

@anntzer made a fair point about dpi-scaling that I have not had time to look into, so moving to draft is a good call.

I think it should be quite straightforward to sort it out though, given time (and inspiration, but that is a bit random).

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.

\genfrac should accept a unit for thickness
5 participants