matplotlib / matplotlib

matplotlib: plotting with Python
https://matplotlib.org/stable/
20.39k stars 7.68k forks source link

[Bug]: Alignment of minus sign when using LaTeX #28766

Open johannfaouzi opened 3 months ago

johannfaouzi commented 3 months ago

Bug summary

There seems to be a different alignment for the minus sign depending on if the string contains only the minus sign or more characters when LaTeX is used.

Code for reproduction

import matplotlib.pyplot as plt
plt.rcParams.update({"text.usetex": True})

plt.text(0, 0, '$-3$', fontsize=40)
plt.text(0.2, 0, '$-$', fontsize=40)
plt.text(0.28, 0, '$3$', fontsize=40)
plt.ylim(-0.1, 0.1);
plt.axis('off');

Actual outcome

actual_output

Expected outcome

expected_output

Additional information

No response

Operating system

macOS Sonoma 14.6.1

Matplotlib Version

3.9.2

Matplotlib Backend

module://matplotlib_inline.backend_inline

Python version

3.10.13

Jupyter version

6.5.4

Installation

conda

oscargus commented 3 months ago

Matplotlib just grabs the generated image, cropped to minimal size, and position it in the correct location.

Although it may seem silly that this example doesn't work, one may also imagine much more complicated equations with multiple fractions etc, where it is clear that there is no way to really align two different equations as if they were written as one. That information is simply missing in the output Matplotlib gets.

timhoffm commented 3 months ago

That information is simply missing in the output Matplotlib gets.

One could add that information by adding a constant prefix including letters with descenders and ascenders, e.g. "gH", and then strip away the prefix.

QuLogic commented 3 months ago

I thought we did measure something with lp somewhere, but not sure if that is linked to this code path.

anntzer commented 2 months ago

Actually the information is already available (#16476), and indeed the bug is not present in any backend except agg; the problem arises because, even though the dvi file correctly places the minus sign well above the intended baseline position, the dvi parser cannot report the raster image of the minus sign as having "negative" depth (likely ultimately because in _output(), _font._height_depth_of(g) doesn't know about these negative depths). Other backends (including mplcairo's raster backend) don't have this issue because they simply read the baseline and glyph coordinates from the dvi file and redraw the glyphs themselves, which is probably the better approach in any case (see also part of https://github.com/matplotlib/matplotlib/issues/20469#issuecomment-864470954 as well as the paragraph I've deleted at https://github.com/matplotlib/matplotlib/pull/28810/files.