🐥

pythonでグラフを書こう-(基礎)

2022/10/19に公開

introduction

pythonでグラフを書こう!おら!pyplotをつかうぞおおお!ax?fig?しらねぇ!plotメソッドで適当に出力!!ってやってたら、グラフの書き方一生わからずに毎回適当に調べて適当にうまくいって終わるだけになってた。それじゃもったいないので体系化します。

plotするためのライブラリ-matplotlib

参考文献には、matplotlibはPythonで静的なプロットやアニメーション、インタラクティブな可視化を実現するための包括的なライブラリであると書いている。まぁ要するにグラフを書く時にはこのライブラリが必要ですねって話。ライブラリが何かわかんない!って人に少しだけ説明しておくと、マイクラで言うところのMODやプラグインの部類。つまりpythonをさらに便利にすることができる拡張機能みたいなやつ。ファイルの最初にインストして利用するんやで。

plotをするには2つの方法が存在する

matplotlibには、2つのグラフを書く方法が存在する。それが以下の2つや。

・pyplotインターフェース
・オブジェクト指向インターフェース

どちらも後々解説していくんだけど、前者から説明するな。pyplotインターフェースは、もともとMATLABの機能をpythonでも使えたらいいなってことで導入された機能なんやで。そこからつくったから、まぁ操作性は抜群にいいとおもう。でもその代わりプロットの自由度はあんまないことに注意や。
たいして後者のオブジェクト指向インターフェースは、pythonがオブジェクト指向の言語であることからわかるようにpythonのために作られているようなもんや。だから操作方法は理解すんのがむずいけど、その分プロットの自由度はめちゃくちゃ高いらしい。

ここからの方針としては、まず簡単な前者の方法を書けるようになってから後者の方法に挑戦する。もしも後者だけ身につければいいって人は、後半だけみてくれ。自分としては、どっちもかけたほうがいいやんって思ってるから(自動車免許もMTかATかで変わるやん?あんな感じ。まぁ自分はATやけどな笑)、今回はどっちも解説するで。

pyplotインターフェース

まずは基本から。プロットをするには、xとyの点列が必要になる。んでもって、xとyの要素数を一緒にして、一対一対応させて書いていくわけ。まぁ下を見よう。

plt-1st.py
import matplotlib.pyplot as plt

x = [0, 1, 2, 3] # x座標
y = [1, 5, 2, 6] # y座標

plt.plot(x, y) # 点列(x,y)を黒線で繋いだプロット
plt.show() # プロットを表示

plotメソッドを用いることによって、折れ線グラフが書けるということはココから学べるやん?んで、showメソッドを用いることによって、グラフの表示ができる。jupyterとかつかってるならplt.show()使わなくてもだせるらしいんだけど、そこらへんは自分でためしてくれな。

numpyを用いる

xの配列には、単純な配列を渡すのと、numpyでベクトルとして渡す方法があるが、後者の方が操作性が高いのでできる限りnumpyを利用することにするとよい。配列の作り方は様々であるが、まずはarrayで作ってみよう。

np01.py
np.array([1, 2, 3])
array([1, 2, 3])

arangeメソッド

arangeも使ってみる。1つ目の使い方は引数を一つ入れることで、それまでの数字をarrayにつくる。

np02.py
np.arange(5)
array([0, 1, 2, 3, 4])

2つめの使い方はa~bまでの数を連番に配列をする。小数でも用いることができる。

np02.py
np.arange(1, 11)
np.arange(0.5, 5.5)
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
array([0.5, 1.5, 2.5, 3.5, 4.5])

3つめの使い方は公差数列を作る方法。以下の例では、10が入らないことに注意。

np03.py
np.arange(0, 10, 2)
np.arange(3, -1, -0.5) 
array([ 0,  2,  4,  6,  8])
array([ 3. ,  2.5,  2. ,  1.5,  1. ,  0.5,  0. , -0.5])

linspaceメソッド

linspaceも同じように配列を作成することができる。特に等差数列を作成することができるが、基本的には以下の文法になる。

np04.py
np.linspace(最初の数, 最後の数, 要素数)

最初の数から最後の数までを、要素数に応じて等間隔に分割することができる。実際に使ってみよう。要素数を指定しない場合、デフォルト値は50である。

np05.py
np.linspace(1, 50, 5)
np.linspace(1, 50)
array([ 1.  , 13.25, 25.5 , 37.75, 50.  ])
array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.,
       14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.,
       27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
       40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50.])

その他のメソッド

他にも配列を作ることができるが、その他はグラフを作ることにはあまり関与しないので、紹介のみにしておこう。
zeros,ones,empty,fullメソッドを使うと、全て同じ数の配列にすることができる。

np06.py
np.zeros(5)
np.ones(5)
np.empty(5)
np.full(5, 0.1)

関数を用いてyの配列も作ることができる

numpyの使う最大の利点は、関数にnumpyのベクトルを入れることによって、すべての要素を計算することができる(ベクトル計算をすることができる)ことだ。

plt-2nd.py
import numpy as np
import matplotlib.pyplot as plt

x=np.array([1,2,3,4,5])
plt.plot(x, x**2)
plt-3rd.py
import numpy as np
import matplotlib.pyplot as plt

x=np.array([1,2,3,4,5])
y=np.sin(x)
plt.plot(x, y)

plot()の引数

plot内の引数には、以下の3つがある。
・marker
・markersize
・color
・alpha
・label

markerはその点の形を変更する機能、markersizeはmarkerの大きさ、colorはその点の色、alphaは透明度を変更することができる。labelはそのプロットを命名する。legendと一緒に用いる。
それぞれに関しては詳しくはこのサイトを参照すればよい。

グラフの周辺設定

・titleメソッド
グラフのタイトルの設定
・xlabel,ylabelメソッド
labelの名前の設定
・xlim,ylimメソッド
x軸とy軸の範囲設定
・gridメソッド
目盛線の設定
・legendメソッド
凡例(y=sinxはこの線ですよと表示するもの)の設定。labelと一緒に用いる。
・savefigメソッド
画像を保存するというメソッド

plt-4th.py
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi)
y = np.sin (x)
plt.title("for-test")
plt.plot(x, y, label="$y=sin(x)$")
plt.xlabel("X-value")  # x軸ラベルの設定
plt.ylabel("Y-value")  # y軸ラベルの設定
plt.xlim(0, 2*np.pi)  # x軸の最大・最小値設定
plt.ylim(-1.5, 1.5)  # y軸の最大・最小値設定
plt.grid()  # グリッド線の表示
plt.legend()
plt.show()

複数のグラフを1つの図に表示

plot()を2つもちいることによって、グラフを同じ図に表示することができる。

plt-5th.py
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)
 
plt.plot(x, y1, label="sin")
plt.plot(x, y2, label="cos")
 
plt.legend()
plt.show()

オブジェクト指向インターフェース

pyplotインターフェースはこれぐらいにして、オブジェクト指向インターフェースに移ろう。まずはじめにするのがplt.figureである。これはfigureのインスタンスを生成するメソッドであるが、インスタンスがわからない人はfigureの土台設計をしていると考えれば良い。このインターフェースに関してはこのサイトをしっかりと参考にさせてもらう。

test.py
fig = plt.figure()

add_subplot

次にadd_subplotをして、グラフの表の外枠を作成する。

test2.py
fig = plt.figure()
ax = fig.add_subplot(111)

add_subplot()のカッコ内にある3つの数は、上の例なら1行1列の1番目の部分に表を作るということ。
これをすることで初めてグラフをプロットすることができる。詳しく言えば、AxesオブジェクトをFigureインスタンスに生成するということなのだが、別に必要ではないのでわからなければ追求しなくても良い。

plt.subplots

これはplt.figureとadd_subplotを組み合わせたメソッドである。plt.subplots(nrows, ncols)のnrowsとncolsに値を入れることによって、そのグラフの行と列を考えることができる。

test3.py
fig, axes = plt.subplots(
    2,
    3,
    facecolor="skyblue",
    sharex="col",
    sharey=True,
    subplot_kw=dict(facecolor="gray"),
)

axes[0, 0].set_xlim(0, 10)  # 一番左上のグラフのx軸の範囲を0~10に設定
axes[1, 2].set_xlim(2, 3)  # 一番右下のグラフのx軸の範囲を2~3に設定
axes[0, 1].set_ylim(0, 100)  # 上段中央のグラフのy軸の範囲を0~100に設定

fig.savefig("2-2_b.png", facecolor=fig.get_facecolor())

実践

土台まで作ることができれば、ほとんどpyplotインターフェースと同じ内容で作成することができる。なにかをつけたいものに対しては、そのaxesオブジェクトに対してメソッドを与えてあげることによって成立上で少しだけ用いたが、今回のインターフェースの場合ではset_xlimによって範囲を決めることができる。

test4.py
fig = plt.figure(facecolor="white")
ax = fig.add_subplot(111, xlabel="xlabel", ylabel='ylabel')

# xの値のリストとyの値リストを個別に与える
x = [0, 2, 3, 4, 10]
y = [8, 5, 3, 4, 1]
ax.plot(x, y, marker="o", label="blue")

# xの値を与えない場合
y = [1, 3, 2, 5, 4, 3, 6, 5, 8, 7, 9]
ax.plot(y, marker="o", label="orange")

ax.legend()  # 凡例表示
fig.savefig("3-1_a.png")  # 画像保存

ここまでできれば十分だろう。

もっと詳しく学びたい時に

matplotlibを勉強する

図の作成関連を勉強するなら以下の2つのサイトが非常に勉強になる。
https://qiita.com/nkay/items/d1eb91e33b9d6469ef51

https://qiita.com/kenichiro_nishioka/items/8e307e164a4e0a279734

また、軸回りなどのラベルの設定は以下のサイトが勉強になる。
https://www.yutaka-note.com/entry/matplotlib_axis

また、numpyをもっと勉強したいなら以下のサイトが役に立つだろう。
https://www.headboost.jp/how-to-create-an-array/

Discussion