Repository navigation
Closed
Labels
Milestone
Description
Bug report
When making a plot using the 'classic' style, matplotlib overrides the default value for text.latex.unicode, setting it to False. This causes a problem for any plot that has negative numbers in any label, because matplotlib now uses a unicode symbol to represent the negative sign.
Code for reproduction
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['text.usetex'] = True
# Example data
t = np.arange(-1.0, 1.0 + 0.01, 0.01)
s = np.cos(4 * np.pi * t) + 2
plt.plot(t, s)
with plt.style.context('classic'):
plt.savefig('tex_demo')Actual outcome
The following traceback:
File "test_mpl.py", line 14, in <module>
plt.savefig('tex_demo')
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/pyplot.py", line 707, in savefig
res = fig.savefig(*args, **kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/figure.py", line 1763, in savefig
self.canvas.print_figure(*args, **kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/backend_bases.py", line 2234, in print_figure
**kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/backends/backend_agg.py", line 548, in print_png
FigureCanvasAgg.draw(self)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/backends/backend_agg.py", line 467, in draw
self.figure.draw(self.renderer)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/artist.py", line 68, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/figure.py", line 1240, in draw
renderer, self, artists, self.suppressComposite)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/artist.py", line 68, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/axes/_base.py", line 2386, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/artist.py", line 68, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/axis.py", line 1118, in draw
tick.draw(renderer)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/artist.py", line 68, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/axis.py", line 268, in draw
self.label1.draw(renderer)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/artist.py", line 68, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/text.py", line 797, in draw
mtext=mtext)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/backends/backend_agg.py", line 255, in draw_tex
Z = texmanager.get_grey(s, size, self.dpi)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/texmanager.py", line 585, in get_grey
pngfile = self.make_png(tex, fontsize, dpi)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/texmanager.py", line 508, in make_png
dvifile = self.make_dvi(tex, fontsize)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/texmanager.py", line 400, in make_dvi
texfile = self.make_tex(tex, fontsize)
File "/Users/goldbaum/Documents/matplotlib-git/lib/matplotlib/texmanager.py", line 311, in make_tex
if rcParams['text.latex.unicode']:
UnicodeEncodeError: 'ascii' codec can't encode character '\u2212' in position 298: ordinal not in range(128)
Expected outcome
The plot should be saved to disk without erroring. The script runs without error on matplotlib 1.5.3.
Matplotlib version
Matplotlib 2.0.0 on OSX, installed via pip.
Activity
ngoldbaum commentedon Apr 3, 2017
Ah, it works if the bits that interact with matplotlib look like this:
instead of this:
So I guess that explains why no one noticed until now.
Unfortunately the way the script runs in the description is more or less how yt is using matplotlib. It's kind of a hack, but it's the only way I could figure out to work around #6518 and make sure yt plots have the same fonts they had under matplotlib 1.5.3.
tacaswell commentedon Apr 4, 2017
I can reproduce this, but do not understand why....
I think the important thing is if the figure (and hence axes and such) are created in the context manager or not.
The three obviously relavent rcparams ('text.latex.unicode', 'text.usetex', 'axes.unicode_minus') are the same in the new default and classic mode (or I can not read which is also possible).
A workaround might be to set
'axes.unicode_minus'toFalsetacaswell commentedon Apr 4, 2017
This behaves as expected, but again, not quite sure why.
ngoldbaum commentedon Apr 4, 2017
According to the API docs,
plt.style.context({'text.usetex': True}, 'classic')is equivalent toplt.style.context({'text.usetex': True})(the second argument tocontextis a boolean). But I see what you're getting at, this also triggers a unicode error:tacaswell commentedon Apr 4, 2017
hmm, I mis-remembered that API then...It is a list of styles, not
*argsof styles:and that order makes more sense!
ngoldbaum commentedon Apr 4, 2017
FWIW I've mitigated this on the yt side with yt PR 2573 (https://bitbucket.org/yt_analysis/yt/pull-requests/2573). I guess using the classic style just to get the fonts I want was a bit of a blunt instrument.
anntzer commentedon Jun 18, 2019
text.latex.unicode is now on by default, per #11381 (not on the 2.2.x branch, FWIW).
However this now fails with
but I have a fix coming up for that...