非情報系のためのょゎょゎmatplotlib

# ごあいさつ
この記事は[eeic （東京大学工学部電気電子・電子情報工学科） Advent Calendar 2018](https://qiita.com/advent-calendar/2018/eeic) 9日目に参加しています．

内容は，**matplotlibを用いたグラフの表示**です．簡単だね．僕自身ょゎょゎだから許してほしい．

情報系（ここでは日常的に計算機実験などを行い，プログラムを扱うまたは学ぶ環境に属していることを指す）ではない人が，エクセルではちょっと手の届かないプロットをしたいと思った場合って結構しんどいと思うので．情報をまとめておこうかなと思います．

## 内部向け挨拶
こんにちはお久しぶりですはじめまして，eeic2015のじゃがよこです．
現在は電気系ではない専攻に所属していますが，心はいつでも電気系です．
今年は数年ぶりに技術記事で参加してみようと思います．
内容はまあ~~クソ雑魚ナメクジ~~知ってることかもしれないですがゆるしてにゃん．

# はじめに
ここから本編です。
## 緒言
実験データを処理するぞ！
エクセルで扱うにはちょっとサイズが大きいし，gnuplotとかいうのはなんか敷居が高い感じがする……せや！Pythonとかいうのちょっと流行ってるしかっこいいし使ったろ！……というシチュエーションに思い当たる人はいませんか．僕は思い当たります．

そこで，「Python プロット」などとググると，とりあえず次のようにプロットさせようとしてきます．

```Python3
import matplotlib.pyplot as plt
plt.plot(data)
```
ただ描画するだけならたしかにこれでもいいんですが，実際に図を使うためには様々な要素を設定する必要があります．
また，複数の図を並べたりするのもちょっと面倒です．

そこで四苦八苦していたとき，こういうページに出会いました．

[早く知っておきたかったmatplotlibの基礎知識、あるいは見た目の調整が捗るArtistの話](https://qiita.com/skotaro/items/08dc0b8c5704c94eafb9)

plt.plot()のような書き方は，「Pyplotインタフェース」というのだそうです．MATLABっぽい書き方なんだとか．
でもせっかくMATLABじゃなくてPython使ってるんだし，オブジェクト指向インタフェースで書いてみませんか．汎用性が高いのはこっちだと思います．

こうして私はオブジェクト指向インタフェースですべてを書くように切り替え，[matplotlib公式ドキュメント](https://matplotlib.org/devdocs/api/axes_api.html)を参照しながらプロットを作る日々が始まりました．
本記事はmatplotlibオブジェクト指向インタフェースの取っ掛かりになればと思って書いています．

では、早速準備していきたいと思います．
## 想定する環境
MacOS10.12.6，Python3.6で実行しています．
matplotlib 2.0.2，numpy 1.14.5です．バージョンあげてなくてごめんなさい．

```bash
pip install matplotlib
```

必要なものをインポートしておきます．

```python3
import numpy as np
import matplotlib.pyplot as plt
```

## サンプルデータ
散布図用のデータ（ランダム）と波形用のデータ（sin波）を用意しておきます．

```python3
# 波形用サンプル
x0 = np.arange(0,100,1)
y0 = np.sin(x0)

# 散布図用サンプル
x1 = np.random.randn(30)
y1 = x1 + np.random.randn(30)
```

# 描画するための準備
## オブジェクトを作成
artistと呼ばれるオブジェクトを作ります．
グラフに関連するオブジェクトの総称がartistみたいです．
ここにデータをプロットしていくことになります．

```python3
# figureオブジェクトの作成
fig = plt.figure()
# figに属するaxesオブジェクトを作成
ax = fig.add_subplot(1,1,1)
```

詳しくは上述のリンクや[公式FAQ](https://matplotlib.org/1.5.1/faq/usage_faq.html)にも書いてありますが，簡単に解説．
figureオブジェクトは，あなたのまっさらなキャンバス，またはチラシの裏です．ここに絵を描いていきます．
axesオブジェクトは，あなたが心に決めた領域です．チラシを4つに折って広げて，それぞれの領域に絵を描こうと思ったら，その4箇所がそれぞれaxesオブジェクトになります．
axesオブジェクトにはグラフの軸であるaxisオブジェクトとか，線であるところのlineオブジェクトであるとか，そういうのが随時追加されていきます．

## subplotの追加
### add_subplot
引数は順に，「nrows, ncols, index」……すなわち，「何行，何列，番号」となります．
僕は未だに覚えられないんですけど，たぶんこういう図のような関係になっています．
![add_subplot.png](https://qiita-image-store.s3.amazonaws.com/0/94342/836d8fcb-c7b5-9b00-2218-529ce5608bad.png)
axesの間隔とか，そういうのはのちに定義するとして，簡単なグラフならこれで十分です．

### subplot2grid
subplotを追加する方法をもう1つ紹介しておきます．
大きさの違うグラフを並べたいときとかによくやります．

```Python3
plt.subplot2grid(shape, loc, rowspan=1, colspan=1, fig=None)
```

……はい，Pyplotインタフェースじゃねえか，と．返す言葉もないです．
引数figにfigureオブジェクトを渡せば，狙ったfigureに作ってくれると思います．

引数の説明です．

- shape: (nrows, ncols)の順に，figureをいくつに分割するかを指定します．分割数なので1始まり．
- loc: (row, col)の順に，どの位置から描画を開始するかを指定します．add_subplotとは異なり，0始まりです．
- rowspan, colspan: 何個の分割を占めるaxesを作るかを指定します．指定しなければ1分割だけです．


例です．

```Python3
ax1 = plt.subplot2grid((4,5), (0,0), rowspan=1, colspan=1)
ax2 = plt.subplot2grid((4,5), (1,1), rowspan=2, colspan=3)
ax3 = plt.subplot2grid((4,5), (3,0), rowspan=1, colspan=5)
```
配置はこうなります．なんにも調整していないので位置が確保されていることだけ確認してください．
![スクリーンショット 2018-11-17 13.34.22.png](https://qiita-image-store.s3.amazonaws.com/0/94342/f6049c15-8875-9ba3-eaaa-88ccacaf7056.png)

複雑な配置をするときによく使います．
ほかに，add_axesというメソッドがfigureオブジェクトにはあるんですけど，あんまり使いこなせていません．

# 描画する
axesに要素をプロットします．
詳しくは[matpltolib.axes](https://matplotlib.org/devdocs/api/axes_api.html)を参照してください．
## plot
```Python3
ax.plot(x0,y0,fmt)
```
fmtのところにはstrで（' 'でかこって）プロットのスタイルを指定します．
書き方は公式によると次の通り．順番は変わっても大丈夫．

```
fmt = '[marker][line][color]'
```

- marker: マーカーの形状．'.'で点，'o'で丸，'x'でバツなど．
- line: 線の形状．'-'で直線，'--'で破線，':'で点線など．
- color: 色．'r'で赤，'b'で青，'c'でシアン，'m'でマゼンタ，'k'で黒など．

たとえば赤で点線でマーカーを丸にしたいときはfmtの位置に'o:r'とか書いておけばいいわけです．

引数にはこれら以外に，キーワードを指定して渡すことができるものがあります．
例えば線の太さを変えたければ，引数に"linewidth=2.0"などと指定できます．
色も，"color='magenta'"などと指定できます．指定できる色名は[ここ](https://pythondatascience.plavox.info/matplotlib/%E8%89%B2%E3%81%AE%E5%90%8D%E5%89%8D)を参照．
また，凡例を表示するときに便利なので"label='hogehoge'"と指定しておくといいでしょう．

詳しくは[matpltolib.axes.plot](https://matplotlib.org/devdocs/api/_as_gen/matplotlib.axes.Axes.plot.html)を参照してください．

## scatter
```Python3
ax.scatter(x1,y1)
```
一番簡単なのは上記のやりかたです．
これもplotと同様に，キーワード引数が存在します．
点の形状を変えたければ"marker='x'"とか．
詳しくは[matpltolib.axes.scatter](https://matplotlib.org/devdocs/api/_as_gen/matplotlib.axes.Axes.scatter.html)を参照してください．


# カユいところに手を届かせたい
以下には，僕が以前ハマった図の調整について思い出せるままに書いておきます．
##