Python で作成したグラフの部分だけを pdf として保存する

SymPy で作成したグラフの部分だけをファイルとして保存する の補足。

フォントに関するエラーを避けて,Python の matplotlib.pyplot.plot()sympy.plotting.plot.plot() で作成したグラフの部分だけを(フォントに関するエラーを回避して) pdf として保存する。

追記:以下のエラーの件は,matplotlib のバージョンアップにより解消された模様です。以下の記事を参照:

症状:pdf として保存しようとするとエラー

matplotlib.pyplot.plot() の場合

In [1]:
# NumPy も使います
import numpy as np
# Matplotlib でグラフを描きます
import matplotlib.pyplot as plt

# 以下はグラフを SVG で Notebook にインライン表示させる設定
%config InlineBackend.figure_formats = ['svg']

plt.savefig() で pdf として保存しようとすると,以下のようにフォントに関するエラーが出て,まともな pdf ファイルとして保存されない。

In [2]:
x = np.linspace(-2*np.pi, 2*np.pi, 100)

plt.plot(x, np.sin(x));

plt.savefig('err-pltplot.pdf')
The PDF backend does not currently support the selected font.
---------------------------------------------------------------
RuntimeError                  Traceback (most recent call last)
<ipython-input-2-c29f2d9f2b64> in <module>
      3 plt.plot(x, np.sin(x));
      4 
----> 5 plt.savefig('err-pltplot.pdf')

... 

RuntimeError: TrueType font is missing table

sympy.plotting.plot.plot() の場合

In [3]:
# SymPy を使うときのおまじない
from sympy import *
from sympy.abc import *
from sympy import pi

# 以下はグラフを SVG で Notebook にインライン表示させる設定
%config InlineBackend.figure_formats = ['svg']

.save() で pdf として保存しようとすると,フォントに関するエラーが出て,まともな pdf ファイルとして保存されない。

In [4]:
p1 = plot(sin(t), (t, -2*pi, 2*pi));

p1.save('./err-plot.pdf')
The PDF backend does not currently support the selected font.
---------------------------------------------------------------
RuntimeError                  Traceback (most recent call last)
<ipython-input-4-73f3adef8078> in <module>
      1 p1 = plot(sin(t), (t, -2*pi, 2*pi));
      2 
----> 3 p1.save('./err-plot.pdf')

...

RuntimeError: TrueType font is missing table

解決策

pdf として保存する前に以下の呪文を唱える。(sympy.plotting.plot.plot() も matplotlib を呼んでいるので同様。)

In [5]:
# グラフを pdf で保存する場合
from matplotlib import rcParams
rcParams['pdf.fonttype'] = 42

保存成功!

matplotlib.pyplot.plot() の場合

In [6]:
x = np.linspace(-2*np.pi, 2*np.pi, 100)

plt.plot(x, np.sin(x));

plt.savefig('saved-pltplot.pdf')

sympy.plotting.plot.plot() の場合

plot()show=False オプションをつけないと,グラフが2回表示されるのはご愛嬌。)

In [7]:
p1 = plot(sin(t), (t, -2*pi, 2*pi));

p1.save('./saved-plot.pdf')

問題点:pdf のファイルサイズがでかい

こんな簡単なグラフの pdf が 16MB にもなる。

In [8]:
%%bash 
rm -f err-*.pdf
ls -lh saved-*.pdf
-rw-r--r-- 1 kasai riko 16M 12月 23 10:24 saved-plot.pdf
-rw-r--r-- 1 kasai riko 16M 12月 23 10:24 saved-pltplot.pdf

やっぱり一旦 svg で保存して rsvg-convert したほうがいいかも

やはり,いったん svg で保存して,rsvg-convert で pdf にコンバートしたほうがファイルサイズも全然ちいさいので,よろしいかもしれない。

In [9]:
plt.plot(x, np.sin(x));
plt.savefig('saved-pltplot.svg')
In [10]:
%%bash
rsvg-convert -f pdf -o saved-pltplot2.pdf saved-pltplot.svg
In [11]:
p1 = plot(sin(t), (t, -2*pi, 2*pi));
p1.save('./saved-plot.svg')
In [12]:
%%bash
rsvg-convert -f pdf -o saved-plot2.pdf saved-plot.svg
In [13]:
%%bash 
ls -lh saved-*.pdf
-rw-r--r-- 1 kasai riko  16M 12月 23 10:24 saved-plot.pdf
-rw-r--r-- 1 kasai riko 7.6K 12月 23 10:24 saved-plot2.pdf
-rw-r--r-- 1 kasai riko  16M 12月 23 10:24 saved-pltplot.pdf
-rw-r--r-- 1 kasai riko 6.9K 12月 23 10:24 saved-pltplot2.pdf

上記のように,rsvg-convert でコンバートして作成した pdf のほうが圧倒的にファイルサイズが小さい。