matplotlib でフォントを埋め込む方法
matplotlib とかその派生の seaborn で作った図(PDF)を論文に貼りたいが、その図にフォントが埋め込まれないときの対処メモ。焦らず、まずは心を落ち着けよう。
症状
PDF ファイルのフォントの埋め込み状況を確認すると Type3 フォントが埋め込まれてない。フォント名としては DejaVuSans とか。ヤバイ、カメラレディの提出に間に合わない。
対処方法1
matplotlib で図を生成するとき、Type3 フォントではなくTrueType フォントを使うように指定する。
具体的には、図を描画する前に以下の命令を実行する。
matplotlib.rc('pdf', fonttype=42)
これでフォントが埋め込まれた。以下で確認できる。
$ pdffonts demo.pdf name type encoding emb sub uni object ID ------------------------------------ ----------------- ---------------- --- --- --- --------- DejaVuSans CID TrueType Identity-H yes no yes 24 0 DejaVuSans-Bold CID TrueType Identity-H yes no yes 15 0
何をやっているか?
使用した matplotlib.rc
関数の API は以下にある。
PDF の設定についてはこのあたりに書かれている。
### PDF backend params #pdf.compression: 6 # integer from 0 to 9 # 0 disables compression (good for debugging) #pdf.fonttype: 3 # Output Type 3 (Type3) or Type 42 (TrueType) #pdf.use14corefonts: False #pdf.inheritcolor: False
デフォルトが Type3 フォントで、42 にすると TrueType フォントが使われるということらしい。なぜか TrueType にするとフォントが埋め込まれる。ラッキー。
対処方法2
上記の方法はサブセット埋め込み(sub)になっていないのでファイルサイズが大きい。
そんなときは以下のように pgf バックエンドで描画するとよい(ただし実行には LaTeX 環境の構築が必要)。
plt.savefig("demo.pdf", backend="pgf")
フォント名が変わったけど必要な文字だけサブセット埋め込みになっているのでいい感じ。
$ pdffonts demo.pdf name type encoding emb sub uni object ID ------------------------------------ ----------------- ---------------- --- --- --- --------- EJSLOC+DejaVuSans CID TrueType Identity-H yes yes yes 7 0
何をやっているか?
PDF の描画を pgf というバックエンドにより行っている。LaTeX の処理系を使っている。詳細は以下にある。
おしまい。
■ 参考