Matplotlib tex-macro в описании - PullRequest
       33

Matplotlib tex-macro в описании

0 голосов
/ 21 октября 2018

Я использую matplotlib для генерации pgf файлов.Исходя из этого, я использую автономные tex файлы, которые включают только необходимые настройки и ранее созданные pgf s.В этом сценарии я получаю ошибки при использовании пользовательских макрокоманд для описания в моих файлах графиков.

Вот пример генератора pgf:

import matplotlib as mpl
mpl.use("pgf")
mpl.rcParams.update({
    "pgf.texsystem": "pdflatex",
    "pgf.preamble": [
        #r"\newcommand{\foo}{foo}",
        r"\usepackage{import}",
        r'\subimport{./}{foo.tex}'
    ]
})

import matplotlib.pyplot as plt
plt.figure(figsize=(4.5,2.5))
plt.plot(range(5))
plt.xlabel(r'\foo{}')
plt.savefig('foo.pgf')

, который можно использовать вкаталог со следующим foo.tex файлом:

\newcommand{\foo}{foo}

Запуск этого приводит к следующей ошибке:

ValueError: Error processing '\foo{}'
LaTeX Output:
! Undefined control sequence.
<argument> ....000000}{12.000000}\selectfont \foo
                                                  {}
<*> ...ze{10.000000}{12.000000}\selectfont \foo{}}

!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on texput.log.

Обратите внимание, что это ошибка, сгенерированная matplotlib и не компиляции моих автономных файлов.Также обратите внимание, что ошибка исчезает, когда вместо макроса pgf.preamble (строка закомментирована) предоставляется макрос \foo.Я проверил pgf, созданный этим вариантом, и он действительно использует \foo{}.

У меня проблемы с сужением проблемы дальше.Вот мои конкретные вопросы:

  1. Почему matplotlib вызывает pdflatex вообще?Я генерирую pgf вывод и, следовательно, pdflatex не должно быть необходимо.(Для справки: я strace d описан выше и действительно знаю, что вызывается pdflatex.)
  2. Есть ли способ сохранить временный файл, который matplotlib пытается скомпилировать?Ошибка ссылается на texput.log (конечно), что этот файл впоследствии не существует.
  3. Почему я не могу использовать макрос в метке, предоставленной в другом текстовом файле?

1 Ответ

0 голосов
/ 22 октября 2018

tl; dr Включая tex -файлы в pgf.preamble из matplotlib требуются абсолютные пути.


В будущем я рекомендую следующие pdflatex «сценарий замены» для целей отладки:

#!/usr/bin/env bash
MAIN=/usr/bin/pdflatex
cat /dev/stdin | tee /some/abs/path/to/dbg.tex | "${MAIN}" "${@}"

Обязательно сохраните его как pdflatex, убедитесь, что он исполняемый, убедитесь, что /usr/bin/pdflatex является вашим действительным pdflatex, и убедитесь, что эта оболочкапервый найден в PATH (ср. which pdflatex).При работе генератора python мы сохраняем последний вход tex в dbg.tex.Это отвечает (2).

Учитывая вывод, мы видим:

\documentclass{minimal}
\usepackage{import}
\subimport{./}{foo.tex}

\begin{document}
text $math \mu$
\typeout{pgf_backend_query_start}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont lp}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 0}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 1}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 2}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 3}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 4}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont \foo{}}
\typeout{\the\wd0,\the\ht0,\the\dp0}

Я не знаю, для чего это должно быть полезно.Но я предполагаю, что matplotlib пытается настроить шрифт, для которого он пытается скомпилировать этот "тестовый" документ.Это (вроде) отвечает (1).

Теперь вывод (очевидный задним числом): matplotlib компилирует этот образец документа во временный каталог.Очевидно, что в этом каталоге нет foo.tex, поэтому subimport завершается ошибкой.С этого момента становится очевидным, что \foo не будет доступен.

Хотя это и не самое чистое решение, это можно исправить, включив foo.tex через абсолютный путь.Рабочий генератор python, чтобы наконец ответить (3):

import matplotlib as mpl
import pathlib

mpl.use("pgf")
mpl.rcParams.update({
    "pgf.texsystem": "pdflatex",
    "pgf.preamble": [
        r"\usepackage{import}",
        f'\subimport{{{pathlib.Path.cwd().resolve()}/}}{{foo.tex}}']
})

import matplotlib.pyplot as plt
plt.figure(figsize=(4.5,2.5))
plt.plot(range(5))
plt.xlabel(r'\foo{}')
plt.savefig('foo.pgf')

(я использую python3 и pathlib. Для python2 мы бы предпочли вернуться к os.getcwd .)

...