ベクトルの描画

ベクトルの描画

 

【線型代数07】ベクトルの視覚化

 線型代数を学ぶときには ベクトルを視覚化 すると理解の助けとなります。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() を使ってベクトルの演算を視覚化することがあるので、今回のコードはすべてコピーして取っておいてください。