以前学んだベクトルの記事では、プログラミングを使って「向きと大きさを持つ矢印」を描画し、足し算や合成を視覚化する方法を学習しました。今回は「Pythonを使って数学の視覚化をする」シリーズの続きとして、AI(人工知能)やゲーム開発の根幹を支える「行列(Matrix)」に挑戦します。
行列を理解しプログラムで扱えるようになると、図形を回転させたり、拡大させたりといった変換ができるようになります。
行列の基本ルール
行列とは、数値や変数を縦と横(行と列)の表のように並べたものです。例えば、2つの行と2つの列を持つ行列(2行2列の行列)は、次のように表されます。
$$
A = \begin{pmatrix} a & b \\ c & d \end{pmatrix}
$$
まずは、行列を扱う上で基本となる計算方法と、基本となる行列について見ていきましょう。
- 行列の足し算: 同じサイズの行列同士の足し算は、同じ場所(成分)にある数字同士を足し合わせます。図形に適用すると、全体を平行移動させる働きがあります。
$$
\begin{pmatrix} a & b \\ c & d \end{pmatrix} + \begin{pmatrix} e & f \\ g & h \end{pmatrix} = \begin{pmatrix} a+e & b+f \\ c+g & d+h \end{pmatrix}
$$ - 行列の掛け算: 行列の掛け算は少し複雑で、左の行列の「行(横の並び)」と、右の行列の「列(縦の並び)」の要素を順番に掛け合わせて足すというルールがあります。図形に適用すると「回転」「拡大縮小」「歪ませる」働きがあり、空間そのものを変換させることができます。
$$
\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} e & f \\ g & h \end{pmatrix} = \begin{pmatrix} ae + bg & af+bh \\ ce + dg & cf + dh \end{pmatrix}
$$ - 単位行列: 対角線上の数字が1で、それ以外が0の基本となる行列\( \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix}\)のことです。普通の数字の「1」と同じ役割を持ち、これを他の行列や図形に掛けても何も変化が起きません。
[練習問題] 行列を手計算してみよう
プログラミングで計算する前に、まずは自分で行列の計算ルールを確認してみましょう。
問題1(足し算)
$$
\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} + \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix}
$$
解答1 同じ場所にある数字を足します。
$$
\begin{pmatrix} 1+5 & 2+6 \\ 3+7 & 4+8 \end{pmatrix} = \begin{pmatrix} 6 & 8 \\ 10 & 12 \end{pmatrix}
$$
問題2(掛け算)
$$
\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} \begin{pmatrix} 2 & 0 \\ 1 & 3 \end{pmatrix}
$$
解答2 左の行列の「横」と右の行列の「縦」を掛けて足します。
- 左上:\(1 \times 2 + 2 \times 1 = 2 + 2 = 4\)
- 右上:\(1 \times 0 + 2 \times 3 = 0 + 6 = 6\)
- 左下:\(3 \times 2 + 4 \times 1 = 6 + 4 = 10\)
- 右下:\(3 \times 0 + 4 \times 3 = 0 + 12 = 12\)
よって、答えは以下のようになります。
$$
\begin{pmatrix} 4 & 6 \\ 10 & 12 \end{pmatrix}
$$
Pythonで答え合わせ
先ほど手計算した結果が本当に正しいか、NumPyを使って確かめてみましょう。Colabの新しいセルに以下のコードを入力して実行してみてください。
import numpy as np
# 問題1の行列を用意する
matrix_a1 = np.array([
[1, 2],
[3, 4]
])
matrix_b1 = np.array([
[5, 6],
[7, 8]
])
# 足し算を計算して表示する (+記号で計算できる)
print("問題1(足し算)の答え:")
print(matrix_a1 + matrix_b1)
# 問題2の行列を用意する
matrix_a2 = np.array([
[1, 2],
[3, 4]
])
matrix_b2 = np.array([
[2, 0],
[1, 3]
])
# 行列の掛け算を計算して表示する (np.dot()を使います)
print("\n問題2(掛け算)の答え:")
print(np.dot(matrix_a2, matrix_b2))とセルに入力して実行してみましょう。すると結果は
問題1(足し算)の答え:
[[ 6 8]
[10 12]]
問題2(掛け算)の答え:
[[ 4 6]
[10 12]]
のように表示され、手計算の結果と完全に一致することが確認できます。
図形の拡大・縮小と回転
行列を使って図形を変形させるには、図形を構成する点(座標)のデータに対して、特定のルールを持った行列を掛け合わせます。例えば、対角線上に同じ数字が並んだ行列を掛ければ図形はその数字の倍率で「拡大・縮小」され、三角関数を組み合わせた行列を掛ければ、原点を中心に図形を「回転」させることができます。プログラミングなら、これらの計算を組み合わせて図形を動かすことができます。
では、実際にやってみましょう。
Colabの新しいセルに、四角形の座標ベクトルを用意して、それを「2倍に拡大」し、「90度回転」させるプログラムを書いてみます。
図形の描画には、matplotlibの記事で学んだ機能を使います。
なお、グラフの中に「元の図形」などの日本語を文字化けせずに表示させるため、あらかじめjapanize-matplotlib というライブラリをインストールして読み込んでおきます。
# 日本語表示のためのライブラリをインストール (Colab用)
!pip install japanize-matplotlib
import matplotlib.pyplot as plt
import numpy as np
import japanize_matplotlib # 日本語化ライブラリの読み込み
from matplotlib.patches import Polygon
# 四角形の4つの頂点の座標(x, y)を用意する
# 計算の都合上、上がX座標のリスト、下がY座標のリストになるように2行4列の行列にします
points = np.array([
[1, 3, 3, 1],
[1, 1, 2, 2]
])
# 2倍に拡大する行列を用意する
scale_matrix = np.array([
[2, 0],
[0, 2]
])
# 90度(反時計回り)回転させる行列を用意する
rotate_matrix = np.array([
[0, -1],
[1, 0]
])
# np.dot()を使って、行列の掛け算で図形を変形させる
# まず2倍に拡大する
scaled_points = np.dot(scale_matrix, points)
# その結果をさらに90度回転させる
rotated_points = np.dot(rotate_matrix, scaled_points)
# グラフ描画の準備
fig, ax = plt.subplots()
# 元の図形を青色で描画する (転置 .Tをして形式を合わせる)
poly_original = Polygon(points.T, closed=True, color="blue", alpha=0.5, label="元の図形")
ax.add_patch(poly_original)
# 変形後の図形を赤色で描画する
poly_transformed = Polygon(rotated_points.T, closed=True, color="red", alpha=0.5, label="拡大して回転した図形")
ax.add_patch(poly_transformed)
# グラフの表示範囲と設定
ax.set_xlim(-8, 8)
ax.set_ylim(-1, 8)
ax.set_aspect("equal") # 図形が歪まないように縦横比を固定する
plt.grid(True)
plt.axhline(0, color="black", linewidth=1)
plt.axvline(0, color="black", linewidth=1)
plt.legend()
plt.show()とセルに入力して実行してみましょう。すると結果は

のように表示されます。
プログラムの解説(図形の拡大・縮小と回転)
- 元のデータの準備(9~12行目):
pointsに四角形の4つの頂点座標を定義しています。行列の掛け算のルールに合わせるため、1行目がX座標、2行目がY座標となるように配置しています。 - 変換行列の準備(15~24行目): 拡大させるための
scale_matrixと、回転させるためのrotate_matrixという2つの「変換行列」を用意しています。 - 変形の実行(28~30行目):
np.dot()を使って、元の座標データに対して順番に行列を掛け算しています。これで新しい頂点座標が計算されました。この回転は「図形の中心」ではなく「原点(0, 0)」を中心に行われるため、図形は左上(第2象限)へ移動します。 - 図形の描画(36~41行目):
Polygon()を使って、頂点を結んだ塗りつぶし図形を作成します。このとき、points.Tのように.T(転置)をつけることで、行列の縦と横をひっくり返し、matplotlibが読み込みやすい形式に整えています。また、ax.set_aspect("equal")でグラフの縦横比を固定し、図形が本来の形から歪んで見えないようにしています。
図形のせん断(Shear)
せん断(Shear : シーア)とは、重ねたトランプの山を横から軽く押したときのように、高さは変えずに図形全体を斜めにずらす(歪ませる)変形のことです。X軸方向にせん断を行う行列は、次のような形をしています。
$$
A = \begin{pmatrix} 1 & a \\ 0 & 1 \end{pmatrix}
$$
\(a\)の数値の分だけ、図形の上の部分が横に引っ張られます。
では、実際にやってみましょう。
Colabの新しいセルに、以下のコードを入力して実行してみてください。
import matplotlib.pyplot as plt
import numpy as np
import japanize_matplotlib # 日本語化ライブラリの読み込み
from matplotlib.patches import Polygon
# 元の正方形の座標を用意する
points = np.array([
[0, 2, 2, 0],
[0, 0, 2, 2]
])
# x軸方向に斜めに歪ませる(せん断)行列を用意する (a = 1.5)
shear_matrix = np.array([
[1, 1.5],
[0, 1]
])
# np.dot()を使ってせん断を適用する
sheared_points = np.dot(shear_matrix, points)
# グラフ描画の準備
fig, ax = plt.subplots()
# 元の図形を青色で描画
ax.add_patch(Polygon(points.T, closed=True, color="blue", alpha=0.5, label="元の正方形"))
# 歪ませた図形を緑色で描画
ax.add_patch(Polygon(sheared_points.T, closed=True, color="green", alpha=0.5, label="せん断された図形"))
# グラフの表示設定
ax.set_xlim(-1, 6)
ax.set_ylim(-1, 3)
ax.set_aspect("equal")
plt.grid(True)
plt.axhline(0, color="black", linewidth=1)
plt.axvline(0, color="black", linewidth=1)
plt.legend()
plt.show()とセルに入力して実行してみましょう。すると結果は

のように表示されます。
プログラムの解説(せん断の適用)
- せん断行列の作成(12~15行目): 右上の要素を1.5にした変換行列
shear_matrixを用意しました。 - 変形と描画(18~27行目): 先ほどと同じように
np.dot()で掛け算を行い、元の正方形と、せん断された平行四辺形を描画して比較しています。図形の下辺は動かず、上辺だけが大きく右にずれているのがわかります。
逆行列で元に戻す
行列を使って図形を様々な形に変形させることができましたが、数学にはこの変形を「キャンセルして元に戻す」方法があります。それが「逆行列」です。
元の行列に対してその逆行列を掛けると、図形は一番最初の状態に復元されます。複雑な計算が必要な逆行列も、PythonのNumPyにあるnp.linalg.inv() という機能を使えば求めることができます。
では、実際にやってみましょう。
Colabの新しいセルに、先ほどのせん断させた図形を、逆行列を使って元の正方形に戻すプログラムを書いてみます。元に戻ったことが分かりやすいように、赤色の点線で描画してみましょう。
import matplotlib.pyplot as plt
import numpy as np
import japanize_matplotlib # 日本語化ライブラリの読み込み
from matplotlib.patches import Polygon
# 元の正方形の座標を用意する
points = np.array([
[0, 2, 2, 0],
[0, 0, 2, 2]
])
# X軸方向に斜めに歪ませる(せん断) (a = 1.5)
shear_matrix = np.array([
[1, 1.5],
[0, 1]
])
# np.dot()を使ってせん断を適用する
sheared_points = np.dot(shear_matrix, points)
# --- ここから逆行列の処理 ---
inverse_matrix = np.linalg.inv(shear_matrix)
# 歪んだ図形(sheared_points)に逆行列を掛けて、元に戻す
restored_points = np.dot(inverse_matrix, sheared_points)
# グラフ描画の準備
fig, ax = plt.subplots()
# 歪んだ図形を緑色で描画
ax.add_patch(Polygon(sheared_points.T, closed=True, color="green", alpha=0.5, label="せん断された図形"))
# 元に戻した図形を赤色の点線で描画 (元の青い正方形と同じ位置になるか確認)
ax.add_patch(Polygon(restored_points.T, closed=True, fill=False, edgecolor="red", linewidth=3, linestyle="--", label="元に戻した図形"))
# グラフの表示設定
ax.set_xlim(-1, 6)
ax.set_ylim(-1, 3)
ax.set_aspect("equal")
plt.grid(True)
plt.axhline(0, color="black", linewidth=1)
plt.axvline(0, color="black", linewidth=1)
plt.legend()
plt.show()とセルに入力して実行してみましょう。すると結果は

のように表示されます。
プログラムの解説(逆行列による復元)
- 逆行列の計算(23行目):
np.linalg.inv(shear_matrix)と記述し、せん断のルールを持った行列から、それをキャンセルする逆行列を計算して作り出しています。 - 復元の実行(26行目): 歪んだ後の座標データ
sheared_pointsに対して、作った逆行列をnp.dot()で再度掛け算しています。これで元の状態に戻ります。
まとめ
今回は、Pythonを使って「行列」による図形の変換を視覚化しました。
- 行列の役割: 掛け算することで、図形を「拡大・縮小」「回転」「せん断」という変換をさせることができる。
- せん断(Shear): 図形を斜めに歪ませる変形。
- 逆行列: 変形をキャンセルして元の状態に戻せる行列。
行列の仕組みを学習すると、ゲームのキャラクターがどうやって動いているのか、AIが画像データをどうやって処理しているのかといった仕組みが見えてきます。ぜひ行列の数字を色々書き換えて、図形がどう変化するか遊んでみてください。

今回はこれで終了です。
今回のサンプルを用意したので、もし必要な場合は上の「Open in Colab」と書いてあるボタンをクリックしてください。なおそのままだと編集不可なので編集をしたい場合は「ドライブにコピー」をクリックしてコピーしてください。
なおGoogle ColaboratoryについてわからなかったらGoogleColaboratoryを使ってみよう_導入編をご覧ください。