迷路を表示するには

はじめに

ここでは,numpy.ndarrayで表現される迷路(壁が1・通路が0の二重配列)をmatplotlibを用いて表示する方法を紹介する.

以下で紹介する方法については,すべてnumpyとmatplotlibのインポートが必要である.

import numpy as np

import matplotlib.pyplot as plt

上記のimport文が無いと表示ができないので注意する.

以降numpyをnp,matplotlib.pyplotをpltと省略して示す.

matplotlibはプロット作業の最後にplt.show関数またはplt.pause関数を呼び出さなければ,画面に表示されないので注意する.


第1週目

迷路を表示する

迷路の表示には,plt.imshow関数を用いる.

plt.imshow(maze, cmap="binary")

ここで,mazeは迷路を記憶しているnp.ndarray変数とする.

オプション引数cmapには,"binary"に限らず様々なものが用意されている.

興味があるものは調べてみるとよい.

縦横比を1:1にする

plt.gca().set_aspect("equal")

第2・3週目

スタートとゴールを表示したい

start = (y1, x1)

goal = (y2, x2)

plt.plot(start[1], start[0], "D", color="tab:red", markersize=10)

plt.plot(goal[1], goal[0], "D", color="tab:green", markersize=10)

二点の座標を結ぶベクトル(矢印)を表示したい

# p -> q の矢印をプロットする

p = (y1, x1)

q = (y2, x2)

plt.quiver(p[1], p[0], (q[1]-p[1]), (q[0]-p[0]), angles='xy', scale_units='xy', scale=1)

矢印を表示することによって,探索の過程を下図のように描画することができる.手法ごとの探索の違いを視覚的に確認できるため,実行結果の出力に利用すると良い.

第4週目(必要に応じて第5・6週目も)

ヒートマップを表示したい

迷路の表示と同様に,plt.imshow関数を用いればよい.

plt.imshow(image)

例えば,強化学習の課題の場合では,imageは価値関数V(s)を記憶しているnp.ndarray変数(迷路と同様のサイズ)とする.

ただし,二回以上plt.imshowを呼び出すと,次々に上書きされるので注意する.


発展:ヒートマップを表示したいが,特定のセルだけ表示したくない

plt.imshow関数は二回以上呼び出すと,次々に上書きされる.

もし上書きされたくない(例えば,壁の部分は上書きしてほしくない)時は,該当のセルを透明にすることで上書きを防ぐことができる.

maze = **地図を表す二重配列**

heatmap = **地図と同じサイズのヒートマップ**

cmap = plt.get_cmap("Greens")

image = []

for y in range(height):

image_line = []

for x in range(width):

if maze[y, x] == 1:

# 壁の部分を透明にする

pixel = (0, 0, 0, 0)

else:

pixel = cmap(heatmap[y, x])

image_line.append(pixel)

image.append(image_line)

plt.imshow(maze, cmap="binary")

plt.imshow(image)

上記のプログラムは,地図を表示した上にヒートマップを表示するサンプルである.

**地図を表す二重配列**など,**で囲われた範囲にはそれぞれ該当するデータを各自記述する.

第5・6週目

ある座標にテキストを表示したい

迷路を表現する配列をmazeとし,maze[y, x]の位置に"text"と表示するには以下のコードを用いる.

plt.text(x, y, "text", horizontalalignment="center", verticalalignment="center")

キーボードからの入力を受け取りたい

キーボードからの入力を受け取るためには,input関数を用いればよい.

ただし,input関数は入力された内容を文字列として取得するため,整数や実数を入力する場合は別途文字列を数値に変換するためのint関数やfloat関数を用いる.

raw_input = input("なんとかを入力してください >> ")

int_input = int(raw_input)

float_input = float(raw_input)


発展:パーティクルを表示したい

パーティクルフィルタにおいて,パーティクルを点で表現したい場合は,plt.plot関数を用いてプロットする.

ただし,ただ単にplt.plot関数を利用すると,複数のパーティクルが重なって1個にしか見えなくなるため,乱数によって表示位置にばらつきを持たせる.

例:表示したいパーティクルの座標が (y, x) のとき.

noise_x, noize_y = np.random.rand(2) * 0.8 - 0.4

plt.plot(x + noise_x, y + noise_y, ".", color="tab:red")

その他

発展:アニメーション表示したい

matplotlibを用いたアニメーション表示はいくつか方法があるが,ここではplt.pause関数を用いたアニメーション表示の方法を紹介する.

while True:

# *********

# プロット処理 (plt.imshow等)

# *********

plt.pause(0.01)

plt.clf()

ここで,plt.clf関数は,これまでプロットした内容を消去する関数である.

また,plt.pause関数は,後続の処理ブロックすることなく表示する関数であり,インターバル(sleep時間:秒)を引数にとる.

※matplotlibのアニメーションは,連続して使用すると描画が重くなることがあるので注意すること.