Не может изменить шрифт на Helvetica в Matplotlib в Python на Mac OS X 10.6

Я пытаюсь изменить шрифт matplotlib на helvetica, который я хотел бы использовать в графике PDF. Я пробую следующее:

import matplotlib
matplotlib.use('PDF')
import matplotlib.pylab as plt
from matplotlib import rc
plt.rcParams['ps.useafm'] = True
rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
plt.rcParams['pdf.fonttype'] = 42

Это не работает - когда я запускаю свой код с помощью -verbose-debug, я получаю ошибку:

backend WXAgg version 2.8.10.1
/Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/site-packages/matplotlib/__init__.py:833: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
findfont: Could not match :family=sans-serif:style=normal:variant=normal:weight=normal:stretch=normal:size=medium. Returning /Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/site-packages/matplotlib/mpl-data/fonts/ttf/Vera.ttf
Assigning font /F1 = /Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/site-packages/matplotlib/mpl-data/fonts/ttf/Vera.ttf
Embedding font /Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/site-packages/matplotlib/mpl-data/fonts/ttf/Vera.ttf
Writing TrueType font

Поэтому, по-видимому, он не может найти Helvetica. Я не знаю, почему. У меня есть Helvetica в каталоге afm mpl-данных, и когда matplotlib инициирует, он считывает его и выдает:

createFontDict: /Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/site-packages/matplotlib/mpl-data/fonts/afm/Helvetica.afm

Нужен ли мне специальный шрифт .ttf Helvetica? Если да, то как я могу его получить? Я знаю, что у меня есть Helvetica в моей системе, так как я вижу ее в Illustrator и многих других программах.

Я использую распространение Enthought Python следующим образом:

$ python
Enthought Python Distribution -- http://www.enthought.com
Version: 6.2-2 (32-bit)

Python 2.6.5 |EPD 6.2-2 (32-bit)| (r265:79063, May 28 2010, 15:13:03) 
[GCC 4.0.1 (Apple Inc. build 5488)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib
>>> matplotlib.__version__
'0.99.3'

Любые идеи, как это можно исправить?

спасибо.

Ответы

Ответ 1

Решение состоит в том, чтобы использовать fondu для преобразования шрифта .dfont Helvetica из Mac OS X в .ttf, а затем поместить его в каталог mpl-data/fonts, в который входит Matplotlib. Это решило проблему.

Ответ 2

Пошаговое решение для OS X 10.11 El Capitan и Python 3 (на основе этот пост).

  • Установить фонду: brew install fondu
  • Найдите местоположение matplotlib:

    python3 -c "import matplotlib ; print(matplotlib.matplotlib_fname())" 
    

    Для меня это /usr/local/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc

  • Сделайте копию Helvetica:

    mkdir ~/Desktop/font_copies
    cp /System/Library/Fonts/Helvetica.dfont ~/Desktop/font_copies
    
  • Преобразуйте копию Helvetica, которую мы сделали от dfont до ttf:

    cd /usr/local/lib/python3.5/site-packages/matplotlib/mpl-data/fonts/ttf/
    fondu -show ~/Desktop/font_copies/Helvetica.dfont
    
  • Удалить кеш шрифтов: rm ~/.matplotlib/fontList.py3k.cache

Готово! Теперь вы можете использовать Helvetica:

import matplotlib.pyplot as plt
plt.rc('font', family='Helvetica')

Ответ 3

У меня все еще проблема с установкой Helvetica. Я использовал фонду в файле .dfont и теперь у вас есть Helvetica.ttf в каталоге mpl-data/fonts/ttf:

$ pwd
/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/mpl-data/fonts/ttf
$ ls
COPYRIGHT.TXT             RELEASENOTES.TXT          STIXSizFiveSymReg.ttf     Vera.ttf                  VeraSeBd.ttf
Helvetica.ttf             STIXGeneral.ttf           STIXSizFourSymBol.ttf     VeraBI.ttf                cmb10.ttf
HelveticaBold.ttf         STIXGeneralBol.ttf        STIXSizFourSymReg.ttf     VeraBd.ttf                cmex10.ttf
HelveticaBoldOblique.ttf  STIXGeneralBolIta.ttf     STIXSizOneSymBol.ttf      VeraIt.ttf                cmmi10.ttf
HelveticaLight.ttf        STIXGeneralItalic.ttf     STIXSizOneSymReg.ttf      VeraMoBI.ttf              cmr10.ttf
HelveticaLightOblique.ttf STIXNonUni.ttf            STIXSizThreeSymBol.ttf    VeraMoBd.ttf              cmss10.ttf
HelveticaOblique.ttf      STIXNonUniBol.ttf         STIXSizThreeSymReg.ttf    VeraMoIt.ttf              cmsy10.ttf
LICENSE_STIX              STIXNonUniBolIta.ttf      STIXSizTwoSymBol.ttf      VeraMono.ttf              cmtt10.ttf
README.TXT                STIXNonUniIta.ttf         STIXSizTwoSymReg.ttf      VeraSe.ttf

И я редактировал мой файл ~/.matplotlib/matplotlibrc (который был загружен в соответствии с --verbose-debug):

font.serif          : Palatino, Bitstream Vera Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman,
     Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
font.sans-serif     : Helvetica #, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Avant Garde, sans-serif

Но я получаю эту ошибку при построении графика:

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/font_manager.py:1216: 
UserWarning: findfont: Font family ['sans-serif'] not found. Falling back to Bitstream Vera Sans
  (prop.get_family(), self.defaultFamily[fontext]))

Если я установил шрифт по умолчанию как serif, Palatino появится просто отлично.

Любые советы?

Ответ 4

В случае, если это кому-то поможет, я написал оболочку script, которая автоматически добавляет шрифты .ttf из пользовательской папки в mpl-data. Просто поместите файлы .ttf в папку fonts, расположенную в том же каталоге, что и этот script. Лично я помещаю этот файл и папку fonts в папку dotfiles, которую я синхронизую с дистрибутивами с git.

В любом случае, вот оно:

#!/bin/bash
# This function sets up any .ttf fonts contained in the <fonts> directory to be detected by matplotlib
# Normally matplotlib just includes a couple open-source .ttf files, but this way we can carry many more
# options across different systems.
# See: https://olgabotvinnik.com/blog/2012-11-15-how-to-set-helvetica-as-the-default-sans-serif-font-in/

# We want empty loops if nothing available, so turn on null-globbing
shopt -s nullglob

# Add the fonts
mpldir="$(python -c "import matplotlib; print(matplotlib.matplotlib_fname())")" # this is the location of matplotlib default "matplotlibrc" file
mfontdir="${mpldir%matplotlibrc}/fonts/ttf" # the same directory should contain a "fonts" folder
echo "Transfering .ttf files in \"fonts\" folder to \"$mfontdir\"..."
for font in fonts/*.ttf; do
  if [ ! -r "$mfontdir/${font##*/}" ]; then # only copy if not already present
    echo "Adding font \"${font##*/}\"..."
    cp "$font" "$mfontdir/"
  fi
done

# Then delete the font cache(s) so fonts are loaded on next startup
# For get_cachedir see: https://stackoverflow.com/a/24196416/4970632
cachedir=$(python -c "import matplotlib; print(matplotlib.get_cachedir())")
caches=($cachedir/*.cache) # array listing of all font caches
for cache in "${caches[@]}"; do
  if [ ! -d "$cache" ]; then # ignore the tex.cache folder
    echo "Deleting cache \"$cache\"..."
    rm "$cache"
  fi
done

Это изначально появилось в fooobar.com/info/392873/....