org-babelを使うときに、Matplotlibで日本語を含むPDFの図をつくる

課題

org-babeleを使って、Matplotlibで日本語を含むPDFの図をつくるばあい、次の三つの問題にぶつかる

  • 図に日本語を使うと豆腐(ただの四角)になる
  • PDFに出力しようとしても方法がわからない
  • org-babelのオプションがよくわからない

この三つの問題があるので、どんなキーワードで検索したものか悩んだ。 いったいどこが問題なのかも切りわけることができないので、けっこう苦労した。

今回のタイトルは長すぎな感があるけれど、問題の切り分けができていないと、やりたいことってこんな感じになってしまう。 ここから、順次切り分けることで、シンプルなタイトルになっていく。

さて、デンマークでは少しコロナ対策が緩和方向に向かっていて、こどもの学校がはじまっている。 街中にも少し人が増えている。 昨日、用事があって、中心部に行ったのだが、2週間前よりも明らかに人が増えていた。

お天気が続いて、暖かいので半袖の人も目立つ。

次は5月10日以降に第2段の緩和が検討されている。 それに向けて、人々は少し浮かれている気がする。

このまま緩和が続いて、僕も研究室に入れるようになるといいなあと期待している。

図に日本語を使う

まずは、普通のpythonスクリプトで、日本語を含んだ図を使えるようにしよう。

FAQ的な疑問なので、わりと簡単に答えがみつかる。 こちらがいちばんシンプルでわかりやすかった。同サイトの最後の方の説明を参考にして、以下のような設定をする。 これは個別にスクリプト中で指定する方法だ。 実際には、.matplotlibrcで指定しておく方が指定し忘れがなくなるのでおすすめだ。

ただし、いきなり.matplotlibrcに設定をすると、今度はちゃんと.matplotlibを読みにいっているかどうか?という問題がまた出てきて、トラブったときにめんどうだ。 なのでまずは、スクリプトのなかで設定することにした。

前半が設定。後半は、図を作成している。 といっても、X軸とY軸を表示しているだけだけ。

from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 
                               'Yu Gothic',
			       'Meirio',
			       'Takao',
			       'IPAexGothic',
			       'IPAPGothic',
			       'VL PGothic', 
			       'Noto Sans CJK JP',
			       ]
myfig = plt.figure()
axes1 = myfig.add_subplot(111)
axes1.set_xlabel('X軸です')
myfig.show()

PDFで図を作成する

次にこの図をpdfで保存できるようにする。

まず、pdfで使用するフォントとして、Type3フォントではなくTrueTypeフォントを使用するように指定する。 (Type3フォントがなにかは知らない。TrueTypeをデフォルトにすればいいのにと思うけど、なにか事情があるのだろうか。)

デフォルトでは以下が3になっているので、コメントを外して、42に変える。42はTrueTypeフォントのことだと、このrcファイルに書いてある。

plt.rcParams['pdf.fonttype'] = 42

PDFで図を作成する方法は以下。

まずはpdfを使うためのBackendとして、PdfPagesを導入する。次に、図を作成し、pdf形式で保存する。

from matplotlib.backends.backend_pdf import PdfPages

with PdfPages('myfig.pdf') as pdf:
  myfig = plt.figure()
  myfig.add_subplot(111)
  pdf.savefig()
  plt.close()

なお、myfig.savefig('myfig.png')とすれば、同時にpngで保存も可能だ。

Matplotlibによる日本語入りPDF

フォント設定からPDF作成をまとめると、最終的に以下のようになる。

import matplotlib.pyplot as plt
import matplotlib
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 
                               'Yu Gothic',
			       'Meirio',
			       'Takao',
			       'IPAexGothic',
			       'IPAPGothic',
			       'VL PGothic', 
			       'Noto Sans CJK JP',
			       ]
plt.rcParams['pdf.fonttype'] = 42
from matplotlib.backends.backend_pdf import PdfPages

with PdfPages('myfig.pdf') as pdf:
  myfig = plt.figure()
  myfig.add_subplot(111)
  pdf.savefig()
  plt.close()

org-babelのなかで使用する

org-babelで使用するときには、以下のように、BEGIN_SOURCEにオプションを指定する。 pdfでの表示は試していないけど、pngではテスト済みだ。 最後にファイル名をretunしておくことで、できた画像を表示することができる。

#+BEGIN_SRC python :results file :exports both
import matplotlib.pyplot as plt
import matplotlib
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 
                               'Yu Gothic',
			       'Meirio',
			       'Takao',
			       'IPAexGothic',
			       'IPAPGothic',
			       'VL PGothic', 
			       'Noto Sans CJK JP',
			       ]
plt.rcParams['pdf.fonttype'] = 42
from matplotlib.backends.backend_pdf import PdfPages

with PdfPages('myfig.pdf') as pdf:
  myfig = plt.figure()
  myfig.add_subplot(111)
  pdf.savefig()
  plt.close()
return myfig.png'
#+END_SRC

#+RESULTS:
[[file:myfig.png]]

ちなみに、以下の図は練習で作成した図。

https://blog.ecofirm.com/images/myfig.png

Hugo で構築されています。
テーマ StackJimmy によって設計されています。