【Python】蛇使いへの道 (5) Matplotlibと戯れる

Pythonを使ったデータサイエンティストになるための修行です。
ここではPythonデータ解析の3種の神器、Matplotlibをやります。

いままでのPythonの実行はなんでも良かったのですが、これからはipython notebookを使っていきます。

**PREV** →[【Python】蛇使いへの道 (4) Numpyを手なずける](http://qiita.com/Morinikki/items/2104c0f6b03fffa02193)
**NEXT** →[【Python】蛇使いへの道 (6) Pandasを操る](http://qiita.com/Morinikki/items/40faa91e7a83807c0552)

# IPython Notebook
IPythonはpython shellよりも高性能なインタラクティブシェルです。
これをブラウザ上で実行できるようにしたものが IPython Notebook になります。
コードの実行、編集、保存がGUIでできるため、Python 初心者にもオススメです。
また、MatplotlibやPandasなどの主要ライブラリとの連携が取れているので、出力を画像として埋め込むことができます。

以下のコマンドで起動できます。
IPython NotebookはAnacondaに含まれているのですでにインストールされているはずです。
起動に成功すると自動でブラウザが立ち上がります。

```bash:Terminal
$ ipython notebook
```

起動するとこんな感じです。
右の[New] > [Notebooks] > [Python]を選択すると新しいNotebookが作成されます。
![f0ee9d36d4f62936bfc61e7bb14747ad.png](https://qiita-image-store.s3.amazonaws.com/0/99505/bfd23930-82b6-1197-84ef-65a757a8dd5c.png)

Notebookを開いたら好きなようにコードを書くことができます。
Markdownでコメントを書くこともできます。
上の再生マークを押すか、`shift + enter`で実行できます。
![2c0f791bbadaebc727640eea69f67acb.png](https://qiita-image-store.s3.amazonaws.com/0/99505/ee1596ae-503c-3d81-fe68-1b5f0b8a625a.png)

# Matplotlib

## グラフの書き方

まずはmattplotlibのpyplotをpltとしてインポートします。
これは定型的な書き方です。

`%matplotlib inline`はIPython Notebookでmatplotlibのグラフをインラインで表示させるために必要です。


```python
import matplotlib.pyplot as plt
%matplotlib inline
```

とりあえず適当なグラフを描画してみましょう。


```python
plt.plot([1, 3, 2, 4])
```




![output_4_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/16b87279-82b2-a64c-8476-8fa22a9bbdc5.png)


こんな感じでインラインで表示できます。

次はsin波とcos波を書いてみます。


```python
import numpy as np
from math import pi

# 0から2πまで100分割したarrayを生成
x = np.linspace(1, 2*pi, 100)
y = np.sin(x)
plt.plot(x, y)
# グリッド線を描画
plt.grid()
# ラベルを描画
plt.legend(['sin(x)'])
```



![output_7_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/c7aa5c2d-de76-bc18-42bd-a288d99fda6c.png)



## 複数のLine

`%pylab`と入力するとnumpyやmatplotlibなどがすでにインポートされた状態になります。


```python
%pylab
```


複数のLineを描画するにはplot(x1, y1); plot(x2, y2)のように分けるか、plot(x1,y1,x2,y2)のように一つにまとめてplotします。
xが共通ならyはnp.arrayが使える。


```python
# 0から1まで0.01刻みでarrayを生成
x  = arange(0, 1, 0.01)
# 3つの1D arrayを縦に積んで2D arrayを作る
a1 = vstack((x, x**2, x**3)); a1
# 転置して描画する
plot(x, a1.T)
grid()
legend('X X^2 X^3'.split(), loc='best')
```

![output_12_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/2eef4761-867c-c578-86f1-ea234db788a9.png)




## ファイルへの出力

上記の図をファイルに出力する。


```python
savefig('lines.png')
```

!をつければシェルのコマンドも使えます。


```python
>>> !ls *.png
lines.png
```



## Object明示方式

これまで説明したようにObjectを明示しなくてもMatplotlibは利用できますが、複数のグラフやLineを操作する場合はこれらのObjectを明示的に操作するほうが良いです。


```python
x = linspace(0, 2*pi, 100)
figure1 = gcf()
axis1 = gca()

line1, line2, = axis1.plot(x, sin(x), x, cos(x))
line3, = axis1.plot(x, sin(x)+cos(x))
axis1.legend([line1, line2, line3], ['sin', 'cos', 'sin+cos'])
```




![output_20_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/c4dfd64a-9525-5f5a-e205-08baaae42ced.png)



## 軸の設定


```python
x = linspace(-10, 10, 200)
y = exp(-x ** 2)
plot(x, y)
grid()
# x軸のラベルを書く
xlabel('position')
# y軸のラベルを書く
ylabel('density')
```




![output_22_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/22dcd572-cd19-0554-05bb-291dec2a80c1.png)




```python
plot(x, y)
# 自動設定された軸の範囲を調べる
xmin, xmax, ymin, ymax = gca().axis()  
# 軸の範囲を調整して少し見やすくする
xlim([xmin*0.5, xmax*0.5])
ylim([ymin-0.1, ymax+0.1])
grid()
xlabel('position')
ylabel('density')
```



![output_23_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/765fa8a6-9174-2f24-60a4-2817af96ee81.png)



## Line style

線の色や形を変えることができます。


```python
from numpy.random import random


for i, style in enumerate(['r-o', 'g:x', 'b--^', 'm-.s']):
    plot(random(10)+i, style)
```


![output_26_0.png](https://qiita-image-store.s3.amazonaws.com/0/99505/8732a312-5a98-9191-8038-2edfd373574d.png)



## 棒グラフ


```python
left = np.array([1, 2, 3, 4, 5])
height1 = np.array([100, 200, 300, 400, 500])
height2 = np.array([1000, 800, 600, 400, 200])
p1 = plt.bar(left, height1, color="green")
p2 = plt.bar(left, height2, bottom=height1, color="orange")
```


![output_28_0.png](https://qiita-image-store.s3.amazonaws.com/0/99505/8986b7ea-2f79-d58e-2f79-5322eb9ae940.png)



## 積み上げグラフ


```python
a1 = random((4,10))
x = range(10)
colors = list('rgbm')
stackplot(x, a1, colors=colors)
bars=[bar([0], [0], color=color) for color in colors]
```


![output_30_0.png](https://qiita-image-store.s3.amazonaws.com/0/99505/8cd3c120-e39d-1454-43c1-5ca55fcf97f8.png)



## 散布図

直交座標での散布図(scatter graph)


```python
t = linspace(0, 2*pi, 1000)  # 角度
x = sin(3*t)
y = cos(5*t)
scatter(x, y, s=10)  # sは点の大きさ
```


![output_33_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/399d20b7-a40d-469a-d4aa-6c2da9b993c3.png)



極座標でのグラフ


```python
r = sin(2*t)
polar(t, r)
```


![output_35_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/738992ac-9fb5-a234-276d-d8ba8642a88f.png)



## 等高線

```math
z(x,y)=x^2+y^3
```
の色分けした等高線を描画する。


```python
x1 = y1 = linspace(-1, 1, 10)
x, y = meshgrid(x1, y1)
z = x**2 + y**3
n = linspace(-2, 2, 20)  # 等高線密度
contourf(x, y, z, n) # z軸が色で表現される
grid()
```


![output_38_0.png](https://qiita-image-store.s3.amazonaws.com/0/99505/5a81396d-f5d5-92cc-fffd-0fe6af67653e.png)



## 3Dグラフ


```python
# 3D用にモジュールをインポートします
from mpl_toolkits.mplot3d import Axes3D

figure1 = gcf()
axis1 = Axes3D(figure1)
x1 = y1 = linspace(-5, 5, 50)
x, y = meshgrid(x1, y1)
z = exp(-(x**2 + y**2))
axis1.plot_surface(x, y, z, rstride=1, cstride=2)
```



![output_40_1.png](https://qiita-image-store.s3.amazonaws.com/0/99505/95403edd-909e-2d42-81c8-5068ed9bd9c4.png)



**NEXT** →[【Python】蛇使いへの道 (6) Pandasを操る](http://qiita.com/Morinikki/items/40faa91e7a83807c0552)