matplotlib
前回、Pythonのmatplotlib pcolormeshで二次元カラープロットを表示する方法を紹介しました。
今回はmatplotlibのpcolormeshを使って正規分布(ガウス分布)を2次元プロットする方法を紹介します。
まず今回プロットするガウス分布のX軸方向とY軸方向の2つのデータを準備しました。
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
z_x = norm.pdf(x, 2.5)
z_y = norm.pdf(y, 7.5)
fig = plt.figure()
plt.clf()
plt.plot(x, z_x)
plt.show()
fig = plt.figure()
plt.clf()
plt.plot(y, z_y)
plt.show()
実行結果
今回正規分布のグラフを作成するのにSciPyの「stats.norm.pdf」を使用しました。
使い方はこちらの記事で紹介していますので、よかったらどうぞ。
それでは始めていきましょう。
掛け算で2次元リストを作成
pcolormeshで正規分布を2次元プロットするには、X軸方向、Y軸方向のデータから2次元のデータを作成する必要があります。
まずは単純にX軸方向とY軸方向のデータを掛け合わせ2次元リストを作って、それをpcolormeshで表示してみることにします。
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
z_x = norm.pdf(x, 2.5)
z_y = norm.pdf(y, 7.5)
z = []
for z_y_val in z_y:
z_temp = []
for z_x_val in z_x:
z_temp.append(z_x_val*z_y_val)
z.append(z_temp)
fig = plt.figure()
plt.clf()
plt.pcolormesh(x, y, z)
plt.colorbar()
plt.show()
実行結果
行列演算を用いる方法
先ほどの2つのリストの要素を掛け算し、2次元リストとするのは行列演算を使うともっとシンプルに書くことができます。
今回の場合、2つのリストの要素を掛け合わせ、それぞれの要素の数だけ縦横に数値をもつ2次元プロットにしたいので、この様に行列の掛け算を行います。
これを先ほどの2つのリストで再現するとこちらの様になります。
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
z_x = np.matrix(norm.pdf(x, 2.5))
z_y = np.matrix(norm.pdf(y, 7.5)).T
z = np.array(z_y * z_x)
print(z)
実行結果
[[4.26695018e-15 5.45154649e-15 6.89570896e-15 ... 5.37495530e-25
2.60322291e-25 1.24825960e-25]
[8.98808066e-15 1.14833634e-14 1.45254071e-14 ... 1.13220286e-24
5.48353660e-25 2.62938574e-25]
[1.87444804e-14 2.39483476e-14 3.02924749e-14 ... 2.36118867e-24
1.14358168e-24 5.48353660e-25]
...
[6.21809323e-04 7.94436844e-04 1.00489013e-03 ... 7.83275450e-14
3.79359544e-14 1.81904972e-14]
[4.96524830e-04 6.34370705e-04 8.02421067e-04 ... 6.25458150e-14
3.02924749e-14 1.45254071e-14]
[3.92538056e-04 5.01514987e-04 6.34370705e-04 ... 4.94468981e-14
2.39483476e-14 1.14833634e-14]]
片方のリストは縦に並べたいので「array.T」、もしくは「array.transpose()」を使って転位する必要があることに注意してください。
また行列の掛け算では掛ける順番が重要なので、縦に並べたリストを先に、横に並んでいるリストを後にすることを間違えない様にしてください。
あとはこれを使ってpcolormeshで2次元プロット化するだけです。
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
z_x = np.matrix(norm.pdf(x, 2.5))
z_y = np.matrix(norm.pdf(y, 7.5)).T
z = np.array(z_y * z_x)
fig = plt.figure()
plt.clf()
plt.pcolormesh(x, y, z)
plt.colorbar()
plt.show()
実行結果
一つ分からなかったのは、この行列演算により2次元リストを作成した場合、最後にNumPyのndarrayにしないとエラーとなることです。
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y = np.arange(0, 10, 0.1)
z_x = np.matrix(norm.pdf(x, 2.5))
z_y = np.matrix(norm.pdf(y, 7.5)).T
z = z_y * z_x
fig = plt.figure()
plt.clf()
plt.pcolormesh(x, y, z)
plt.colorbar()
plt.show()
実行結果
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[13], line 18
15 fig = plt.figure()
16 plt.clf()
---> 18 plt.pcolormesh(x, y, z)
20 plt.colorbar()
22 plt.show()
(中略)
ValueError: For X (101) and Y (101) with flat shading, A should
have shape (100, 100, 3) or (100, 100, 4) or (100, 100) or
(10000,), not (1, 10000)
この点はよく分からなかったのですが、行列演算で2次元リストを作る技は覚えておくと便利だと思います。
次回はNumPyで格子状の多次元配列を作成する方法(mgrid関数、meshgrid関数)を紹介します。
ではでは今回はこんな感じで。
コメント