You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Unexpected replacement of \right) with exclamation point in MathTextParser output #5210
With certain LaTeX strings, the right paranthesis indicates by \right) is replaced with an exclamation point when passed to MathTextParser and rendered as a bitmap or png. This behaviour appears to occur when the parantheses are around an expression comprising multiple layered fractions. It does not occur if \right] or \right\} are used
The minimal code to reproduce this is as follows:
import matplotlib.mathtext as mt
s = r'$\left(\frac{\frac{\frac{M}{I}}{N}}' \
r'{\frac{\frac{B}{U}}{G}}\right)$'
parser = mt.MathTextParser("Bitmap")
for size in range(1, 30):
filename = "figure{0}.png".format(size)
parser.to_png(filename, s, fontsize=size)
This gives output like
Investigations indicate that this occurs only for certain combinations of expression and font size, but the example given above seems to give the most consistent failure conditions. It may be related to dpi in the rendering, however this has not yet been conclusively proven or disproven.
A bit more investigation - I monkey patched my matplotlib installation - putting in a print(result) directly after the call to parseString()here. With a working expression that goes fine and prints out a textual representation. With the bugged scenario, I see:
Traceback (most recent call last):
File "D:\baptiste_test.py", line 9, in <module>
parser.to_png(filename, s, fontsize=size)
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 3101, in to_
png
rgba, depth = self.to_rgba(texstr, color=color, dpi=dpi, fontsize=fontsize)
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 3066, in to_
rgba
x, depth = self.to_mask(texstr, dpi=dpi, fontsize=fontsize)
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 3039, in to_
mask
ftimage, depth = self.parse(texstr, dpi=dpi, prop=prop)
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 3012, in par
se
box = self._parser.parse(s, font_output, fontsize, dpi)
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 2339, in par
se
print(result[0])
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 1403, in __r
epr__
' '.join([repr(x) for x in self.children]))
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 1403, in __r
epr__
' '.join([repr(x) for x in self.children]))
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 1403, in __r
epr__
' '.join([repr(x) for x in self.children]))
File "C:\Python27\lib\site-packages\matplotlib\mathtext.py", line 1403, in __r
epr__
' '.join([repr(x) for x in self.children]))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb3' in position 1:
ordinal not in range(128)
This indicates that the bug might originate in a mis-translated character - maybe a missing codepoint in the font?
For info - I just built off master and replicated this. It's also been replicated on the versions mentioned on SO - mpl 1.4.3 and 1.5.0. I don't think it's relevant, but I've seen it on both Windows and Linux.
I've done some further digging - sticking some debug prints in _get_glyph within the BakomaFonts class. In the failing case, the code seems to be looking up an exclamation (u'!') when you'd expect it to be looking for u'\xc4' and returning parenrightBigg (i.e. where the corresponding left bracket is looking up u'\xc3' and returning parenleftBigg). In situations where it only uses parenrightbigg, there is no problem (this occurs for fontsize=5 in the given example but no others). The debug line I put in _get_glyph was:
print('Getting glyph for symbol',repr(unicode(sym)))
print('Returning',cached_font, num, symbol_name, fontsize, slanted)
I guess whether it needs the bigg or Bigg version is based on a combination of fontsize and dpi
the '\x21' is wrong - but I can't work out what the right one is '\x29' is close, but "too curved". Hopefully one of the core devs can easily lookup this number (decimal 195) against the glyph it renders and correct.
@rsnape: Your comment that \x29 was not the correct one had me thinking: a couple of lines underneath \x29 is given as a large size alternative for }, but it is obviously a large parens, no a bracket, and sticking \left\{ .... \right\} around your code gives this at size 5:
but this at larger sizes:
So, yeah, we should check that all those codes are correct. I don't know exactly how to do that, though; I haven found a list of the Bakoma glyphs anywhere. @mdboom?
@zblz - my understanding is that 28 and 29 are just the basic paren glyphs and the \Bigg braces fall back on that. They actually give the same glyph as the lookup for '(' and ')' as far as I can tell. I'd like to find the table too - having done quite a bit of legwork to isolate, I'd like to submit a PR for this one :)
@zblz Yes - maybe a good call to remove them for all, unless it's easy to find exactly which are available and why. The removal solution seems better than falling back on () for braces too (IMHO)
Well - I found this which seems to show the lookup, but it does show 33 or 0x21 mapping to rightparenBigg - and 0x28 and 0x29 mapping to leftbraceBigg and rightbraceBigg respectively. This implies that the line I highlighted is correct. So maybe the bug is in the lookup or font definition, rather than that line mapping sized delimiters to glyphs.
_EDIT_ Pretty sure this may be relevant - in the ascii table 0x21 is !, 0x28 is ( and 0x29 is ). This looks like a lookup defaulting to ascii lookup rather than glyph index, I think.
changed the title [-]Unexpected replacement of \right) with exlamation point in MathTextParser output[/-][+]Unexpected replacement of \right) with exclamation point in MathTextParser output[/+]on Apr 24, 2026
Activity
rsnape commentedon Oct 8, 2015
A bit more investigation - I monkey patched my matplotlib installation - putting in a
print(result)directly after the call toparseString()here. With a working expression that goes fine and prints out a textual representation. With the bugged scenario, I see:This indicates that the bug might originate in a mis-translated character - maybe a missing codepoint in the font?
tacaswell commentedon Oct 8, 2015
attn @mdboom @zblz
rsnape commentedon Oct 8, 2015
For info - I just built off master and replicated this. It's also been replicated on the versions mentioned on SO - mpl 1.4.3 and 1.5.0. I don't think it's relevant, but I've seen it on both Windows and Linux.
QuLogic commentedon Oct 8, 2015
Strangely, it works correctly at
fontsize=5, but no other sizes.rsnape commentedon Oct 8, 2015
@QuLogic ha - yes - I hadn't noticed that but you're right certainly on the build I just did from master
rsnape commentedon Oct 9, 2015
I've done some further digging - sticking some debug prints in
_get_glyphwithin theBakomaFontsclass. In the failing case, the code seems to be looking up an exclamation (u'!') when you'd expect it to be looking foru'\xc4'and returningparenrightBigg(i.e. where the corresponding left bracket is looking upu'\xc3'and returningparenleftBigg). In situations where it only usesparenrightbigg, there is no problem (this occurs forfontsize=5in the given example but no others). The debug line I put in_get_glyphwas:I guess whether it needs the
biggorBiggversion is based on a combination offontsizeanddpirsnape commentedon Oct 9, 2015
OK - I think problem is in this line : https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/mathtext.py#L727
this reads
the
'\x21'is wrong - but I can't work out what the right one is'\x29'is close, but "too curved". Hopefully one of the core devs can easily lookup this number (decimal 195) against the glyph it renders and correct.zblz commentedon Oct 9, 2015
@rsnape: Your comment that

\x29was not the correct one had me thinking: a couple of lines underneath\x29is given as a large size alternative for}, but it is obviously a large parens, no a bracket, and sticking\left\{ .... \right\}around your code gives this at size 5:but this at larger sizes:

So, yeah, we should check that all those codes are correct. I don't know exactly how to do that, though; I haven found a list of the Bakoma glyphs anywhere. @mdboom?
zblz commentedon Oct 9, 2015
In L735 of mathtext.py there is this comment:
It seemed to me that the fourth size was the one giving problems in {} and () as well, so removing them as initially done for [], I got:
at all sizes! Maybe we should consider removing the fourth size outright.
rsnape commentedon Oct 9, 2015
@zblz - my understanding is that 28 and 29 are just the basic paren glyphs and the
\Biggbraces fall back on that. They actually give the same glyph as the lookup for'('and')'as far as I can tell. I'd like to find the table too - having done quite a bit of legwork to isolate, I'd like to submit a PR for this one :)rsnape commentedon Oct 9, 2015
@zblz Yes - maybe a good call to remove them for all, unless it's easy to find exactly which are available and why. The removal solution seems better than falling back on
()for braces too (IMHO)rsnape commentedon Oct 9, 2015
Well - I found this which seems to show the lookup, but it does show
33or0x21mapping torightparenBigg- and0x28and0x29mapping toleftbraceBiggandrightbraceBiggrespectively. This implies that the line I highlighted is correct. So maybe the bug is in the lookup or font definition, rather than that line mapping sized delimiters to glyphs._EDIT_ Pretty sure this may be relevant - in the ascii table
0x21is!,0x28is(and0x29is). This looks like a lookup defaulting to ascii lookup rather than glyph index, I think.22 remaining items
ksunden commentedon May 2, 2025
@QuLogic re-milestoning this for 3.11.0 to match the PR you put in, if you think these should go in a micro release, feel free to re-milestone both.
QuLogic commentedon Apr 10, 2026
The
text-overhaulbranch is now merged tomain.[-]Unexpected replacement of \right) with exlamation point in MathTextParser output[/-][+]Unexpected replacement of \right) with exclamation point in MathTextParser output[/+]