Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 353385d

Browse files
committed
make texmanager respect changes to rcParams after initial import
svn path=/trunk/matplotlib/; revision=3562
1 parent 2593438 commit 353385d

2 files changed

Lines changed: 83 additions & 79 deletions

File tree

CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2007-07-18 make usetex respect changes to rcParams. texmanager used to
2+
only configure itself when it was created, now it
3+
reconfigures when rcParams are changed. Thank you Alexander
4+
Schmolck for contributing a patch - DSD
5+
16
2007-07-17 added validation to setting and changing rcParams - DSD
27

38
2007-07-17 bugfix segfault in transforms module. Thanks Ben North for

lib/matplotlib/texmanager.py

Lines changed: 78 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,23 @@
3333
3434
"""
3535

36-
import glob, md5, os, shutil, sys, warnings
37-
from tempfile import gettempdir
38-
from matplotlib import get_configdir, get_home, get_data_path, \
39-
rcParams, verbose
36+
import copy, glob, md5, os, shutil, sys, warnings
37+
import numpy as npy
38+
import matplotlib as mpl
39+
from matplotlib import rcParams
4040
from matplotlib._image import readpng
41-
from matplotlib.numerix import ravel, where, array, \
42-
zeros, Float, absolute, nonzero, sqrt
4341

44-
debug = False
42+
DEBUG = False
4543

4644
if sys.platform.startswith('win'): cmd_split = '&'
4745
else: cmd_split = ';'
4846

49-
5047
def get_dvipng_version():
5148
stdin, stdout = os.popen4('dvipng -version')
5249
for line in stdout:
5350
if line.startswith('dvipng '):
5451
version = line.split()[-1]
55-
verbose.report('Found dvipng version %s'% version,
52+
mpl.verbose.report('Found dvipng version %s'% version,
5653
'helpful')
5754
return version
5855
raise RuntimeError('Could not obtain dvipng version')
@@ -64,14 +61,13 @@ class TexManager:
6461
working dir
6562
"""
6663

67-
oldpath = get_home()
68-
if oldpath is None: oldpath = get_data_path()
64+
oldpath = mpl.get_home()
65+
if oldpath is None: oldpath = mpl.get_data_path()
6966
oldcache = os.path.join(oldpath, '.tex.cache')
7067

71-
configdir = get_configdir()
68+
configdir = mpl.get_configdir()
7269
texcache = os.path.join(configdir, 'tex.cache')
7370

74-
7571
if os.path.exists(oldcache):
7672
print >> sys.stderr, """\
7773
WARNING: found a TeX cache dir in the deprecated location "%s".
@@ -82,6 +78,7 @@ class TexManager:
8278

8379
dvipngVersion = get_dvipng_version()
8480

81+
# mappable cache of
8582
arrayd = {}
8683
postscriptd = {}
8784
pscnt = 0
@@ -91,12 +88,15 @@ class TexManager:
9188
monospace = ('cmtt', '')
9289
cursive = ('pzc', r'\usepackage{chancery}')
9390
font_family = 'serif'
91+
font_families = ('serif', 'sans-serif', 'cursive', 'monospace')
9492

95-
font_info = {'new century schoolbook': ('pnc', r'\renewcommand{\rmdefault}{pnc}'),
93+
font_info = {'new century schoolbook': ('pnc',
94+
r'\renewcommand{\rmdefault}{pnc}'),
9695
'bookman': ('pbk', r'\renewcommand{\rmdefault}{pbk}'),
9796
'times': ('ptm', r'\usepackage{mathptmx}'),
9897
'palatino': ('ppl', r'\usepackage{mathpazo}'),
9998
'zapf chancery': ('pzc', r'\usepackage{chancery}'),
99+
'cursive': ('pzc', r'\usepackage{chancery}'),
100100
'charter': ('pch', r'\usepackage{charter}'),
101101
'serif': ('cmr', ''),
102102
'sans-serif': ('cmss', ''),
@@ -107,49 +107,37 @@ class TexManager:
107107
'computer modern roman': ('cmr', ''),
108108
'computer modern sans serif': ('cmss', ''),
109109
'computer modern typewriter': ('cmtt', '')}
110+
111+
_rc_cache = None
112+
_rc_cache_keys = ('text.latex.preamble', )\
113+
+ tuple('font.'+n for n in ('family', ) + font_families)
110114

111115
def __init__(self):
112116

113117
if not os.path.isdir(self.texcache):
114118
os.mkdir(self.texcache)
115-
if rcParams['font.family'].lower() in ('serif', 'sans-serif', 'cursive', 'monospace'):
116-
self.font_family = rcParams['font.family'].lower()
119+
ff = rcParams['font.family'].lower()
120+
if ff in self.font_families:
121+
self.font_family = ff
117122
else:
118123
warnings.warn('The %s font family is not compatible with LaTeX. serif will be used by default.' % ff)
119124
self.font_family = 'serif'
120-
self._fontconfig = self.font_family
121-
for font in rcParams['font.serif']:
122-
try:
123-
self.serif = self.font_info[font.lower()]
124-
except KeyError:
125-
continue
126-
else:
127-
break
128-
self._fontconfig += self.serif[0]
129-
for font in rcParams['font.sans-serif']:
130-
try:
131-
self.sans_serif = self.font_info[font.lower()]
132-
except KeyError:
133-
continue
134-
else:
135-
break
136-
self._fontconfig += self.sans_serif[0]
137-
for font in rcParams['font.monospace']:
138-
try:
139-
self.monospace = self.font_info[font.lower()]
140-
except KeyError:
141-
continue
142-
else:
143-
break
144-
self._fontconfig += self.monospace[0]
145-
for font in rcParams['font.cursive']:
146-
try:
147-
self.cursive = self.font_info[font.lower()]
148-
except KeyError:
149-
continue
150-
else:
151-
break
152-
self._fontconfig += self.cursive[0]
125+
126+
fontconfig = [self.font_family]
127+
for font_family, font_family_attr in \
128+
((ff, ff.replace('-', '_')) for ff in self.font_families):
129+
for font in rcParams['font.'+font_family]:
130+
if DEBUG: print 'family: %s, font: %s, info: %s'%(font_family,
131+
font, self.font_info[font.lower()])
132+
if font.lower() in self.font_info:
133+
setattr(self, font_family_attr,
134+
self.font_info[font.lower()])
135+
break
136+
else:
137+
warnings.warn('No LaTeX-compatible font found for the %s font family in rcParams. Using default.' % ff)
138+
setattr(self, font_family_attr, font_family)
139+
fontconfig.append(getattr(self, font_family_attr)[0])
140+
self._fontconfig = ''.join(fontconfig)
153141

154142
# The following packages and commands need to be included in the latex
155143
# file's preamble:
@@ -158,17 +146,33 @@ def __init__(self):
158146
while r'\usepackage{type1cm}' in cmd:
159147
cmd.remove(r'\usepackage{type1cm}')
160148
cmd = '\n'.join(cmd)
161-
self._font_preamble = '\n'.join([r'\usepackage{type1cm}',
162-
cmd,
163-
r'\usepackage{textcomp}'])
149+
self._font_preamble = '\n'.join([r'\usepackage{type1cm}', cmd,
150+
r'\usepackage{textcomp}'])
164151

165152
def get_basefile(self, tex, fontsize, dpi=None):
166-
s = tex + self._fontconfig + ('%f'%fontsize) + self.get_custom_preamble()
167-
if dpi: s += ('%s'%dpi)
168-
bytes = unicode(s).encode('utf-8') # make sure hash is consistent for all strings, regardless of encoding
153+
s = ''.join([tex, self.get_font_config(), '%f'%fontsize,
154+
self.get_custom_preamble(), str(dpi or '')])
155+
# make sure hash is consistent for all strings, regardless of encoding:
156+
bytes = unicode(s).encode('utf-8')
169157
return os.path.join(self.texcache, md5.md5(bytes).hexdigest())
170158

171159
def get_font_config(self):
160+
"Reinitializes self if rcParams self depends on have changed."
161+
if self._rc_cache is None:
162+
self._rc_cache = dict((k,None) for k in self._rc_cache_keys)
163+
changed = [par for par in self._rc_cache_keys if rcParams[par] != \
164+
self._rc_cache[par]]
165+
if changed:
166+
if DEBUG: print 'DEBUG following keys changed:', changed
167+
for k in changed:
168+
if DEBUG:
169+
print 'DEBUG %-20s: %-10s -> %-10s' % \
170+
(k, self._rc_cache[k], rcParams[k])
171+
# deepcopy may not be necessary, but feels more future-proof
172+
self._rc_cache[k] = copy.deepcopy(rcParams[k])
173+
if DEBUG: print 'DEBUG RE-INIT\nold fontconfig:', self._fontconfig
174+
self.__init__()
175+
if DEBUG: print 'DEBUG fontconfig:', self._fontconfig
172176
return self._fontconfig
173177

174178
def get_font_preamble(self):
@@ -222,34 +226,33 @@ def make_tex(self, tex, fontsize):
222226
try:
223227
fh.write(s)
224228
except UnicodeEncodeError, err:
225-
verbose.report("You are using unicode and latex, but have "
226-
"not enabled the matplotlib 'text.latex.unicode' "
227-
"rcParam.", 'helpful')
229+
mpl.verbose.report("You are using unicode and latex, but have "
230+
"not enabled the matplotlib 'text.latex.unicode' "
231+
"rcParam.", 'helpful')
228232
raise
229233

230234
fh.close()
231235

232236
return texfile
233237

234-
def make_dvi(self, tex, fontsize, force=0):
235-
if debug: force = True
238+
def make_dvi(self, tex, fontsize):
236239

237240
basefile = self.get_basefile(tex, fontsize)
238241
dvifile = '%s.dvi'% basefile
239242

240-
if force or not os.path.exists(dvifile):
243+
if DEBUG or not os.path.exists(dvifile):
241244
texfile = self.make_tex(tex, fontsize)
242245
outfile = basefile+'.output'
243246
command = self.get_shell_cmd('cd "%s"'% self.texcache,
244247
'latex -interaction=nonstopmode %s > "%s"'\
245248
%(os.path.split(texfile)[-1], outfile))
246-
verbose.report(command, 'debug')
249+
mpl.verbose.report(command, 'debug')
247250
exit_status = os.system(command)
248251
fh = file(outfile)
249252
if exit_status:
250253
raise RuntimeError(('LaTeX was not able to process the following \
251254
string:\n%s\nHere is the full report generated by LaTeX: \n\n'% repr(tex)) + fh.read())
252-
else: verbose.report(fh.read(), 'debug')
255+
else: mpl.verbose.report(fh.read(), 'debug')
253256
fh.close()
254257
for fname in glob.glob(basefile+'*'):
255258
if fname.endswith('dvi'): pass
@@ -258,54 +261,51 @@ def make_dvi(self, tex, fontsize, force=0):
258261

259262
return dvifile
260263

261-
def make_png(self, tex, fontsize, dpi, force=0):
262-
if debug: force = True
263-
264+
def make_png(self, tex, fontsize, dpi):
264265
basefile = self.get_basefile(tex, fontsize, dpi)
265266
pngfile = '%s.png'% basefile
266267

267268
# see get_rgba for a discussion of the background
268-
if force or not os.path.exists(pngfile):
269+
if DEBUG or not os.path.exists(pngfile):
269270
dvifile = self.make_dvi(tex, fontsize)
270271
outfile = basefile+'.output'
271272
command = self.get_shell_cmd('cd "%s"' % self.texcache,
272273
'dvipng -bg Transparent -D %s -T tight -o \
273274
"%s" "%s" > "%s"'%(dpi, os.path.split(pngfile)[-1],
274275
os.path.split(dvifile)[-1], outfile))
275-
verbose.report(command, 'debug')
276+
mpl.verbose.report(command, 'debug')
276277
exit_status = os.system(command)
277278
fh = file(outfile)
278279
if exit_status:
279280
raise RuntimeError('dvipng was not able to \
280281
process the flowing file:\n%s\nHere is the full report generated by dvipng: \
281282
\n\n'% dvifile + fh.read())
282-
else: verbose.report(fh.read(), 'debug')
283+
else: mpl.verbose.report(fh.read(), 'debug')
283284
fh.close()
284285
os.remove(outfile)
285286

286287
return pngfile
287288

288-
def make_ps(self, tex, fontsize, force=0):
289-
if debug: force = True
289+
def make_ps(self, tex, fontsize):
290290

291291
basefile = self.get_basefile(tex, fontsize)
292292
psfile = '%s.epsf'% basefile
293293

294-
if force or not os.path.exists(psfile):
294+
if DEBUG or not os.path.exists(psfile):
295295
dvifile = self.make_dvi(tex, fontsize)
296296
outfile = basefile+'.output'
297297
command = self.get_shell_cmd('cd "%s"'% self.texcache,
298298
'dvips -q -E -o "%s" "%s" > "%s"'\
299299
%(os.path.split(psfile)[-1],
300300
os.path.split(dvifile)[-1], outfile))
301-
verbose.report(command, 'debug')
301+
mpl.verbose.report(command, 'debug')
302302
exit_status = os.system(command)
303303
fh = file(outfile)
304304
if exit_status:
305305
raise RuntimeError('dvipng was not able to \
306306
process the flowing file:\n%s\nHere is the full report generated by dvipng: \
307307
\n\n'% dvifile + fh.read())
308-
else: verbose.report(fh.read(), 'debug')
308+
else: mpl.verbose.report(fh.read(), 'debug')
309309
fh.close()
310310
os.remove(outfile)
311311

@@ -346,21 +346,20 @@ def get_rgba(self, tex, fontsize=None, dpi=None, rgb=(0,0,0)):
346346
if not fontsize: fontsize = rcParams['font.size']
347347
if not dpi: dpi = rcParams['savefig.dpi']
348348
r,g,b = rgb
349-
key = tex, fontsize, dpi, tuple(rgb)
349+
key = tex, self.get_font_config(), fontsize, dpi, tuple(rgb)
350350
Z = self.arrayd.get(key)
351351

352352
if Z is None:
353-
# force=True to skip cacheing while debugging
354-
pngfile = self.make_png(tex, fontsize, dpi, force=False)
353+
pngfile = self.make_png(tex, fontsize, dpi)
355354
X = readpng(os.path.join(self.texcache, pngfile))
356355

357356
if (self.dvipngVersion < '1.6') or rcParams['text.dvipnghack']:
358357
# hack the alpha channel as described in comment above
359-
alpha = sqrt(1-X[:,:,0])
358+
alpha = npy.sqrt(1-X[:,:,0])
360359
else:
361360
alpha = X[:,:,-1]
362361

363-
Z = zeros(X.shape, Float)
362+
Z = npy.zeros(X.shape, npy.float)
364363
Z[:,:,0] = r
365364
Z[:,:,1] = g
366365
Z[:,:,2] = b

0 commit comments

Comments
 (0)