Программирование

Как задать пользовательский шрифт в MathText Matplotlib

Узнайте, как настроить MathText в Matplotlib, чтобы использовать пользовательский шрифт (например, Algerian) и при этом сохранить полноценный синтаксис LaTeX, включая поддержку XeLaTeX, а также как переключить на внешнее рендеринг LaTeX через text.usetex.

Как заставить математический текст в Matplotlib использовать пользовательский прямой шрифт (например, Algerian) вместо стандартного Computer Modern, при этом сохраняя форматирование LaTeX?

Мне нужно, чтобы окружающий текст и LaTeX‑уравнение отображались в одном и том же прямом шрифте. Например:

python
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'Algerian'
plt.rcParams['font.weight'] = 'bold'
plt.rcParams['font.size'] = 10

plt.figure()
plt.text(0.1, 0.5, r"$a*\ln(x)*x^2+2$", fontfamily='Algerian')
plt.show()

В этом фрагменте обычный текст соответствует шрифту Algerian, но математическое выражение переходит в курсив и использует Computer Modern. Есть ли способ сделать так, чтобы и пользовательский прямой шрифт, и корректное LaTeX‑форматирование работали в Matplotlib, возможно, используя XeLaTeX или LuaLaTeX?

Проблема в том, что движок MathText в Matplotlib – тот, который рисует встроенные формулы, когда text.usetex = False – знает только несколько шрифтов.
Если задать обычный текст шрифтом Algerian, MathText всё равно откатывается к своему стандартному Computer Modern, и символы в уравнении появляются курсивными.

Есть два способа заставить математическую часть использовать тот же ровный шрифт Algerian, при этом сохраняя полноценный синтаксис LaTeX:

Цель Что менять Как задать Что получится
Использовать MathText (без внешнего LaTeX) mathtext.fontset='custom' и отдельные записи шрифтов (rm, it, bf, cal, …) Устанавливаем в rcParams и в plt.text ставим math_fontfamily='custom' или math_fontfamily='Algerian' MathText отрисует уравнение в Algerian (ровно) и будет распознавать команды LaTeX вроде \ln, \int, \frac и т.д.
Включить настоящий LaTeX‑движок (XeLaTeX/LuaLaTeX) text.usetex=True и преамбула LaTeX, загружающая fontspec и задающая основной шрифт Algerian Весь текст – обычные слова и математика – будет отрисован LaTeX‑ом, так что один и тот же шрифт будет использоваться везде. Полная поддержка LaTeX (пакеты, более богатый набор символов, тонкая настройка и т.д.).

Ниже – рабочие примеры для обоих подходов.


1. MathText с пользовательским ровным шрифтом

python
import matplotlib.pyplot as plt
import matplotlib as mpl

# 1. Скажем MathText использовать собственный набор шрифтов
mpl.rcParams.update({
    'mathtext.fontset': 'custom',      # включаем режим «custom»
    'font.family': 'Algerian',        # обычный текст
    'font.size': 10,
    'font.weight': 'bold',
    # Указываем, какие файлы использовать для каждого стиля
    'mathtext.rm': 'Algerian',        # ровный (rm = roman)
    'mathtext.it': 'Algerian:italic',# курсив (если есть)
    'mathtext.bf': 'Algerian:bold',  # жирный
    'mathtext.cal': 'Algerian:italic', # каллиграфический
    # При желании можно убедиться, что шрифт действительно доступен
})

# 2. Используем пользовательский семейство в вызове текста
plt.figure()
plt.text(
    0.1, 0.5,
    r"$a*\ln(x)*x^2+2$",
    math_fontfamily='Algerian',  # говорит MathText использовать вышеуказанные настройки
    fontsize=10
)
plt.show()

Что происходит

  • Вокруг уравнения текст в Algerian и жирный.
  • Само уравнение отрисовано MathText, но благодаря mathtext.fontset='custom' и заданному rm символы берутся из Algerian (ровно).
  • Если у Algerian нет курсивной версии, mathtext.it откатится к Computer Modern; можно либо добавить файл курсивного шрифта, либо оставить такой fallback.

2. Полная отрисовка LaTeX (XeLaTeX / LuaLaTeX)

Если нужны более продвинутые возможности LaTeX (например, \frac, \sum, дополнительные пакеты), включаем LaTeX‑движок и позволяем ему выбрать шрифт через fontspec.

python
import matplotlib.pyplot as plt
import matplotlib as mpl

mpl.rcParams.update({
    'text.usetex': True,             # используем внешний LaTeX‑движок
    'font.family': 'Algerian',       # обычный текст
    'font.size': 10,
    'font.weight': 'bold',
    # Переопределяем преамбулу LaTeX
    'text.latex.preamble': r'''
        \usepackage{fontspec}
        \setmainfont{Algerian}
        \setmathfont{Algerian}      # опционально: шрифт для математики
    ''',
    # Указываем, что нужно использовать XeLaTeX / LuaLaTeX
    'text.latex.unicode': True,
    'text.latex.preview': False,
})

plt.figure()
plt.text(
    0.1, 0.5,
    r"$a*\ln(x)*x^2+2$",
    fontsize=10
)
plt.show()

Требования

  • На системе должен быть установлен XeLaTeX или LuaLaTeX.
  • Шрифт Algerian должен быть доступен в базе шрифтов TeX или в системе (например, в /usr/share/fonts или ~/Library/Fonts).
  • Теперь LaTeX отрисует как обычный текст, так и математику в одном и том же ровном шрифте Algerian.

Быстрый чек‑лист

Шаг Что проверить
1. Установить Algerian С помощью системного установщика шрифтов или fc-list убедиться, что он доступен.
2. Для MathText mpl.rcParams['mathtext.fontset'] = 'custom' и задать rm, it, bf, cal.
3. Для LaTeX mpl.rcParams['text.usetex'] = True и преамбула с fontspec + \setmainfont{Algerian}.
4. Тест Запустить простую plt.text(..., r"$\int_0^\infty x^2 dx$").
5. Если курсивный fallback Добавить файл курсивного шрифта или оставить fallback.

Независимо от выбранного метода, синтаксис LaTeX остаётся прежним, а вся фигура – обычный текст и уравнения – выглядит в одном ровном шрифте Algerian.

Авторы
Проверено модерацией
Модерация