Skip to main content
 首页 » 编程设计

python之Matplotlib + Latex 葡萄牙语渲染标签

2025年05月04日15qq78292959

让我们从头开始:

Ipython 版本:1.1.0

Matplotlib 版本:1.3.1

Latex 版本:pdfTeX 3.1415926-2.4-1.40.13 (TeX Live 2012/Debian)

在 Ubuntu 12.04 LTS 中。

我想在 Ipython Notebook session 中绘制类似于下面的内容。

# Using the magic encoding 
# -*- coding: utf-8 -*- 
 
fig_width_pt =  512#246.0               # Get this from LaTeX using  
                                        # \showthe\columnwidth 
inches_per_pt = 1.0/72.27               # Convert pt to inch 
golden_mean = (sqrt(5)-1.0)/2.0         # Aesthetic ratio 
fig_width = fig_width_pt*inches_per_pt  # width in inches 
fig_height = fig_width*golden_mean      # height in inches 
fig_size =  [fig_width,fig_height] 
 
params = {'backend': 'ps', 
          'axes.labelsize': 10, 
          'text.fontsize': 10, 
          'legend.fontsize': 10, 
          'xtick.labelsize': 10, 
          'ytick.labelsize': 10, 
          'text.usetex': True, 
          'figure.figsize': fig_size} 
rcParams.update(params) 
plt.xlabel(r'$Diâmetro de Agua Doce$') 
plt.ylabel('Diametro de Agua Salgada') 
plt.title('Distribuicao da Populacao de Salmoes') 
 
alaska_plot_list0 = list(alaska[:,0]) 
alaska_plot_list1 = list(alaska[:,1]) 
scatter(alaska_plot_list0, alaska_plot_list1,  
        label="Alaska", color='green', alpha=.5) 
 
canada_plot_list0 = list(canada[:,0]) 
canada_plot_list1 = list(canada[:,1]) 
scatter(canada_plot_list0, canada_plot_list1, label="Canada", alpha=.5) 
#scatter(alaska[:,0], alaska[:,1], 'o', alpha=.5, label="Alaska") 
#scatter(canada[:,0], canada[:,1], 'o', alpha=.5, label="Canada") 
plt.legend() 
plt.grid() 
savefig('distribuicao.pdf') 

请注意这一行:

plt.xlabel(r'$Diâmetro de Agua Doce$') 

这是在 LaTeX 环境中使用特殊(或重音字符)的尝试,因此我可以在生成的图表中正确拼写葡萄牙语单词。

这种方法会产生以下错误:

--------------------------------------------------------------------------- 
UnicodeDecodeError                        Traceback (most recent call last) 
<ipython-input-10-a1d75b5e9ea2> in <module>() 
     33 plt.legend() 
     34 plt.grid() 
---> 35 savefig('distribuicao.pdf') 
 
/usr/local/lib/python2.7/dist-packages/matplotlib/pyplot.pyc in savefig(*args, **kwargs) 
    559 def savefig(*args, **kwargs): 
    560     fig = gcf() 
--> 561     return fig.savefig(*args, **kwargs) 
    562  
    563  
 
/usr/local/lib/python2.7/dist-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: 
 
/usr/local/lib/python2.7/dist-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: 
 
/usr/local/lib/python2.7/dist-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): 
 
/usr/local/lib/python2.7/dist-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: 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-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') 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-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') 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-packages/matplotlib/axis.pyc in draw(self, renderer, *args, **kwargs) 
   1103         self._update_label_position(ticklabelBoxes, ticklabelBoxes2) 
   1104  
-> 1105         self.label.draw(renderer) 
   1106  
   1107         self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2) 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-packages/matplotlib/text.pyc in draw(self, renderer) 
    545         renderer.open_group('text', self.get_gid()) 
    546  
--> 547         bbox, info, descent = self._get_layout(renderer) 
    548         trans = self.get_transform() 
    549  
 
/usr/local/lib/python2.7/dist-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 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-packages/matplotlib/texmanager.pyc in get_text_width_height_descent(self, tex, fontsize, renderer) 
    664         else: 
    665             # use dviread. It sometimes returns a wrong descent. 
--> 666             dvifile = self.make_dvi(tex, fontsize) 
    667             dvi = dviread.Dvi(dvifile, 72 * dpi_fraction) 
    668             try: 
 
/usr/local/lib/python2.7/dist-packages/matplotlib/texmanager.pyc in make_dvi(self, tex, fontsize) 
    385             return self.make_dvi_preview(tex, fontsize) 
    386  
--> 387         basefile = self.get_basefile(tex, fontsize) 
    388         dvifile = '%s.dvi' % basefile 
    389  
 
/usr/local/lib/python2.7/dist-packages/matplotlib/texmanager.pyc in get_basefile(self, tex, fontsize, dpi) 
    221                      self.get_custom_preamble(), str(dpi or '')]) 
    222         # make sure hash is consistent for all strings, regardless of encoding: 
--> 223         bytes = unicode(s).encode('utf-8') 
    224         return os.path.join(self.texcache, md5(bytes).hexdigest()) 
    225  
 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128) 
 
<matplotlib.figure.Figure at 0x4727a10> 

在网上搜索,所以,我发现了一些其他尝试排版重音单词的方法,我找到的所有资源都无法解决我的问题。

像这样的尝试会导致相应的错误消息:

plt.xlabel(u'Diâmetro de Agua Doce') 

产量:

--------------------------------------------------------------------------- 
UnicodeEncodeError                        Traceback (most recent call last) 
<ipython-input-11-a1e2e4496433> in <module>() 
     33 plt.legend() 
     34 plt.grid() 
---> 35 savefig('distribuicao.pdf') 
 
/usr/local/lib/python2.7/dist-packages/matplotlib/pyplot.pyc in savefig(*args, **kwargs) 
    559 def savefig(*args, **kwargs): 
    560     fig = gcf() 
--> 561     return fig.savefig(*args, **kwargs) 
    562  
    563  
 
/usr/local/lib/python2.7/dist-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: 
 
/usr/local/lib/python2.7/dist-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: 
 
/usr/local/lib/python2.7/dist-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): 
 
/usr/local/lib/python2.7/dist-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: 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-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') 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-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') 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-packages/matplotlib/axis.pyc in draw(self, renderer, *args, **kwargs) 
   1103         self._update_label_position(ticklabelBoxes, ticklabelBoxes2) 
   1104  
-> 1105         self.label.draw(renderer) 
   1106  
   1107         self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2) 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-packages/matplotlib/text.pyc in draw(self, renderer) 
    545         renderer.open_group('text', self.get_gid()) 
    546  
--> 547         bbox, info, descent = self._get_layout(renderer) 
    548         trans = self.get_transform() 
    549  
 
/usr/local/lib/python2.7/dist-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 
 
/usr/local/lib/python2.7/dist-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  
 
/usr/local/lib/python2.7/dist-packages/matplotlib/texmanager.pyc in get_text_width_height_descent(self, tex, fontsize, renderer) 
    664         else: 
    665             # use dviread. It sometimes returns a wrong descent. 
--> 666             dvifile = self.make_dvi(tex, fontsize) 
    667             dvi = dviread.Dvi(dvifile, 72 * dpi_fraction) 
    668             try: 
 
/usr/local/lib/python2.7/dist-packages/matplotlib/texmanager.pyc in make_dvi(self, tex, fontsize) 
    389  
    390         if DEBUG or not os.path.exists(dvifile): 
--> 391             texfile = self.make_tex(tex, fontsize) 
    392             outfile = basefile + '.output' 
    393             command = self._get_shell_cmd( 
 
/usr/local/lib/python2.7/dist-packages/matplotlib/texmanager.pyc in make_tex(self, tex, fontsize) 
    304             else: 
    305                 try: 
--> 306                     fh.write(s.encode('ascii')) 
    307                 except UnicodeEncodeError as err: 
    308                     mpl.verbose.report("You are using unicode and latex, but " 
 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe2' in position 299: ordinal not in range(128) 
 
<matplotlib.figure.Figure at 0x4613e90> 

和上面的完全一样。

和:

plt.xlabel('Diâmetro de Agua Doce'.decode('utf-8')) 

产量:

也同上。

有没有办法输入一组字符,例如:á、à、é、í、õ、ú 等等?

请您参考如下方法:

找到了!

只需使用另一个 matplotlib/LaTeX 参数!

'text.latex.unicode':True 

所以,原来的参数表变成了:

params = {'backend': 'ps', 
      'axes.labelsize': 10, 
      'text.fontsize': 10, 
      'legend.fontsize': 10, 
      'xtick.labelsize': 10, 
      'ytick.labelsize': 10, 
      'text.usetex': True, 
      'text.latex.unicode':True 
      'figure.figsize': fig_size} 
rcParams.update(params) 

并且字符串必须以 unicode 字符串说明符开头:

plt.xlabel(u'Diâmetro de Água Doce') 

不需要 LaTeX 特殊字符映射。

谢谢@unutbu!