Python3 – xのn乗のグラフ(matplotlibのsubplotとアニメーション)

GIFアニメーション

matplotlibのアニメーション作成は2つ種類があって、ArtistAnimationとFuncAnimationとがある。

参考:matplotlib でアニメーションを作る

ArtistAnimation は、あらかじめ全てのグラフを配列の形で用意しておき、それを1枚ずつ流すというものである。FuncAnimationは予め完成したグラフを渡すのではなく、アニメーションの1フレームごとに関数を実行する。データが巨大すぎる場合や潜在的に無限に続く場合に便利。

ArtistAnimation

ArtistAnimationを使って、xの2乗~10乗のグラフを配列に入れて、アニメーションをつくってみる。

サンプルコード

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def xpown(s, e):
    graphs = []
    fig = plt.figure()
    for n in range(s, e + 1):
        x = np.arange(-100, 100, 0.1)
        y = x ** n
        g = plt.plot(x, y, label='y = x ** {}'.format(n))
        graphs.append(g)
    plt.legend()
    ani = animation.ArtistAnimation(fig, graphs, interval=500)
    ani.save('pow1.gif', writer='imagemagick')

if __name__ == '__main__':
    xpown(2, 10)

結果

これだと、10乗のグラフのyが大きすぎて、他がみんな直線みたいになってしまった。

FuncAnimation

FuncAnimationを使ってやってみる。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

x = np.arange(-100, 100, 0.1)
n = 1
max = 10
fig = plt.figure()

def plot_pow(data):
    plt.cla()
    global n
    n = n + 1 if n < max else 2
    y = x ** n
    im = plt.plot(x, y, label='y = x ** {}'.format(n))
    plt.legend()

if __name__ == '__main__':
    ani = animation.FuncAnimation(fig, plot_pow, interval=400, frames=9)
    ani.save("pow2.gif", writer="imagemagick")

結果

指数が偶数ならy軸に対称のグラフになり、奇数なら原点に対象のグラフになります。原点に対象っていうのか。

Subplot

matplotlibで複数のグラフを表示したいときにsubplotが使えます。
参考:[Python]Matplotlibで複数のグラフを描画する方法

サンプルコード

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-100, 100, 0.1)
fig = plt.figure()
ax = []
for i in range(9):
    y = x ** (i ++ 2)
    ax.append(plt.subplot2grid((3, 3), (i // 3, i % 3)))
    ax[i].set_title('y = x ** {}'.format(i + 2))
    ax[i].plot(x, y)
plt.show()

結果

Python3 – matplotlibでアニメーションGIFをつくる

matplotlib.animatioを使うとアニメーションがつくれます。自分の環境ではgifで保存しようとしたら、imagemagickがなくてエラーになりました。imagemagickのインストールとかはここに書いてありました。

Imagemagick

http://www.imagemagick.org/script/binary-releases.php#windows

Imagemagickのパスをmatplotlibに設定する必要がある。下記のようにするとmatplotlibが見ている設定ファイルの場所がわかる。

import matplotlib
print(matplotlib.matplotlib_fname())

自分はユーザディレクトリ内のAnaconda3の中の下記だった。

Anaconda3\lib\site-packages\matplotlib\mpl-data\matplotlibrc

matplotlibrcの最後の行らへんに、下記行があるので、ここにImagemagickのパスを入れる。

#animation.convert_path: 'convert' # Path to ImageMagick's convert binary.

コメントを外して、下記のように入力します。入力の際、パスを「’」で囲むと下記のようなエラーになります。

animation.convert_path: D:\ImageMagick-7.0.4-Q16\magick.exe


C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py:782: UserWarning: MovieWriter imagemagick unavailable
warnings.warn(“MovieWriter %s unavailable” % writer)
Traceback (most recent call last):
File “C:/Users/hoge/hoge.py”, line 15, in
ani.save(‘sample.gif’, writer=’imagemagick’)
File “C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py”, line 810, in save
writer.grab_frame(**savefig_kwargs)
File “C:\Users\hoge\Anaconda3\lib\contextlib.py”, line 66, in __exit__
next(self.gen)
File “C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py”, line 196, in saving
self.finish()
File “C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py”, line 389, in finish
+ ‘ Try running with –verbose-debug’)
RuntimeError: Error creating movie, return code: 1 Try running with –verbose-debug

サンプルコード

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def anim():
    graphs = []
    fig = plt.figure()
    x = np.arange(-50, 50, 0.1)
    y = x ** 2
    for i in range(50):
        plt.plot(x, y)
        g = plt.plot(i, i ** 2, 'o')
        graphs.append(g)
    ani = animation.ArtistAnimation(fig, graphs, interval=50)
    plt.show()
    ani.save('anim.gif', writer='imagemagick')

if __name__ == '__main__':
    anim()

Python – Matplotlibで3次元グラフを書く

下記の式をグラフ化してみる。


$$f(x_0, x_1)=x_0^2+x_1^2$$

コード

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def func(x0, x1):
    return x0**2 + x1**2

x0 = np.arange(-3, 3, 0.25)
x1 = np.arange(-3, 3, 0.25)
X0, X1 = np.meshgrid(x0, x1)
Y = func(X0, X1)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(X0,X1,Y)
plt.show()

参考:matplotlibで3Dグラフを描画する

Python – matplotlibの使い方

matplotlibは、pythonでグラフとかかけるやつです。インストールは、ここに説明があります。ギャラリーみるとかなり色々なグラフをかけるようです。使い方のドキュメントはここです。

グラフを書いてみる

plot()でプロットできます。引数は1つだとyだけ、2つだと、x,yの順になるみたい。ylabelとかでラベルも設定できる。show()で表示することができる。

import matplotlib.pyplot as plt
plt.plot([1,200,3, 100, 30], [2, 4, 6, 9, 20])
plt.ylabel('hogehoge')
plt.show()

g1

参考:matplotlib入門

numpyと一緒につかってサインコサインとか簡単にかけるらしい。

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-3, 3, 0.1)
y = np.sin(x)
plt.plot(x, y)
plt.show()

g2

np.arangeで、-3から3までを0.1間隔でつくってる。np.sin(x)とやると、xに入ってる要素に応じた結果が配列で返ってくる。1次関数を簡単に書く方法はないのでしょうか?たとえば、y = 3x + 3という数式を入れたらパッと表示されるとか。できた。numpy便利だな。

1次関数

x = np.arange(0, 3, 0.1)
y = 2 * x + 5
plt.plot(x, y)
plt.show()

g3

2次関数

x = np.arange(-10, 10, 0.1)
y = 2 * x**2 + 3 * x - 4
plt.plot(x, y)
plt.show()

g4

3次関数

x = np.arange(-10, 10, 0.1)
y = 3 * x**3 + 2 * x**2 + 3 * x - 4
plt.plot(x, y)
plt.show()

g5

4次関数

x = np.arange(-10, 10, 0.1)
y = 4*x**4 + 3*x**3 + 2*x**2 + x + 5
plt.plot(x, y)
plt.show()

g6

散布図

散布図は、plot(x, y, ‘o’)といった感じで、第三引数に文字いれればできる。文字はなんでもいいわけではなく、決まりがある。o(オー)だと〇とか。roとやると赤い〇になる。dとか1とかも使えた。

x = np.arange(-10, 10, 0.5)
y = 3 * x + 5 + np.random.randn(40) * 5
plt.plot(x, y, 'rd')
plt.show()

g7