Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incorrect detection of text.latex.unicode=True #2649

Closed
insertinterestingnamehere opened this issue Dec 5, 2013 · 5 comments
Closed

incorrect detection of text.latex.unicode=True #2649

insertinterestingnamehere opened this issue Dec 5, 2013 · 5 comments

Comments

@insertinterestingnamehere

When loading rcparameters from a custom matplotlibrc file it appears that Matplotlib is unable to find the value for text.latex.unicode properly.
After trying a variety of configurations I have narrowed it down to the options text.usetex : True and text.latex.unicode : True in the matplotlibrc file.
I can replicate the error with all the other options set to default.
The error does not appear when plotting from 0 to 1.
It does appear when plotting from -1 to 1.
Oddly enough, it does not appear when I set the parameter manually via

plt.rc('text', usetex=True)

From this, it seems to me that something is wrong with how the custom matplotlibrc file is being applied.

Here is the traceback:


UnicodeEncodeError Traceback (most recent call last)
in ()
59 plt.clf()
60
---> 61 node_project()
62 runge_plot()
63 cheb_polys()

in node_project()
21 plt.xlim((-1.05, 1.05))
22 plt.ylim((-.25, 1.25))
---> 23 plt.savefig("node_project.pdf")
24 plt.clf()
25

c:\Anaconda\lib\site-packages\matplotlib\pyplot.pyc in savefig(_args, *_kwargs)
559 def savefig(_args, *_kwargs):
560 fig = gcf()
--> 561 return fig.savefig(_args, *_kwargs)
562
563

c:\Anaconda\lib\site-packages\matplotlib\figure.pyc in savefig(self, _args, *_kwargs)
1419 self.set_frameon(frameon)
1420
-> 1421 self.canvas.print_figure(_args, *_kwargs)
1422
1423 if frameon:

c:\Anaconda\lib\site-packages\matplotlib\backends\backend_qt4agg.pyc in print_figure(self, _args, *_kwargs)
165
166 def print_figure(self, _args, *_kwargs):
--> 167 FigureCanvasAgg.print_figure(self, _args, *_kwargs)
168 self.draw()

c:\Anaconda\lib\site-packages\matplotlib\backend_bases.pyc in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, *_kwargs)
2218 orientation=orientation,
2219 bbox_inches_restore=_bbox_inches_restore,
-> 2220 *_kwargs)
2221 finally:
2222 if bbox_inches and restore_bbox:

c:\Anaconda\lib\site-packages\matplotlib\backend_bases.pyc in print_pdf(self, _args, *_kwargs)
1950 from backends.backend_pdf import FigureCanvasPdf # lazy import
1951 pdf = self.switch_backends(FigureCanvasPdf)
-> 1952 return pdf.print_pdf(_args, *_kwargs)
1953
1954 def print_pgf(self, _args, *_kwargs):

c:\Anaconda\lib\site-packages\matplotlib\backends\backend_pdf.pyc in print_pdf(self, filename, **kwargs)
2350 width, height, image_dpi, RendererPdf(file, image_dpi),
2351 bbox_inches_restore=_bbox_inches_restore)
-> 2352 self.figure.draw(renderer)
2353 renderer.finalize()
2354 finally:

c:\Anaconda\lib\site-packages\matplotlib\artist.pyc in draw_wrapper(artist, renderer, _args, *_kwargs)
53 def draw_wrapper(artist, renderer, _args, *_kwargs):
54 before(artist, renderer)
---> 55 draw(artist, renderer, _args, *_kwargs)
56 after(artist, renderer)
57

c:\Anaconda\lib\site-packages\matplotlib\figure.pyc in draw(self, renderer)
1032 dsu.sort(key=itemgetter(0))
1033 for zorder, a, func, args in dsu:
-> 1034 func(*args)
1035
1036 renderer.close_group('figure')

c:\Anaconda\lib\site-packages\matplotlib\artist.pyc in draw_wrapper(artist, renderer, _args, *_kwargs)
53 def draw_wrapper(artist, renderer, _args, *_kwargs):
54 before(artist, renderer)
---> 55 draw(artist, renderer, _args, *_kwargs)
56 after(artist, renderer)
57

c:\Anaconda\lib\site-packages\matplotlib\axes.pyc in draw(self, renderer, inframe)
2084
2085 for zorder, a in dsu:
-> 2086 a.draw(renderer)
2087
2088 renderer.close_group('axes')

c:\Anaconda\lib\site-packages\matplotlib\artist.pyc in draw_wrapper(artist, renderer, _args, *_kwargs)
53 def draw_wrapper(artist, renderer, _args, *_kwargs):
54 before(artist, renderer)
---> 55 draw(artist, renderer, _args, *_kwargs)
56 after(artist, renderer)
57

c:\Anaconda\lib\site-packages\matplotlib\axis.pyc in draw(self, renderer, _args, *_kwargs)
1091 ticks_to_draw = self._update_ticks(renderer)
1092 ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
-> 1093 renderer)
1094
1095 for tick in ticks_to_draw:

c:\Anaconda\lib\site-packages\matplotlib\axis.pyc in _get_tick_bboxes(self, ticks, renderer)
1040 for tick in ticks:
1041 if tick.label1On and tick.label1.get_visible():
-> 1042 extent = tick.label1.get_window_extent(renderer)
1043 ticklabelBoxes.append(extent)
1044 if tick.label2On and tick.label2.get_visible():

c:\Anaconda\lib\site-packages\matplotlib\text.pyc in get_window_extent(self, renderer, dpi)
752 raise RuntimeError('Cannot get window extent w/o renderer')
753
--> 754 bbox, info, descent = self._get_layout(self._renderer)
755 x, y = self.get_position()
756 x, y = self.get_transform().transform_point((x, y))

c:\Anaconda\lib\site-packages\matplotlib\text.pyc in _get_layout(self, renderer)
327 w, h, d = get_text_width_height_descent(clean_line,
328 self._fontproperties,
--> 329 ismath=ismath)
330 else:
331 w, h, d = 0, 0, 0

c:\Anaconda\lib\site-packages\matplotlib\backends\backend_pdf.pyc in get_text_width_height_descent(self, s, prop, ismath)
1950 fontsize = prop.get_size_in_points()
1951 w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
-> 1952 renderer=self)
1953 return w, h, d
1954

c:\Anaconda\lib\site-packages\matplotlib\texmanager.pyc in get_text_width_height_descent(self, tex, fontsize, renderer)
666 else:
667 # use dviread. It sometimes returns a wrong descent.
--> 668 dvifile = self.make_dvi(tex, fontsize)
669 dvi = dviread.Dvi(dvifile, 72 * dpi_fraction)
670 try:

c:\Anaconda\lib\site-packages\matplotlib\texmanager.pyc in make_dvi(self, tex, fontsize)
391
392 if DEBUG or not os.path.exists(dvifile):
--> 393 texfile = self.make_tex(tex, fontsize)
394 outfile = basefile + '.output'
395 command = self._get_shell_cmd(

c:\Anaconda\lib\site-packages\matplotlib\texmanager.pyc in make_tex(self, tex, fontsize)
306 else:
307 try:
--> 308 fh.write(s.encode('ascii'))
309 except UnicodeEncodeError as err:
310 mpl.verbose.report("You are using unicode and latex, but "

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2212' in position 297: ordinal not in range(128)

By inserting some print statements into the source code it can be seen that the string s is

\documentclass{article}
\usepackage{type1cm}
\renewcommand{\rmdefault}{pnc}
\usepackage{helvet}
\usepackage{courier}
\usepackage{textcomp}


\usepackage[papersize={72in,72in},body={70in,70in},margin={1in,1in}]{geometry}
\pagestyle{empty}
\begin{document}
\fontsize{12.000000}{15.000000}{\sffamily −1.0}
\end{document}

From inserting another print statement it can be seen that text.latex.unicode is False.

@insertinterestingnamehere
Copy link
Author

A simple way to replicate the error is to make a custom matplotlibrc file with text.usetex and text.latex.unicode set to True and then do something like

import numpy as np
import matplotlib
matplotlib.rcParams = matplotlib.rc_params_from_file('./matplotlibrc')
from matplotlib import pyplot as plt
X = np.linspace(-1, 1, 100)
plt.plot(X, Y)
plt.savefig('test.pdf')
plt.clf()

Also, I'm using Windows with the Anaconda Python distribution's most recent 64 bit build of release 1.3.1.
I have verified with my coworkers that this error also appears on Lunux and Mac.

@insertinterestingnamehere
Copy link
Author

Under further inspection, it appears that, the custom rc parameters are loaded properly but are reset to default at some point before the plot finishes rendering.

@insertinterestingnamehere
Copy link
Author

Okay, we have a fix on our end for the plots we were generating.
The issue was that we were importing pyplot in one of the files we importing earlier in the file used to generate the plots. Here's a generic example:

# foo.py
import otherpackages
from matplotlib import pyplot as plt
def func():
    # stuff with otherpackages

def func2():
    # stuff using pyplot

and then

# plots.py
import otherpackages
from foo import func    # This import statement should have come later
import matplotlib
matplotlib.rcParams = matplotlib.rc_params_from_file('./matplotlibrc')
from matplotlib import pyplot as plt

# make and save a plot using savefig

Switching the order of the imports allowed the script to run fine.

This could still be a bug since I would expect that, after importing pyplot, loading a new matplotlibrc file would do nothing, print a warning, or raise an error of some sort.
As it is it appears that the plot was partially generated using the new setting and the error arises when the default settings are applied.
Is this meant to be the default behavior?

@pwuertz
Copy link
Contributor

pwuertz commented Jan 28, 2014

The matplotlibrc file contains the defaults for plotting figures as well as the default backend and its configuration. Changing the plotting defaults like fonts or colours is possible at any time, while backend selection and configuration only affect the first instantiation of the backend - which happens when you import pyplot.
This is indeed a known limitation at the time, but I see the confusion caused by having backend and figure defaults in the same rc file.

@tacaswell
Copy link
Member

I am closing this as it doesn't look like there is an actually bug.

I think this has also been (partially?) addressed by the style module (which is shipping in 1.4.0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants