Matplotlibでグラフを作図-02 円を作図して簡単な信号機アニメーションを実行する

Matplotlibでグラフを作図-02 円を作図して簡単な信号機アニメーションを実行する

モモノキ&ナノネと一緒にMatplotlibを使ってグラフの作図方法を学習していきます。

モモノキ&ナノネと一緒にMatplotlibで円を描く方法を練習しよう




Matplotlibで円を描く方法と簡単な信号機アニメーションに挑戦

今回はMatplotlibを使って、円を作図する練習をやってみよう。

ただ丸を描くだけ?

うん。丸を描くだけだよ。

前に試した正弦波以外の作図アニメーションをやろとしたんだけど、図形の描き方が分からなかったから調べてみた。

なるほど。グラフに図形を付け加えたいときもありそうだから、描き方を覚えてみる。

Matplotlibで図形を描くには『patches』を使えばいいみたい。円はpatches.Circle()で描けるよ。コードはこんな感じで、引数xyに中心座標、radiusに半径を指定すればOK。

In [13]:
# Jupyter Notebook上でインタラクティブに表示
%matplotlib nbagg 
# %matplotlib inline

import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig, ax = plt.subplots(figsize=(3, 3))
circle = patches.Circle(xy=(0, 0), radius=1.0)
ax.add_patch(circle)
# plt.show()
Out[13]:
<matplotlib.patches.Circle at 0x203a401dda0>

円じゃなくて扇形だけど?

全表示されていないだけで、軸スケールを調整すれば円になるよ。

ナノネ、set_xlimとset_ylimで、円が全部収まるように軸範囲を設定してみて。

In [11]:
fig, ax = plt.subplots(figsize=(3, 3))
ax.set_xlim(-1.5, 1.5) # x軸範囲
ax.set_ylim(-1.5, 1.5) # y軸範囲
circle = patches.Circle(xy=(0, 0), radius=1.0)
ax.add_patch(circle)
Out[11]:
<matplotlib.patches.Circle at 0x203a3f526d8>

隠れてたところも表示したら、ちゃんと円になった。

軸範囲の設定が面倒だったら、自動調整を利用してもOKだよ。axis('scaled')と.set_aspect('equal')を使うと、データに応じてスケールとアスペクト比を調整してくるよ。

In [12]:
fig, ax = plt.subplots(figsize=(3, 3))
# ax.set_xlim(-1.5, 1.5) # x軸範囲
# ax.set_ylim(-1.5, 1.5) # y軸範囲
circle = patches.Circle(xy=(0, 0), radius=1.0)
ax.add_patch(circle)
ax.axis('scaled')
ax.set_aspect('equal')

軸の自動調整も便利だね。

色設定はpatches.Circle()のオプション引数で設定できるよ。

fc(face color)で塗り潰す色、ec(edge color)で円周の線色をそれぞれ設定できるよ。色の指定方法はカラー名やRGBなど多数あるからお好みで。

In [14]:
fig, ax = plt.subplots(figsize=(3, 3))
circle = patches.Circle(xy=(0, 0), radius=1.0,
                        fc='y',
                        ec='r'
                       )
ax.add_patch(circle)
ax.axis('scaled')
ax.set_aspect('equal')

円周を赤、中を黄色に変更してみた。

塗り潰しが不要なときは、オプション引数でfill=FalseとすればOKだよ。

In [15]:
fig, ax = plt.subplots(figsize=(3, 3))
circle = patches.Circle(xy=(0, 0), radius=1.0,
                        ec='r',
                        fill=False
                       )
ax.add_patch(circle)
ax.axis('scaled')
ax.set_aspect('equal')

OK、塗り潰し無くなった。

線の太さはlinewidthで設定できるよ。

In [16]:
fig, ax = plt.subplots(figsize=(3, 3))
circle = patches.Circle(xy=(0, 0), radius=1.0,
                        ec='r',
                        linewidth=10,
                        fill=False
                       )
ax.add_patch(circle)
ax.axis('scaled')
ax.set_aspect('equal')

線を太くしてみた。

オプションで設定できる項目は他にもたくさんあるから、詳しくは公式ドキュメントを調べてみてね。

matplotlib.patches.Circle(公式ドキュメント)
matplotlib.patches.Circle:外部サイト

ナノネ、円の練習の最後に信号機を作図してみて。

信号機?
三色の円を並べるだけね。

In [17]:
fig, ax = plt.subplots()
ax.patch.set_facecolor('#cccccc')  # axesの背景色

circle_green = patches.Circle(xy=(-2.5, 0), radius=1.0,
                        ec='gray', fc='g') # 青信号(緑色)
circle_yellow = patches.Circle(xy=(0, 0), radius=1.0,
                        ec='gray', fc='y') # 黄信号
circle_red = patches.Circle(xy=(2.5, 0), radius=1.0,
                        ec='gray', fc='r') # 赤信号

ax.add_patch(circle_green)
ax.add_patch(circle_yellow)
ax.add_patch(circle_red)

ax.axis('scaled')
ax.set_aspect('equal')

信号機の作図完了。

信号機できたね!
せっかくなので、前に練習したアニメーション方法で一色ずつ点灯させてみよう。冗長的だけど下のコードでも点灯できるよ。

In [19]:
# Jupyter Notebook上でインタラクティブに表示
%matplotlib nbagg 
# %matplotlib inline

import matplotlib.pyplot as plt
# import matplotlib.patches as patches
import matplotlib.animation as animation

fig, ax = plt.subplots(figsize=(4, 2))
fig.patch.set_alpha(1.0) # figure不透明
ax.patch.set_facecolor('#cccccc')  # axesの背景色
plt.axis([-4, 4, -1.5, 1.5])
ax.set_aspect('equal')

# 信号機(3色分)
# patches.Circle()ではアニメーションが動作せず、plt.Circleに変更した
circle_green = ax.add_patch(plt.Circle(xy=(-2.5, 0), radius=1.0, ec='gray', fc='gray'))
circle_yellow = ax.add_patch(plt.Circle(xy=(0, 0), radius=1.0,ec='gray', fc='gray'))
circle_red = ax.add_patch(plt.Circle(xy=(2.5, 0), radius=1.0,ec='gray', fc='gray'))

def init():
    # initialize :nothing
    return fig,

def animate(i):
    if i==0: # 青信号
        circle_green.set_fc('#00cc55')
        circle_yellow.set_fc('gray')
        circle_red.set_fc('gray')
    elif i==1: # 黄信号
        circle_green.set_fc('gray')
        circle_yellow.set_fc('#ffcc00')
        circle_red.set_fc('gray')
    elif i==2: # 赤信号
        circle_green.set_fc('gray')
        circle_yellow.set_fc('gray')
        circle_red.set_fc('#cc0000')
        
    return fig,

ani = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=3, interval=1000, blit=True)
plt.show()
In [9]:
# gifファイルに出力
ani.save("traffic-light.gif", writer='imagemagick') # gifファイルに出力(ImageMagick利用)

保存したgif画像を表示すると、こんな感じて動くよ。

信号機の点灯、うまくいったね。
でも、データ解析になにか役立つ?

....。

またね。







スポンサーリンク

0 件のコメント :

コメントを投稿