Repository navigation
Closed
Milestone
Description
The documentation says that registering the backend should work as well (or better) than use('pgf').
This breaks when using unicode because the TeX strings are handled by the default matplotlib texmanager instead of the pgf backend.
If there is no way to disable the standard texmanager when rendering using the pgf backend, the documentation should be changed to make this problem clear.
import matplotlib as mpl
#mpl.use("pgf") # works
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pgf import FigureCanvasPgf # does not work
mpl.backend_bases.register_backend('pdf', FigureCanvasPgf) #
mpl.rcParams.update({
'font.family': 'serif',
'text.usetex': True,
'pgf.rcfonts': False,
'pgf.preamble': r'\usepackage{unicode-math}',
})
plt.plot([1, 2], [3, 4])
plt.xlabel(r'$α$')
plt.savefig('foo.pdf')Traceback (most recent call last):
File "baz.py", line 19, in <module>
plt.savefig('baz.pdf')
File "/usr/lib/python3.5/site-packages/matplotlib/pyplot.py", line 577, in savefig
res = fig.savefig(*args, **kwargs)
File "/usr/lib/python3.5/site-packages/matplotlib/figure.py", line 1476, in savefig
self.canvas.print_figure(*args, **kwargs)
File "/usr/lib/python3.5/site-packages/matplotlib/backends/backend_qt5agg.py", line 162, in print_figure
self.draw()
File "/usr/lib/python3.5/site-packages/matplotlib/backends/backend_qt5agg.py", line 148, in draw
FigureCanvasAgg.draw(self)
File "/usr/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py", line 469, in draw
self.figure.draw(self.renderer)
File "/usr/lib/python3.5/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/matplotlib/figure.py", line 1085, in draw
func(*args)
File "/usr/lib/python3.5/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 2110, in draw
a.draw(renderer)
File "/usr/lib/python3.5/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/matplotlib/axis.py", line 1128, in draw
self.label.draw(renderer)
File "/usr/lib/python3.5/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/matplotlib/text.py", line 595, in draw
bbox, info, descent = self._get_layout(renderer)
File "/usr/lib/python3.5/site-packages/matplotlib/text.py", line 320, in _get_layout
ismath=ismath)
File "/usr/lib/python3.5/site-packages/matplotlib/backends/backend_agg.py", line 223, in get_text_width_height_descent
renderer=self)
File "/usr/lib/python3.5/site-packages/matplotlib/texmanager.py", line 670, in get_text_width_height_descent
dvifile = self.make_dvi(tex, fontsize)
File "/usr/lib/python3.5/site-packages/matplotlib/texmanager.py", line 394, in make_dvi
texfile = self.make_tex(tex, fontsize)
File "/usr/lib/python3.5/site-packages/matplotlib/texmanager.py", line 309, in make_tex
fh.write(s.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode character '\u03b1' in position 298: ordinal not in range(128)
Activity
mdboom commentedon Oct 13, 2015
Cc: @pwuertz
pwuertz commentedon Oct 13, 2015
I am pretty sure that it did work at some point, but it's true that usetex true + Unicode cannot be handled by other backends that are using pdflatex. So maybe it should be made clear that this combination of parameters is only possible with xe or lualatex.
What puzzles me is the error you are seeing. Your savefig is calling into the qt5 backend instead of pgf. I will try to find out why.
QuLogic commentedon Oct 13, 2015
Why's that?
pdflatexmostly will work with UTF-8 if you set the input encoding, though it somewhat depends on what version of everything is installed.pwuertz commentedon Oct 13, 2015
AFAIK pdflatex has no support for unicode fonts and generally doesn't know how to handle non-ascii characters. By including inputenc and a few other packages you can add some hardcoded character-to-glyph mappings so you can get away with common language specific characters. But this isn't exactly what you would call "unicode support".
pwuertz commentedon Oct 13, 2015
Ok, this is a bit confusing, and I'm not sure how to wrap this up in the documentation.
The savefig command actually works, although you see an exception later. The reason for this is that the Qt5 / Agg backend is (and stays) the default backend and after saving the figure it additionally tries to draw its own canvas once. This then fails when the agg backend uses pdflatex to process your unicode label.
One could argue that the additional
draw()call afterprint_figure()isn't required, so if you are not using the GUI the GUI shouldn't complain about the usetex configuration. In case you are using the GUI and backend_pgf for PDF output you'd have to change the rc params to something compatible to qt5 / agg though. This usecase is actually my motivation for preferring the register_backend solution - being able to interact with the figure and to save PGF->PDF figures within the same run.itoijala commentedon Oct 14, 2015
So basically using the
register_backendapproach I have to make sure that the labels are compatible with pdflatex. For me that means I will have to use thempl.useapproach. Otherwise using lualatex doesn't have any advantages.pwuertz commentedon Oct 14, 2015
Not really, the problem is the usetex flag. It isn't really required for backend pgf since all text is processed by tex anyways, so you could just omit it. The GUI will try to process your labels without pdflatex and probably won't be able to interpret more complex latex macros, which looks weird but it won't crash on it. Unfortunately matplotlib internally misuses(?) the usetex flag for some other decisions as well, but if you don't care you can just set usetex=False.
itoijala commentedon Oct 14, 2015
I am using usetex to get the tick labels in the math font.
I guess that's not so important.
pwuertz commentedon Oct 14, 2015
Ah yes, this is one of the things I meant by "other decisions". According to the documentation enabling "usetex" means that the non-latex backends should delegate text rendering to the latex manager and include the result, instead of using the internal matplotlib latex formatter. Unfortunately this flag is also being used for changing the style of the tick labels (putting them in math mode) instead of using a dedicated switch.
By the way, I just realized that there is a setting for enabling unicode input encoding in pdflatex/latexmanager. Maybe this is of interest to you?
http://matplotlib.org/users/usetex.html#usetex-with-unicode
Anyway, if you are not planning on using the GUI and a non-GUI-savefig within the same workflow just go with
use("pgf")if this turns out to be more trouble than its worth.ArchangeGabriel commentedon Jun 26, 2016
I’m not sure whether this is what I’m facing, because your guys talk about pdflatex while I definitively use xelatex for pgf rendering. But still, needing both pdf export and interactive plots, I’m trying the “registering” method, and when saving a pdf:
ArchangeGabriel commentedon Jun 26, 2016
Oh, indeed the figure is saved (which is the most important point to me), and I also rely on ticks to be in math mode. ;)
ArchangeGabriel commentedon Jun 26, 2016
And finally, I was indeed able to work around this by setting
text.latex.unicode = Trueand also addingtext.latex.preambleconfig with the relevant packages.ArchangeGabriel commentedon Feb 9, 2017
Just for the record, this is obviously still an issue with 2.0.
6 remaining items
github-actions commentedon Mar 17, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
QuLogic commentedon Apr 18, 2023
The traceback is still happening, but it's a little different now:
This one is because
pgf.preambledoesn't get applied to the latex drawing in Qt.But we go through a lot of trouble to use the right canvas when saving, so it's weird that Qt is drawing here. That's because the QtAgg backend overrides
print_figureto calldrawafter. This also occurs in the Wx backend, but not GTK or Tk.Remove print_figure overrides in backend subclasses
Remove print_figure overrides in backend subclasses
Remove print_figure overrides in backend subclasses
Remove print_figure overrides in backend subclasses
Remove print_figure overrides in backend subclasses