Closed roussel-ryan closed 3 years ago
Likely due to https://github.com/matplotlib/matplotlib/pull/14567? Seems reasonable to special case unicode minus to map to normal minus given that we already special case it for other purposes and also https://github.com/matplotlib/matplotlib/pull/16366, just needs to figure out what are the fonts that need that and can also do it correctly (not mapping to a dash).
Ah, actually that's not a regression, the unicode minus comes from https://github.com/matplotlib/matplotlib/blob/bb75f737a28f620fe023742f59dc6ed4f53b094f/lib/matplotlib/mathtext.py#L63 (of course we can still fix it...).
I'm extremely confused as to why using cmr causes an warning in a StixFonts instance, though (as can be checked by breakpoint()ing at the warning position) :/
Ok thank you for the effort! I'm not sure if I can do anything to help, but please let me know if there is
Same issue here.
Setting font as Computer Modern Roman (matplotlib.rcParams.update({'font.family': 'cmr10'})
) results in negative signs in ticklabels not rendering. Oddly, negative signs in titles & labels render fine.
Code for reproduction
unfortunately the only workaround I could come up with is:
plt.gca().set_xticklabels([i.get_text().replace('−', '$-$') for i in ax.get_xticklabels()])
plt.gca().set_yticklabels([i.get_text().replace('−', '$-$') for i in ax.get_yticklabels()])
which is annoying since 'font.family': ('cmr10', 'STIXGeneral')
should really work.
I looked a bit more into this. Fundamentally, the problem is that we are relying on the old computer modern fonts, where symbols (e.g. minus) and letters/digits are in different font files (cmr10/cmsy10); moreover the "standard" (non-mathtext) Text object is only able to use a single font file at a time (and it would be quite a big surgery to change that limitation).
Fortunately, when using mathtext, you can use multiple fonts at the same time; so one needs to force the ticks to use mathtext with rcParams["axes.formatter.use_mathtext"] = True
, and then we're not done yet, because the ticker uses \mathdefault
to wrap ticks, i.e. use the "non-mathtext" font... so then we need to add a special-case to mathtext, when using cmr10 as the non-mathtext font, to look up the minus sign in cmsy10 instead:
diff --git i/lib/matplotlib/mathtext.py w/lib/matplotlib/mathtext.py
index 8b9df7e19..8fdc29cad 100644
--- i/lib/matplotlib/mathtext.py
+++ w/lib/matplotlib/mathtext.py
@@ -842,6 +842,10 @@ class UnicodeFonts(TruetypeFonts):
found_symbol = False
font = self._get_font(new_fontname)
if font is not None:
+ if font.family_name == "cmr10" and uniindex == 0x2212:
+ font = get_font(
+ cbook._get_data_path("fonts/ttf/cmsy10.ttf"))
+ uniindex = 0xa1
glyphindex = font.get_char_index(uniindex)
if glyphindex != 0:
found_symbol = True
(probably a real patch would need to add a comment there). Together with rcParams["axes.formatter.use_mathtext"] = True
, I think this is the only reasonable short-term fix. Brownie points for whoever makes a PR out of this.
Long term I would like to get rid of the numerous cmXX10 fonts and replace them by the monolithic Latin Modern Math font, which should avoid all these problems. I guess that the cmr fonts shipped by Matplotlib should not be considered as "usable" for anything else than rcParams["mathtext.fontset"] = "cm"
(using them for font.family
will cause lots of trouble, like here); if you want to use CM for regular text consider just downloading Latin Modern Math (for example) and using that.
This also happens with the xkcd plotting style using the "Humor Sans" font.
x = np.linspace(0,10,20)
y = 2*x-3
with plt.xkcd():
fig = plt.figure()
ax = fig.add_subplot()
ax.plot(x,y)
I was able to get rid of the RuntimeWarning by declaring the font usage with:
plt.rcParams["font.serif"] = "cmr10"
Hence:
import matplotlib.pyplot as plt
plt.rcParams["font.serif"] = "cmr10"
fig, ax = plt.subplots()
ax.set_title('This is a special font:')
ax.set_xlabel(r'This is the default font $\alpha\beta\gamma$')
ax.set_yticks([-1, 0, 1])
plt.show()
And, it continues to work despite the declaration of the yticks, as in:
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.serif"] = "cmr10"
fig, ax = plt.subplots()
ax.set_title('This is a special font:')
ax.set_xlabel(r'This is the default font $\alpha\beta\gamma$')
ax.set_yticks(np.arange(-1, 1.25, 0.25))
plt.show()
Hope this helps!
Are there any news on this?
just rebased #18397
This also happens with the xkcd plotting style using the "Humor Sans" font.
So uh, this is why #26854 is failing (the plt.xkcd examples seem to work because they don't have a negative in the labels anywhere): throws "glyph missing" warning for title, omits hyphen for ticks:
Bug report
Trying to use computer modern roman (cmr10) font in plot. Getting an error which prevents minus sign rendering in plot.
Output:
Expected outcome Correct rendering of symbols
Matplotlib version
print(matplotlib.get_backend())
):Installed matplotlib via anaconda on default channel