[matplotlibで錯視] 8. エビングハウス錯視のアニメーション

matplotlib Animation

はじめに

エビングハウス錯視とは、相対的な大きさに関連する錯視の一種であり、代表的なのは同じ大きさの円がそれぞれ大きな円と小さな円で囲まれている図である。大きな円で囲まれた円は小さく、小さな円で囲まれた円は大きく見える。ここでは、その変化の様子をアニメーションで表示することを試みた。

コード

解説

最初に下記画像を作成する。

モジュールのインポート

左側の図の設定

データの生成

外側の円のためのデータを生成する。媒介変数で円の中心の位置を設定している。

外側の円

xとyはそれぞれ6個あるので、それぞれのx,yでCircleにより円を作成する。
ax.add_patch(circle)で図中に円を表示できる。

中心の円

中心の円も外側の円と同様にして挿入する。

右側の図の設定

左の図と同様に設定する。外側の円は左のものより小さいが、中心の円は、Circle((1, 0), 0.15,color='tab:orange')であり左の図と同じである。

軸とアスペクト比の設定

ax.axis(‘off’)で軸を非表示にできる。ax.axis(“equal”)でアスペクト比が揃うので、円を歪ませないでそのまま表示できる。

この図で左の円群が右に移動し、再び戻る様子をアニメーション表示する。

アニメーションに用いるパラメータ

外側の円の半径の設定

円の半径を0.3から0.1に段階的に小さくするため、np.linspace(0.3,0.1)で配列を作成する。np.linspaceで要素数を省略した場合、要素数は50となる。
0.1から0.3へと大きくするには、前述の配列を[::-1]とすることで逆順とした配列とする。
そして、これらをnp.hstackで結合すれば、0.3から0.1へと小さくなり、0.1から0.3へと大きくなる要素数100の配列が得られる。

外側の円の座標の設定

外側の円の座標の設定をする。横方向の位置は、x_l-1からx_r+1に移動することになる。x_lが配列なので、linspaceで生成する配列は2次元配列となる。
円の半径の変化の場合と同様に逆順の配列を結合する。ここでは、2次元配列なのでvstackを用いる。

縦方向の位置の変化は、y_lからy_rとなるので、横方向の移動と同様に作成する。

中心の円の座標の設定

中心の円の横方向の位置は-1から1となるので、外側の円の座標と同様に作成する。
縦方向の位置は常に0なので、np.zerosですべて0の配列を得る。

figの作成

最初に左の円群を表示する。c1からc6が外側の円で、c_cが中心円となる。

アニメーションの初期設定

return c1, c2, c3, c4, c5, c6, c_cのようにアニメーションする変数をreturnする必要がある。

アニメーションの設定

円の位置はset_centerで設定し、円の半径はset_radiusで設定する。
中心円の半径が変わっているように見えるアニメーションとなっているが、中心円の半径は変えていない。

initと同様にreturn c1, c2, c3, c4, c5, c6, c_cのようにアニメーションする変数をreturnする必要がある。

アニメーションの表示

animation.FuncAnimation() init_func=init,でinit関数を実行し、interval = 50, frames = 100 とすることで50msecの間隔で100フレームのアニメーションとなる。

HTML(ani.to_html5_video())でjupyter notebookやjupyter labでアニメーションを表示できる。

中心円にそった水平線を表示した場合

中心円の大きさが変化していないことがわかる。

コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

参考

エビングハウス錯視 - Wikipedia
https://matplotlib.org/api/_as_gen/matplotlib.patches.Circle.html#matplotlib.patches.Circle
ちょっと脳を混乱させたい人の為の6つの面白錯視アニメーション
image credit:lenstore  なんとも不思議な錯視の中にはもはやわが目も信じられなくなり混乱を…

コメント