PythonTeX(実行結果埋め込み)

PythonTeX(Geoffrey M. Poore 作)は、文書の中に書いた Python のコードを コンパイル時に実際に実行し、その結果を本文へ埋め込む パッケージです。グラフ・表・計算結果がコードと一体になるので、数値を手で写し間違える心配がなくなり、ソースを直して組み直せば結果も自動で更新されます。Python だけでなく Ruby・Julia・R・Octave なども扱えます。

何をするものか

ふつうの listingsminted は、コードを 見た目どおりに組版する だけで、実行はしません(→「ソースコード掲載」)。PythonTeX が違うのは、コードを 実行して、その出力を文書に取り込む 点です。たとえば本文中に \py{2**10} と書くと、Python が 2**10 を評価し、結果の 1024 がその場所に組まれます。グラフを描く Python コードを書けば、生成された図がそのまま図として現れます。

読み込みは \usepackage{pythontex} の一行だけ。動かすには Python 本体 が必要で、コードの色付け(シンタックスハイライト)には Pygmentspip install pygments)を使います。コードは「セッション」ごとに別プロセスで、しかも 変更されたものだけ 実行されるので、重い計算を含んでいても再コンパイルは軽く済みます。

コマンドと環境は、共通の 基底名(py など)に接尾辞 を付けた一群(ファミリー)として用意されています。「行内で一つの式を実行したい」のか「コードブロックをまとめて実行したい」のか、「コードも一緒に見せたい」のか「結果だけ欲しいのか」で使い分けます。

主なコマンドと環境

まず 行内コマンド から。\py{式} は式を Python に渡し、その文字列表現を組版します(\py{2**10} → 1024)。区切りには波括弧のほか、同じ記号のペアも使え、\py#2**10#\py@2**10@ も同じ意味です。これは値を文書に差し込むためのもので、代入はできません\py{a=1} は不可)。先に変数を作っておけば \py{a} でその値を呼び出せます。

  • \py{式} — 式を実行し、その結果を組版する(接尾辞なし)。
  • \pyc{コード} — 実行するが、何も組版しない(c は code)。中で print すれば、その出力は取り込まれる。
  • \pyv{コード} — 実行せず、コードを そのまま組版 する(v は verb。pyverbatim 相当)。
  • \pyb{コード}実行も組版もするb は block)。print の出力は自動では入らない。
  • \pys{コード} — 文字列補間。!{式} を評価結果で置き換えてから、コードを LaTeX として解釈する(s は sub)。

複数行には 環境 を使います。pycode は中のコードを実行するだけで組版しません(計算や図の生成に最適)。pyverbatim は組版だけで実行しません。pyblock実行も組版も します。pysub\pys の環境版(!{式} の補間)です。pyblock\pybprint 出力は自動では現れないので、出したい場所で \printpythontex を置いて取り込みます。

対話セッションを見せたいときは **pyconsole 環境** です。中の各行を対話的な Python インタプリタに渡したように扱い、>>> プロンプトと入力・出力をそろえて再現します。行内版の \pycon{コード} は実行して出力だけを取り込み(入力は捨てる)、コンソール上の変数値を参照するのに使います。

使ってみる

pycode 環境で値を計算しておき、本文中で \py{…} を使ってその値を組版する、という典型的な流れです。コードと結果が一つの原稿の中で完結している点に注目してください。

document.tex
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pythontex}

\begin{document}
% 実行されるが、何も組版されない
\begin{pycode}
from math import sqrt
radius = 2.5
area = 3.14159 * radius**2
hyp = sqrt(3**2 + 4**2)
\end{pycode}

半径 \py{radius} の円の面積はおよそ \py{round(area, 2)} です。

\(2^{10} = \py{2**10}\)、また \(\sqrt{3^2+4^2} = \py{hyp}\)\end{document}

これは「半径 2.5 の円の面積はおよそ 19.63 です。」と続き、数式として 2¹⁰ = 1024、√(3²+4²) = 5.0 が組まれます。radius を変えてビルドし直せば、本文の数値もすべて連動して変わります。

ビルドの流れ(3 ステップ)

PythonTeX のビルドは 3 段階 です。① まず通常どおり LaTeX エンジン(pdflatex など)で処理する。このとき本文中のコードは実行されず、外部ファイルに 抽出 されます。② 付属の **pythontex プログラム がその抽出コードを実行し、結果を保存する。③ もう一度 LaTeX エンジンで処理すると、保存された結果が本文に 取り込まれて** PDF になります。

terminal
pdflatex document.tex    # 1) コードを抽出 / extract the code
pythontex document.tex   # 2) Python で実行 / run it with Python
pdflatex document.tex    # 3) 結果を取り込む / pull the output back in

ここがポイントです。コードを実行するのは LaTeX 本体ではなく、間に挟まる **独立したプログラム pythontex です。そのため、この 3 ステップの手動ビルドでは --shell-escape は不要** です(外部コマンドを LaTeX から直接叩く minted とはこの点が違います)。一方、latexmk などで 1 回のコンパイルに自動化 したいときは、LaTeX のパスから pythontex を呼ぶために -shell-escape を有効にする構成がよく使われます。.latexmkrc に依存関係を書けば、コード変更時に pythontex 実行と再コンパイルを自動でこなせます。

日本語の文書でも使えます。pdflatexlualatex に置き換えても、エンジンの違いを問わず同じ 3 ステップで動きます(日本語 LaTeX の platex でも可)。Unicode を含むコードを扱うときは、pdfLaTeX なら \usepackage[T1]{fontenc}\usepackage[utf8]{inputenc}、LuaLaTeX なら \usepackage{fontspec} のように、文書側の文字コード設定を整えておきます。

sympy・pylab ファミリー

標準では Python の py ファミリーに加えて、科学計算向けの 2 つのファミリーが用意されています。いずれも基底名を sympypylab に替えただけで、\sympysympycodesympyblock\pylabpylabcodepylabblock のように同じ顔ぶれの命令が揃います。

  • sympy 系 — 記号計算ライブラリ SymPy を from sympy import * で読み込む。\sympy で差し込んだ数式は、SymPy の LatexPrinter を使って文脈に応じた LaTeX 表記に整形される。
  • pylab 系 — matplotlib の pylab モジュールを from pylab import * で読み込み、グラフ作成と NumPy をまとめて使える。

各ファミリーは独立したコマンド・環境の組として並行して使えます。たとえば SymPy で記号的に解いた式を \sympy できれいな数式として組み、matplotlib で描いた図を pylabcode で生成して \includegraphics で貼り込む、といった使い分けができます。

depythontex と安全性

PythonTeX を使った文書は LaTeX と Python が混ざるため、特別なパッケージを受け付けない投稿先や、他形式への変換には向きません。そこで **depythontex** が役立ちます。パッケージオプション depythontex を有効にしてビルドすると補助ファイル 〈ジョブ名〉.depytx が作られ、depythontex.py スクリプトがこれと元原稿を突き合わせて、すべての PythonTeX のコマンドと環境を、組版済みのコードと出力で置き換えた 別の文書を生成します。結果が焼き込まれた、PythonTeX に依存しないプレーンな LaTeX なので、共有や論文投稿に使えます。

terminal
# 1) depythontex オプション付きで通常の 3 ステップを実行
#    Run the usual three steps with the depythontex option on
pdflatex document.tex
pythontex document.tex
pdflatex document.tex

# 2) 静的な版を書き出す(-o で出力名を指定)
#    Write the static version (-o gives the output name)
depythontex -o document-plain.tex document.tex

最後に、セキュリティ に注意してください。PythonTeX を含む文書のコンパイルは、あなたの計算機上で Python(場合によっては他のプログラムも)を実際に実行 します。したがって 信頼できる出所の文書だけ をコンパイルすべきです。これは「実行する」仕組みである以上、--shell-escape を使う他の手段と同様に避けられない性質です。