内容
- デジタル画像としての大きさの単位であるピクセルと物理的な長さを示すインチを混乱しないようにしよう。
- matplotlibで出力される画像の大きさは、ピクセル単位で表わすと、plt.rcParams["figure.dpi"] × plt.rcParams["figure.figsize"]で計算される。
- 一方matplotlib内のフォントサイズを表現する時にはポイントで指定する。ポイントとは、1/72インチなので物理的な長さの単位であり、ピクセルではない。
- そのため、図中の相対的な大きさを考えてフォントサイズを指定したい時には、plt.rcParams["figure.figsize"]で指定する値との大小のみを考えて指定する必要がある。
環境
matplotlib 2.1.1
イントロ
matplotlibにはいつも大変お世話になっております。データのグラフ化などすごく簡単に素早く、場合によっては一部分を拡大してみたりできちゃったりして、ほんと大好きです。
…ただ、軸、タイトル、凡例などフォントのサイズを変える時に「!?」となることがしばしばでした。勿論これは、matplotlib様が悪いのではなく、僕がフォントのサイズ、dpi、matplotlibにおけるfigureのサイズの相互の関係についてちゃんと分かっていなかったことが原因なのですが、これについて少し調べてみたことを書いてみます。タイトルの怪はあくまで僕にとっての怪ということで。
matplotlibにおけるピクセルとインチ
デジタル画像はピクセルで大きさが指定されているが、当然その実際の大きさはディスプレイの大きさやdpi(dot per inch、1インチあたりのドット数)で異なってくる。matplotlibで出力した図をplt.savefig
などで保存する時も、その図の大きさはピクセル単位で表現されるものが出力される。
この時の縦横のピクセル数は、plt.rcParams["figure.dpi"] × plt.rcParams["figure.figsize"]
で計算されることになる。
そのため、 dpi = 50, figsize = (4.8,3.6) のものと dpi = 100, figsize = (2.4,1.8)のものは出力される画像サイズは同じ大きさになる。imagemagickのindentifyというツールで画像サイズを確認してみる。
- dpi = 50, figsize = (4.8,3.6)
identify inch_half_100dpi.png
>inch_half_100dpi.png PNG 240x180+0+0 DirectClass 8-bit 6.2K 0.000u 0:01
- dpi = 100, figsize = (2.4,1.8)
identify inch_half_100dpi.png
> inch_half_100dpi.png PNG 240x180+0+0 DirectClass 8-bit 6.2K 0.000u 0:01
ということで、同じサイズ(240*180)になるのだが、上記を見て分かるように文字や線の太さなど微妙に違う。
フォントなどのサイズ指定
上記図のような、画像サイズが一緒、もちろんフォントなどのサイズ指定も一緒なのに見た目の大きさに違いがでるのは、フォントや線などはポイントで指定していて、直接比較されているのはfigure.figsizeでインチで指定される長さであるから。
1ポイントは1/72インチと等しい。例えばfont.size=18の時、少なくとも日本語等幅フォントを使っている時、その一文字は18*1/72=0.25
インチとなる。ここで、figsize=(4.8,3.6)(この数値はインチ)とfigsize=(2.4,1.8)の図のタイトルに文字がそれぞれ何文字入るのかやってみると、4.8の方は4.8/0.25=19.2
、2.4の方は2.4/0.25=9.6
となる。
figsize=(4.8,3.6),dpi=100,fontsize=18の時のplt.titleでは「と」(19番目)まで。
figsize=(2.4,1.8),dpi=200,fontsize=18の時のplt.titleでは「こ」(10番目)まで。
どうすれば(特にフォントの大きさについて)思い通りに指定できるか
figsize=(4.8,3.6),dpi=100の時にタイトルを10文字で書いて、半分くらい2.4インチとしよう)に収まるようにしたい時何ポイントにしたらいいの?と思ったら、
2.4(横に使えるインチ) \times (1/72)(1ポイントのインチ)/ 10(文字数) = 17.27
ということで、大体17とか18ポイントでいいことになる。以下のタイトルの文字は18ポイントで指定したもので、大体半分くらいの長さになっている。
全体的な心つもりとして
- figsizeは縦横比を変える時に使用する。横の値は4.8で固定するなどする。
- 高精細にしたい時などはdpiを変化させる。figsizeを変えるとフォントの大きさの指定の感覚を失うことになりかねないのでやめた方がいい。
- フォントサイズはfigsize横サイズデフォルトの4.8を基準とする時は、18くらいは悪くない線。勿論微調整が必要な場合はある。matplotlibrcに書いてデフォルトを変えておこう。
最後に
色々間違っているかもしれませんがご指摘頂ければ幸いです。