Matplotlib + Latex Rendering Labels на португальском языке

Начнем с самого начала:

Версия для питона: 1.1.0

Версия Matplotlib: 1.3.1

Латексная версия: pdfTeX 3.1415926-2.4-1.40.13 (TeX Live 2012/Debian)

Внутри Ubuntu 12.04 LTS.

Я хочу построить что-то вроде того, что ниже, внутри сеанса ноутбука Ipython.

# 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'))

Йелдс:

Тоже самое, что и выше.

Есть ли способ ввести заданные символы, такие как: á, à, é, í, õ, ú и т. д.?


person LuizAngioletti    schedule 06.11.2013    source источник
comment
Я только что понял, что если я закомментирую параметр: 'text.usetex': True и поставлю перед строками, содержащими символы с диакритическими знаками, u'some áéí', я смогу распечатать полезный график, но потеряю всю красивость LaTeX.   -  person LuizAngioletti    schedule 07.11.2013


Ответы (2)


Нашел!

Просто используйте другой параметр 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!

person LuizAngioletti    schedule 08.11.2013

Вы можете использовать нотацию LaTeX следующим образом:

plt.xlabel(r'Di\^ametro de Agua Doce')

введите здесь описание изображения

Вот таблица, показывающая нотацию LaTeX для различных символов с диакритическими знаками.

person unutbu    schedule 06.11.2013
comment
Здесь это почему-то не работает. Я все еще получаю ошибку 'ascii' codec can't encode character u'\xe2' in position 299: ordinal not in range(128), как указано выше. - person LuizAngioletti; 07.11.2013
comment
u'\xe2' — это символ Юникода â (LATIN SMALL LETTER A WITH CIRCUMFLEX). Если вы не введете этот символ в записную книжку IPython, не должно быть никакого способа получить эту ошибку. - person unutbu; 07.11.2013
comment
Извините, разве это не то, что мы пытаемся напечатать? Даже с синтаксисом LaTeX? - person LuizAngioletti; 07.11.2013
comment
Цель состоит в том, чтобы заставить matplotlib/LaTeX генерировать символ â, но для этого вместо этого вы указываете '\^a'. - person unutbu; 07.11.2013
comment
вы были правы, там был потерянный â. Я исправил это и нашел свое решение: здесь - person LuizAngioletti; 08.11.2013