ベクトルの視覚化

当サイトではアフィリエイトプログラムを利用して商品を紹介しています。

【Pythonで学ぶ線形代数学講座(4)】ベクトルの視覚化

ベクトルの視覚化

線形代数を学ぶときにはベクトルを視覚化すると理解の助けとなります。Matplotlib には二次元ベクトル場を描画するために matplotlib.axes.Axes.quiver() という関数が用意されています。ベクトル場とは、すべての点でベクトルが定義されている平面(あるいは空間)のことで、物理学の分野で力場や電場などを表現するときなどに使われます。
 
Axes.quiver() は以下のような構文で使用します。

Axes.quiver(X, Y, U, V, **kw)

X, Y はベクトルの始点の x 座標、y 座標です。
U, V はベクトルの x 成分、y 成分です。
**kw にはベクトルの色やサイズなどを指定することができます。
 
とりあえず、この構文に沿ってベクトル $\begin{bmatrix}2\\1\end{bmatrix}$ を描画してみます。

# python_visualize_vector_2d

# In[1]

import numpy as np
import matplotlib.pyplot as plt

# 5×5サイズのFigureを作成してAxesを追加
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111)

# 格子点を表示
ax.grid()

# 軸ラベルの設定
ax.set_xlabel("x", fontsize=16)
ax.set_ylabel("y", fontsize=16)

# 軸範囲の設定
ax.set_xlim(-3, 3)
ax.set_ylim(-3, 3)

# x軸とy軸
ax.axhline(0, color="gray")
ax.axvline(0, color="gray")

# ベクトルを表示
# quiver(始点x,始点y,成分x,成分y)
ax.quiver(0, 0, 2, 1, color="red",
          angles='xy', scale_units='xy', scale=1)

# ベクトルにテキストを添える
ax.text(2, 1, "[2, 1]", color="red", size=15)

plt.show()

matplotlib.axes.Axes.quiver() によるベクトル描画
ベクトルを描くことはできましたが、Axes.quiver() の引数の渡し方が少し煩わしいですね。先にも述べたように、Axes.quiver() はベクトル場を描く関数なので、始点や成分を配列やリスト形式でまとめて渡せるようになっています。これは数本のベクトルを描くときには面倒な仕様です。

visual_vector()

そこで、直感的な操作でベクトルを描けるようにインターフェースを改造してみます。

# In[2]

# 座標設定関数
def coordinate(axes, range_x, range_y, grid=True,
               xyline=True, xlabel="x", ylabel="y"):
    ax.set_aspect('equal', adjustable='box')
    axes.set_xlabel(xlabel, fontsize=16)
    axes.set_ylabel(ylabel, fontsize=16)
    axes.set_xlim(range_x[0], range_x[1])
    axes.set_ylim(range_y[0], range_y[1])
    if grid == True:
        axes.grid()
    if xyline == True:
        axes.axhline(0, color="gray")
        axes.axvline(0, color="gray")

# ベクトル描画関数
def visual_vector(axes, loc, vector, color="red"):
    axes.quiver(loc[0], loc[1],
              vector[0], vector[1], color=color,
              angles='xy', scale_units='xy', scale=1)

coordinate() は x と y の範囲を渡して座標を設定する関数です。
grid は格子線、xyline は x 軸・y 軸を表示するか否かのオプション引数です。
visual_vector() の loc にはベクトルの始点、vector にはベクトル (1次元配列) を渡します。color にはベクトルの色を指定します。coordinate() と visual_vector() を使ってベクトルを描いてみます。

# In[3]

# FigureとAxes
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111)

# 座標を設定
coordinate(ax, [-3, 3], [-3, 3])

# ベクトルv,wを定義
v = np.array([2, 1])
w = np.array([-1, 1])

# [0,0]を始点にvを描画
visual_vector(ax, [0, 0], v, "red")

# vの終点を始点にwを描画
visual_vector(ax, v, w, "blue")

# [0,0]を始点にv+wを描画
visual_vector(ax, [0, 0], v + w, "green")

plt.show()

visual_vector()によるベクトルのプロット

visual_vector_3d()

3 次元座標 (matplotlib.axes._subplots.Axes3DSubplot) にもベクトルを配置できます。

# python_visualize_vector_3d

# In[1]

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# FigureとAxes
fig = plt.figure(figsize = (6, 6))
ax = fig.add_subplot(111, projection='3d')
ax.grid()
ax.set_xlabel("x", fontsize=16)
ax.set_ylabel("y", fontsize=16)
ax.set_zlabel("z", fontsize=16)
ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)
ax.set_zlim(-5, 5)

# 原点Oを始点にベクトル(-2,3,2)を配置
ax.quiver(0, 0, 0, -2, -3, 2,
          color = "red", length=1,
          arrow_length_ratio=0.1)

ax.quiver 3D Vector
始点とベクトルを受け取るように関数のインターフェースを改造します。

# In[2]

# 3D座標設定関数
def coordinate_3d(axes, range_x, range_y, range_z, grid = True):
    axes.set_xlabel("x", fontsize=16)
    axes.set_ylabel("y", fontsize=16)
    axes.set_zlabel("z", fontsize=16)
    axes.set_xlim(range_x[0], range_x[1])
    axes.set_ylim(range_y[0], range_y[1])
    axes.set_zlim(range_z[0], range_z[1])
    if grid == True:
        axes.grid()

# 3Dベクトル描画関数
def visual_vector_3d(axes, loc, vector, color="red"):
    axes.quiver(loc[0], loc[1], loc[2],
              vector[0], vector[1], vector[2],
              color=color, length=1,
              arrow_length_ratio=0.2)

coordinate_3d() と visual_vector_3d() で 3 次元ベクトルを配置してみます。

# In[3]

# FigureとAxes
fig = plt.figure(figsize=(6, 6))
ax = fig.add_subplot(111, projection='3d')

# 3D座標を設定
coordinate_3d(ax, [-5, 5], [-5, 5], [-5, 5], grid=True)

# 始点を設定
loc = [0, 0, 0]

# 3Dベクトルを定義
v = [-2, -3, 2]

# 3Dベクトルを配置
visual_vector_3d(ax, loc, v, "red")

ax.quiver 3D Vector
visual_vector(), visual_vector_3d() は1度に1本のベクトルしか描けませんが、代わりに扱いやすい関数になっていると思います。今後も visual_vector(), visual_vector_3d() を使ってベクトルの演算を視覚化することがあるので、今回のコードはすべてコピーして取っておいてください。

 

コメント

  1. あとりえこばと より:

    【AI連載小説】科学とコードの交差点(63)
    「Matplotlibでベクトルを視覚化しよう」
     
    開誠(ホワイトボードに座標軸を描きながら):次はベクトルの視覚化だ。Matplotlibを使って、ベクトルを図で表現できるよ。
    美純:それって、矢印で表現するの?
    開誠:そうだ。ベクトル v=[2,3] があるとすると、これを原点から矢印で伸ばすんだ。
    明信(コードを書きながら):Matplotlibの quiver 関数を使うと、これが簡単にできる。

    import matplotlib.pyplot as plt
    
    # ベクトルを定義
    vector_v = [2, 3]
    
    # プロットの設定
    plt.figure(figsize=(6, 6))
    plt.axhline(0, color='black', linewidth=0.5)
    plt.axvline(0, color='black', linewidth=0.5)
    plt.grid(color='gray', linestyle='--', linewidth=0.5)
    
    # ベクトルを描画
    plt.quiver(0, 0, vector_v[0], vector_v[1], angles='xy', scale_units='xy', scale=1, color='r', label='Vector v')
    
    # プロットの設定を表示
    plt.legend()
    plt.title('Vector Visualization')
    plt.xlabel('X-axis')
    plt.ylabel('Y-axis')
    plt.xlim(0, 4)
    plt.ylim(0, 4)
    
    # グラフ表示
    plt.show()

    美純(グラフを見ながら):すごい、これでベクトルがグラフ上でどのように向いているかが一目瞭然だね。
    開誠(ノートパソコンを開きながら):quiver 関数を使わずにベクトルを描画する方法も考えてみよう。
    美純:どうやって?
    明信:普通に plot 関数を使って、始点と終点を線でつなげばいいんじゃないかな。
    開誠:その発想はいいね。始点から終点に向かって線を引くってことだね。例えば、ベクトル v=[2,3] を描画するなら、これだ。

    import matplotlib.pyplot as plt
    
    # ベクトルを定義
    vector_v = [2, 3]
    
    # 始点
    start_point = [0, 0]
    
    # 終点
    end_point = [start_point[0] + vector_v[0], start_point[1] + vector_v[1]]
    
    # プロットの設定
    plt.figure(figsize=(6, 6))
    plt.axhline(0, color='black', linewidth=0.5)
    plt.axvline(0, color='black', linewidth=0.5)
    plt.grid(color='gray', linestyle='--', linewidth=0.5)
    
    # ベクトルを描画
    plt.plot([start_point[0], end_point[0]], [start_point[1], end_point[1]], color='r', label='Vector v')
    
    # プロットの設定を表示
    plt.legend()
    plt.title('Vector Visualization')
    plt.xlabel('X-axis')
    plt.ylabel('Y-axis')
    
    # グラフ表示
    plt.show()

    明信:これで plot 関数を使ってベクトルが描画できる。
    美純:確かに quiver よりもシンプルだね。