12 Python スクリプトの埋め込み

Python スクリプトを埋め込むこともできる. 方法は2通りあり, 都度システムコマンドから呼び出す方法と, reticulateパッケージを使うものがある.reticulate登場以前はチャンクごとに呼び出していたため複数のチャンクに分割して記述するのが難しかったが, 現在はreticulate` パッケージを利用することでRと同じような感覚で, あるいは Jupyter のコードセルと同じような感覚で書ける.

pyenv を使用する場合, 共有ライブラリのインストールが必要なことに注意23.

初めて使う場合は先に reticulate 単体でPythonが実行できるか検証してからの方が良い.

require(reticulate)
# Python エンジンを認識しているか確認
py_discover_config()
repl_python()

# 以下, Python コマンド実行, `exit` で抜ける

現在 (knitr 1.18以降) は R Markdown はデフォルトで reticulate を使う. システムコマンド経由にしたい場合はチャンクオプション python.reticulate=F を設定する, あるいは reticulate::eng_python に変わるエンジンを自作する24.

あとはチャンクのエンジンに r ではなく python を指定することでPythonコードを埋め込める.

matplotlib エンジンで描いたグラフに日本語フォントを埋め込む場合, matplotlib-japreset を使えば必要な設定を一括で行う.

pip install -U git+https://github.com/Gedevan-Aleksizde/matplotlib-japreset.git@master
from matplotlib_japreset import mplj_cairo
Noto Sans CJK JP not found
matplotlib-japreset Cairo mode
font: Noto Sans CJK JP
from matplotlib import rcParams
from plotnine import *
from plotnine.data import mtcars
rcParams['font.family']
['Noto Sans CJK JP']

matplotlib-japreset によって主要OSで標準インストールされている日本語フォントが自動的に選ばれる. 気に入らない場合は rcParams['font.family'] に好きなフォント名を上書きする.

ggplot(mtcars, aes('wt', 'mpg', color='factor(gear)')
) + geom_point() + stat_smooth(method='lm') + facet_wrap('~gear')
Python の plotnine によるグラフ表示例

図 12.1: Python の plotnine によるグラフ表示例

現状ではmatplotlibの標準出力や警告も表示されてしまうため, チャンクオプション results='hide', warning=F, message=F で隠すと良い.

12.1 Python のグラフィックに関する制約

matplotlib ベースのグラフィックを出力したい場合, いくつかの制約がある.

  • matplotlib > 3.2 では R がクラッシュするため, 3.2 を使用する必要
  • axes を使用した場合 (subplot などが依存), matplotlib.pyplot.show の呼び出しと, 次に別のグラフを呼び出す前の matplotlib.pyplot.close() が必要
  • seaborn.FacetGrid を Cairo デバイスで保存できない ( = フォントのサブセット化処理が複雑になる)

よって, 現状では matplotlib エンジンでグラフィックを描くときはなるべく plotnine を使ったほうがトラブルが少ない.

また plotly, bokeh などの matplotlib に依存しないモジュールはPDFには対応していないため直接表示できない. 一旦画像を保存して, あらためて画像ファイルを埋め込む必要がある.