読者です 読者をやめる 読者になる 読者になる

MyEnigma

とあるエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

MATLABユーザのためのPythonグラフ作成ツールmatplotlib入門

Python

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

目次

はじめに

多くの人にとって、

MATLABを使っている理由の一つは、

強力なグラフツールだと思います。

 

最近、MATLABも安く手に入るようになってきましたが、

myenigma.hatenablog.com

LinuxやMacなど色々なプラットフォームで使いたくなるので、

MATLABも使いづらい所があります。

 

そこで良くMATLABの代わりに使われるのがPythonです。

Pythonは非常に広く使用されているフリーの汎用プログラミング言語ですが、

機械学習や、確率統計の分野で広く使用され、

フリーのライブラリも数多く提供されているため、

使用する人が多いようです。

 

そんなPythonには、matplotlibという

強力なグラフツールがあります。

このライブラリを使いこなすことができれば、

pythonをMATLABの代わりに使うことも出来そうです。

 

このmatplotlibを上手く使うことで、

MATLABのような見やすいグラフや、

インタラクティブなグラフ

そして、簡単なアニメーションなどを作ることができます。

 

今回はMATLABユーザの視点で、

matplotlibの使い方を説明したいと思います。

matplotlibのダウンロード

ソースコードやインストーラは下記のページにおいてあります。

pipで入れることもできますが、

下記の記事のように、色々依存関係で落とし穴があるみたいなので、

注意してダウンロードしましょう。

 

どんなグラフを作ることができるのかは、

下記の公式ページの例やギャラリーを見るとわかりやすいかと思います。

線グラフ

下記は基本的な線グラフのサンプルコードです。

from pylab import *

t = arange(0.0, 1.0+0.01, 0.01)
s = cos(2*2*pi*t)
plot(t, s, '-', label="data1",lw=2)

xlabel('time (s)')
ylabel('Speed (m/s)')
title('Test')
legend()
grid(True)

show()

すると下記のようなグラフが表示されます。

f:id:meison_amsl:20150830213659p:plain

MATLABと違う所は、

凡例はplot関数の中で指定すること、

gridの設定方法が異なること、

線の太さはlw(linewidth)引数に入れる

plotだけではグラフは表示されず、show関数が必要なことです。

 

ちなみに、左下のボタンを使えば、

グラフをズームしたり、

グラフを画像に変換したりできます。

棒グラフ

下記は基本的な棒グラフのサンプルコードです。

#!/usr/bin/env python
from pylab import *

figure(1)
y = [15, 30, 45, 10, -5]
x = np.array([1, 2, 3, 4, 5])

bar(x, y, align = "center")
grid(True)
show()

すると下記のような棒グラフを書くことができます。

f:id:meison_amsl:20150830222709p:plain

 

等高線グラフ

contour関数を使います。

4つ目の引数は等高線の数で、

数を増やすと、

細かく等高線を書くことができます。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np

delta = 0.1
minXY=-5.0
maxXY=5.0
nContour=50

def HimmelblauFunction(x,y):
    return (x**2+y-11)**2+(x+y**2-7)**2

def CreateMeshData():
    x = np.arange(minXY, maxXY, delta)
    y = np.arange(minXY, maxXY, delta)
    X, Y = np.meshgrid(x, y)
    Z=[HimmelblauFunction(x,y) for (x,y) in zip(X,Y)]
    return(X,Y,Z)

(X,Y,Z)=CreateMeshData()
CS = plt.contour(X, Y, Z,nContour)
plt.show()

するとこのようなグラフが書けます。

f:id:meison_amsl:20160502150612p:plain

 

また、

下記のようにclabel関数を呼ぶと、

CS = plt.contour(X, Y, Z,nContour)
plt.clabel(CS, inline=1, fontsize=10)

等高線にそれぞれの値を数字で記入してれます。

f:id:meison_amsl:20160502152659p:plain

 

 

三次元プロット

f:id:meison_amsl:20160515085416p:plain

 

下記は基本的な三次元プロットのサンプルコードです。

Axes3Dを使うことで、

通常の二次元plotと同じように

三次元プロットをすることができます。

#!/usr/bin/env python
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

def AxisEqual3d(x,y,z):
    #for 3d axis equal
    max_range = np.array([x.max()-x.min(), y.max()-y.min(), z.max()-z.min()]).max()
    Xb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][0].flatten() + 0.5*(x.max()+x.min())
    Yb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][1].flatten() + 0.5*(y.max()+y.min())
    Zb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][2].flatten() + 0.5*(z.max()+z.min())
    for xb, yb, zb in zip(Xb, Yb, Zb):
        ax.plot([xb], [yb], [zb], 'w')


x=np.array([0,2,4])
y=np.array([0,2,4])
z=np.array([1,3,5])

fig2 = plt.figure()
ax = Axes3D(fig2)
ax.plot3D(x,y,z,"-*r")
ax.set_xlabel("x[m]")
ax.set_ylabel("y[m]")
ax.set_zlabel("z[m]")
AxisEqual3d(x,y,z)
plt.show()

一つ注意点として、三次元プロットでは、

axis("equal")しても三軸の座標軸はサイズが合いません、

そんな時は上記のようなAxisEqual3d(x,y,z)を使うことで、

無理やり座標系を合わせることができます。

 

また、残念ながら自分のMacでは

上記の3次元プロットは表示できませんでした。

WindowsとUbuntuはOKでした。

 

ヒストグラム

下記は基本的なヒストグラムのサンプルコードです。

#!/usr/bin/env python
from pylab import *
import numpy as np

figure(1)
x = np.random.normal(size = 100)

hist(x)
title("Histgram")
xlabel("x")
ylabel("frequency")
show()

すると下記のようなヒストグラムを書くことができます。

f:id:meison_amsl:20150830222952p:plain

 

ちなみに

hist(x, normed = True)

とすると、ヒストグラムの縦軸を正規化することができます。

f:id:meison_amsl:20150830223249p:plain

円グラフ

下記は基本的な円グラフのサンプルコードです。

#!/usr/bin/env python
from pylab import *

labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
fracs = [15, 30, 45, 10]

figure(1)
pie(fracs, labels=labels, autopct='%1.1f%%', shadow=True)

savefig('pie_demo')
show()

すると、下記のような円グラフを書くことができます。

f:id:meison_amsl:20150830221635p:plain

 

autopctは割合を円グラフに表示する引数です。

またsavefigでグラフを保存することができます。  

グラフに水平線・垂直線を引く

axvlineとaxhlineという関数を使いましょう。

import numpy as np
import matplotlib.pyplot as plt

x = np.random.normal(size=100)
y = np.random.normal(size=100)
plt.plot(x,y,'g.')
plt.axvline(x=1, color='red')
plt.axhline(y=2, color='blue')
plt.show()

f:id:meison_amsl:20151014213207p:plain

簡単なGUIツールを作成する方法

あまり知られていませんが、

matplotlibのみで、簡単なGUIツールも作ることができます。

ボタンを作る

上記のサンプルコードを実行すると、

下記のようなボタン付きのグラフを作ることができます。

f:id:meison_amsl:20150830172631p:plain

このサンプルでは、

NextとPreviousのボタンでグラフのレンジを変更できます。

チェックボタンを作る

上記のサンプルコードを実行すると、

下記のように

チェックボタンで描画するグラフを選ぶグラフを作れます。

f:id:meison_amsl:20150830173128p:plain

カーソルの位置を取得し表示

上記のサンプルコードを実行すると、

下記のように

カーソルの位置を取得して表示することができます。

f:id:meison_amsl:20150830175929p:plain

 

指定した領域のデータを抽出する

上記のサンプルコードを実行すると、

下記のようにクリックしながら、

マウスで書いた領域の中の

データを抽出することができます。

f:id:meison_amsl:20151011230114p:plain

 

メニューボタンを作る

上記のサンプルコードを実行すると、

下記のように、メニューリストをグラフ内に表示することができ、

それらのボタンを押すことでプログラムを制御することができます。

f:id:meison_amsl:20150830200840p:plain

 

ラジオボタンの配置

上記のサンプルコードを実行すると、

下記のように、ラジオボタンをグラフ内に配置することができ、

それらのボタンを押すことでプログラムを制御することができます。

f:id:meison_amsl:20150830201415p:plain

 

スライダーの配置

上記のサンプルコードを実行すると、

下記のように、スライダーをグラフ内に配置することができ、

それらのスライダーを調整することでプログラムを制御することができます。

f:id:meison_amsl:20150830204755p:plain

 

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

MATLABの可視化機能の中で

最も素晴らしいものの一つは

簡単にアニメーションを作ることができる所です。

 

matplotlibでも同じように

通常のプロット関数を複数回呼ぶことで、

アニメーションを作ることができます。

下記のサンプルコードを起動すると、

Sinカーブがアニメーションで描画されます。

fig, ax = plt.subplots(1, 1)
x=0
y=np.sin(x)

while True:
        # plotデータの更新
        x += 0.1
        y = np.sin(x)
        ax.plot(x,y,".r")
        plt.pause(.01)#描画するまでの時間[sec]

f:id:meison_amsl:20151012184748p:plain

 

アニメーションを動画として保存する

matplotlibのanimationモジュールを使うと、

簡単にアニメーションを動画として保存できます。

 

下記のサンプルのように

plotのフレームをリストにし、

それをArtistAnimation関数に渡し、

アニメーションオブジェクトを作成します。

あとはSave関数でそのアニメーションを

動画として保存することができます。

 

f# -*- coding: utf-8 -*-
from pylab import *
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
xlist = range(1, 700)
frame_list = []
xl=[]
yl=[]

for x in xlist:
    xl.append(x)
    yl.append(sin(x*3.14/180))
    one_frame = plot(xl, yl)
    frame_list.append(one_frame)

ani = animation.ArtistAnimation(fig, frame_list, interval = 40, repeat_delay = 20)
ani.save("animation.mp4")

 

すると下記のようなサインカーブが伸びる

アニメーションのmp4ファイルが出来ているはずです。

 

ちなみにMacの場合は動画ファイルを作るのに

ffmepgが必要とのことだったので、

下記のコマンドでインストールしました。

brew install ffmpeg

 

MATLABとmatplotlibの相違点

簡単に表にまとめておきます。

MATLAB matplotlib
グラフの表示 plot関数 plot関数+show関数
線の太さの設定 plot(a,b,LineWidth,10) plot(a,b,lw=10)
凡例の設定 legend("a","b") plot関数のlabel引数で設定して、legend() or リストで渡す legend(["velo"])
グラフ罫線の設定 grid on grid(True)
座標軸の非表示 axis off axis("off")
座標軸のスケールを合わせる axis equal axis("equal")
タイトルの設定 title("hoge") set_title("hoge)
x軸のタイトルの設定 xlabel("hoge") set_xlabel("hoge)
y軸のタイトルの設定 ylabel("hoge") set_ylabel("hoge)
x軸の表示範囲 axis([0 0 1 1]) ax.set_xlim(0, 50)
y軸の表示範囲 axis([0 0 1 1]) ax.set_ylim(0, 50)

 

複数のグラフを生成する

一つのスクリプトで、

複数のグラフを書きたい時は、

それぞれのグラフを書く前に、

下記のコマンドでグラフと軸のオブジェクトを作成し、

その後plot関数を呼べば、

複数のグラフを作成することができます。

#plot1
fig, ax=plt.subplots(1)
plot(x1)

#plot2
fig, ax=plt.subplots(1)
plot(x2)

plt.show()

  

C++のコードからmatplotlibの機能を使う

こちらの記事を参照下さい

myenigma.hatenablog.com

 

参考資料

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理