迷路を表示するには
はじめに
ここでは,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のアニメーションは,連続して使用すると描画が重くなることがあるので注意すること.