matplotlib
前回、JavaScriptの関数の定義functionの勉強をしました。
まだまだJavaScriptで勉強することはたくさんあるのですが、そうこうしているうちにPythonでも色々と試したことがあり、ネタが溜まってきたので、一旦Pythonの話題に戻ります。
今回はmatplotlibの画像サイズに関してです。
matplotlibでは出力する画像のサイズを「plt.figure(figsize=(x, y))」で指定します。
例えばこんな感じ。
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(6,4))
plt.savefig('test1.png')
上記のプログラムを実行すると、何もプロットしていないので、真っ白な画像が出力されます。
ちなみにピクセルサイズを確認してみると「600 x 400ピクセル」で解像度は「100 ピクセル/インチ」でした。
さてさてなぜこのような値になったのでしょうか。
インチとdpi
まず「figsize=(x, y)」で指定している値は「インチ」です。
日本人にはなかなか馴染みがない「インチ」ですが、1インチは2.54センチメートルです。
つまり先ほど「figsize=(6, 4)」という指定は、X軸方向に6インチ(15.24 cm)、Y軸方向に4インチ(10.16 cm)の画像サイズという指定なわけです。
ただしパソコンで画像を表示する際の一般的な値は「ピクセル」です。
「ピクセル」は画素数のことで、例えば先ほどの6インチ x 4インチの画像をどれだけ細かいドット(ピクセル)に分割しているかを表す値です。
つまり同じ「6インチ x 4インチの画像」だとしても大きいドットで表示したら荒い画像になりますし、細かいドットで表示したら綺麗な画像になるということです。
実はその値が「dpi(dop per inch)」で、1インチを何ドット(ピクセル)で表示しているかを表しています。
つまり「dpi」は画像の解像度ということ。
先ほどの「figsize=(6, 4)」が「600 x 400ピクセル」で解像度は「100 ピクセル/インチ」でした。
ピクセルとドットは言い換えた単位で同じ者なので、1インチが100ピクセルであるために6 x 4インチの画像は600 x 400ピクセルになったというわけです。
ということは最終的に出力される画像サイズは「figsize=(x, y)」であれば、「x * dpi、y * dpi」となるわけです。
dpiの設定の仕方
先ほどの例ではdpiを指定せずに出力していました。
そしてその時のdpiの値は「100 dpi」でした。
つまりmatplotlibのデフォルトのdpi数は「100」というわけです。
これを変更するには「plt.figure(dpi=指定したいdpi)」とします。
画像サイズを先ほどの「6インチ x 4インチ」としてdpiを72に指定してみます。
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(6,4), dpi=72)
plt.savefig('test2.png')
出力された画像は「432 x 288ピクセル」で「72 ピクセル/インチ」となったかと思います。
6 x 72 = 432であり、4 x 72 = 288 であるため、先ほどの理論通りの画像が出力されたことが分かります。
plt.savefig()とJupyter Notebook上のplt.show()の画像サイズ
ちなみにplt.savefig()で保存した画像サイズとplt.show()でJupyter Notebook上に表示した画像サイズは異なるので、注意が必要です。
上記の例では「plt.savefig()」を使用していますが、こちらの場合は「plt.figure()」で指定された値の画像が保存されます。
しかし「plt.show()」の場合は一度Jupyter Notebook上(つまりはブラウザ上)に表示されたものを保存するためか値が変わってくるので注意が必要です。
例えば「figsize=(6,4)」としてplt.show()でJupyter Notebook上に表示し、その表示された画像を保存してみます。
import matplotlib.pyplot as plt
%matplotlib notebook
fig = plt.figure(figsize=(6,4))
plt.show()
この場合、画像サイズは「1200 x 800ピクセル」で解像度は「72 ピクセル/インチ」となりました。
多分、Jupyter Notebook上に表示するために自動でサイズが調整されてしまっているのでしょう。
ということで画像サイズにこだわる場合は「plt.savefig()」を使うのがいいかと思います。
一般的な用紙サイズとピクセル数
まず一般的に印刷物で使われるdpi数は「350 dpi」とのことでした。
ちなみにWeb上では画像の容量も考慮してか「72 dpi」が一般的とのこと。
次によく使われる用紙サイズとそのピクセル数をテーブルにまとめてみるとこんな感じだそうです。
A判サイズ(mm) | ピクセル数 | B 判サイズ(mm) | ピクセル数 |
A0(841 x 1,189) | 11,589 x 16,384 | B0(1,030 x 1,456) | 14,193 x 20,063 |
A1(594 x 841) | 8,185 x 11,589 | B1(728 x 1,030) | 10,031 x 14,193 |
A2(420 x 594) | 5,787 x 8,185 | B2(515 x 728) | 7,096 x 10,031 |
A3(297 x 420) | 4,093 x 5,787 | B3(364 x 515) | 5,016 x 7,096 |
A4(210 x 297) | 2,894 x 4,093 | B4(257 x 364) | 3,541 x 5,016 |
A5(148 x 210) | 2,039 x 2,894 | B5(182 x 257) | 2,508 x 3,541 |
A6(105 x 148) | 1,447 x 2,039 | B6(128 x 182) | 1,764 x 2,508 |
A7(74 x 105) | 1,020 x 1,447 | B7(91 x 128) | 1,254 x 1,764 |
用紙サイズを指定して出力
ということで用紙サイズを指定したら、そのサイズで画像を出力するようなプログラムを書いてみました。
import matplotlib.pyplot as plt
import random
papersize = 'A4'
dpi = 350
num_points = 100
x_val = range(100)
y_val = [random.randrange(0,100) for _ in x_val]
paper_pixel_350dpi = {'A0':[11589, 16384], 'A1':[8185, 11589],'A2':[5787, 8185],'A3':[4093, 5787],'A4':[2894, 4093],'A5':[2039, 2894],'A6':[1447, 2039],'A7':[1020, 1447],\
'B0':[14193, 20063], 'B1':[10031, 14193],'B2':[7096, 10031],'B3':[5016, 7096],'B4':[3541, 5016],'B5':[2508, 3541],'B6':[1764, 2508],'B7':[1254, 1764]}
pixelsize = paper_pixel_350dpi[papersize]
horizontal_inches = pixelsize[0]/dpi
vertical_inches = pixelsize[1]/dpi
fig = plt.figure(figsize=(horizontal_inches, vertical_inches), dpi=dpi)
plt.clf()
plt.plot(x_val, y_val)
plt.savefig(f'{papersize}.png')
このプログラムはまず「matplotlib.pyplot」をインポートしています。
「random」はランダムなデータを作成するために使用しているだけなので、データがある方は必要ありません。
「papersize」に用紙サイズを、「dpi」に用紙サイズのピクセル数の元になっているdpiを記載します。
次の3行はランダムなデータを作成しているだけなので、説明は割愛します。
「paper_pixel_350dpi」には350dpiにおける各用紙サイズのピクセル数が辞書形式で格納されています。
paper_pixel_350dpi = {'A0':[11589, 16384], 'A1':[8185, 11589],'A2':[5787, 8185],'A3':[4093, 5787],'A4':[2894, 4093],'A5':[2039, 2894],'A6':[1447, 2039],'A7':[1020, 1447],\
'B0':[14193, 20063], 'B1':[10031, 14193],'B2':[7096, 10031],'B3':[5016, 7096],'B4':[3541, 5016],'B5':[2508, 3541],'B6':[1764, 2508],'B7':[1254, 1764]}
次の3行で用紙サイズと用紙サイズのピクセル数の辞書から、指定した用紙サイズのピクセル数を取得し、縦横のインチ数を取得します。
pixelsize = paper_pixel_350dpi[papersize]
horizontal_inches = pixelsize[0]/dpi
vertical_inches = pixelsize[1]/dpi
あとはインチ数とdpiを使って、「plt.figure()」の「figsize」を設定しているというわけです。
これで出力するとこんな画像が得られました。
ブログのサーバーで画像サイズが自動で変換されて、先ほど紹介したA4のピクセル数になっていないかもしれませんが、出力された時点ではA4サイズになっていました。
ということで今まで適当に縦横比だろうと思っていた「figsize=(x, y)」ですが、ちゃんとした指定の仕方が分かってスッキリしました。
次回はmatplotlibの余白サイズの変更の仕方を解説していきます。
ではでは今回はこんな感じで。
コメント