Pythonグラフ描画ライブラリ matplotlib を触る

# matplotlib
前回の記事で少し触ったけど、もう少し色々深めてみる
公式サイト： https://matplotlib.org/

## Jupyter Notebookで使う
matplotlib は JupyterNotebook 上でも使うことができ、インラインで表示ができる
インラインにこだわる必要はないが、別にする意味もないので
今回もJupyterNotebook上で試そうと思う　環境面で楽だし！

## 掘っていく
### 基本　おさらい（サンプルコードのみ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/280d035c-a741-1249-f83e-4862746b7d04.png)
そうだったそうだった
※ 使えるグラフのスタイルは `plt.style.available` で確認が可能！（複数指定も可　詳細はwebで！）

### 記述方法
#### MATLABスタイル
- 上記のように `plt.plot()` のように `matplotlib.pyplotモジュール` を使って記述していく方法

#### オブジェクト指向スタイル
- 描画オブジェクトとサブプロットを用いて記述していく方法で、MATLABスタイルよりは複雑
- メリット
    - １つの描画オブジェクト(`fig`)に対して、複数のサブプロットを持つことができる
    - そのため、複数のグラフを組み合わせての描画が可能

### 描画オブジェクトとサブプロット
#### 関係
- `fig, ax = plt.subplots()`
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/4695df07-dd59-5526-f508-3663e50929fd.png)

    - １つの描画オブジェクト（fig）に対し、１つのサブプロットを作成している
    - １つのサブプロットに対し、２回plotしているため同じグラフに２本描画される
- `fig, axes = plt.subplots(2)`
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/041a82ba-b1c0-1e02-9207-7652a6d0d25e.png)
    - １つのfigに対して、２つのサブプロットを作成
    - `axes[0]` `axes[1]` という別々のサブプロットを使って描画している
- `fug, axes = plt.subplots(1, 2)`
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/7a89504b-1f30-43ec-b5f8-3402aea272df.png)
    - `plt.subplots(n, m)` でn行m列のサブプロットを作成できる
    - 例の場合、1行x２列のサブプロットが作成され、それぞれに描画をしている

#### サブプロットのタイトル
簡単！ `axes[0].set_title('タイトル！')` って感じで書くとつけられる

#### 凡例の表示
こんなんもできるんや・・・さすがグラフ描画専門

##### 記述方法
- 方法１
    - 各グラフ描画時に`label`を指定する
    - `legend`で表示
      ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/4d3e82ac-b945-310b-c35b-accb7ed1b007.png)

- 方法２
    - `legend` で表示時に`label`を指定する
      ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/9efd9f66-7a83-b433-3b7f-0555aed29a50.png)

サブプロットも１種のオブジェクトとして捉えると、方法１の方が個人的にはわかりやすいし変更しやすいかもー！
でもCSVから読んだヘッダーとかを凡例として使うなら、方法２の方が楽チンやな〜　実装次第で臨機応変にですな。

##### 位置
凡例の位置も当然変更できて、`loc`オプションで指定ができる
`ax.legend(loc='lower right')` とかやれば右下に表示される
~~センスに自信がない人は~~ `ax.legend(loc='best')` で丸投げできるw　１番いいやつを頼む

#### 軸の名前
- `ax.set_xlabel('X Label')`
- `ax.set_ylabel('Y Label')` 
うん、そのまんまですな
- オプションもつけられる  `ax.set_xlabel('X Label', style='italic', size=10)`

#### 軸の項目名
これがなくては折れ線グラフとして機能しないよね〜
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/ae2f7eb4-0358-c7d2-0cac-ed2938876b69.png)
実は `ax.plot(['2, 1, 3'])` とか書いてたやつは、 `ax.plot([0, 1, 2], ['2, 1, 3'])` の略だったんだって！
第１引数：[0, 1, 2]がx座標、第２引数：['2, 1, 3']がy座標を表している
項目名は、`ax.set_xticks`で項目名を設定する位置を指定して、`ax.set_xticklabels`で名称を設定する（y軸も同様）
**テキスト挿入**
`ax.text(1,6, 2.9, 'Peak', size=12)` って感じで好きな位置にテキストの挿入ができる

#### おまけ
グラフのスタイルは色から値のポイントマークの形、線のスタイルまで個別に指定できる
`ax.plot([2, 1, 3], color='r', marker='s', linestyle='--', linewidth='3')`
または省略して
`ax.plot([2, 1, 3], 'rs--', linewidth='3')`
でもいける。この略し方クールやなぁ

オプション名|意味|使い方
---|---|---
color|線、ポイントの色|`r`: 赤　`b`: 青　`k`: 黒　など
marker|ポイントの形|`.`: ドット　`s`: 四角　`*`: 星　など　
linestyle|線の種類|`-`: 実線　`--`: 点線　`-.`: 一点鎖線　`:`: ドット　空文字: なし　など
linewidth|線の太さ|3　など

### すでに盛りだくさん感があるが・・・
#### 棒グラフ
折れ線グラフは`plot`で値を置いていったけど、`bar`で置いていくことで棒グラフで描画できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/048e0014-e9fb-add3-8e4d-e9ffcd9446de.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/ebd9c9cf-dc73-3a65-f53a-eb6126238ac6.png)
`x2`が若干ややこしいけど、隣に描画するために棒の幅分プラスしてあげてるんやな、なるほど
隣に描画できるなら上に積み重ねることもできて、その場合は`x1`は固定で
`ax.bar(x1, y2, bottom=y1, width=width, ~~~~)`
というふうにボトム（つまり０とする位置）を指定してあげると縦に積み重なる

#### 円グラフ
`pie`で描画する　あのパイ生地のパイに例えてるの？　オシャレすぎる・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/42f41cdd-c9aa-cd5c-39ea-0bc2eb5bd4c1.png)
やっやこしっ！ オプション名でだいたいわかるけど、これだけ覚えてれば良さそうね

オプション名|意味|使い方
---|---|---
explode|中心から<br>どれぐらい離すか|[0, 0.1, 0]（割合）<br>半径x0.1離れる　など
labels|項目名|そのまんま
autopct|パーセンテージ表示方|`%.1f%%`: 小数点以下1桁と「%」<br>関数等も指定できるので必要に応じて調べる
startangle|開始角度|90（時計で言うと１２時が90度、３時が０度）
counterclock|反時計回りか|True/False 反時計にしたい時ってあるのか？w

`ax.axis('equal')`はグラフのアスペクト比調整の呪文らしいので書いておくと幸せ

#### 散布図
`scatter`で描画していく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/fa12fa6d-5756-7720-ad18-16ea812d32ae.png)
特に変わったところはないな
オプションの`s`は点の大きさを指定している

#### ヒストグラム
`hist`で描画していく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/3090e9e7-cd9b-3133-f336-8f91bcf70ec4.png)
データがこれとしたら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/d1425bf3-787b-2277-768e-3d5c365d4e19.png)
`bins`はヒストグラムのビン（階級）を表してて、１階級にどれだけデータを含むかの値なんだってさ
`stacked=True`を指定すると、例で言うと男女のグラフが積み重なったヒストグラムになる

#### 箱ひげ図
ん？なにそれ？

### 応用
#### ２種のグラフを重ねて表示する
某サイトを参考にテストデータを拝借、計算方法等は今はどうでもいいのでそのまま使う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/35d72c4b-fc85-2f0b-3863-eea5b5b1b9d4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/051c60af-3eb8-e6e7-964a-26fac43e4f26.png)
新しく出てきたメソッドとかにコメント入れてみましたが、
`twinx`サブプロットさえ作ってしまえば、あとは今まで通りな感じですね！！！

## 感想
グラフだけで色々できすぎ〜　プログラムだけでここまでグラフが描けるということには驚いてる（Excelのグラフも使えこなせないのは内緒）
他にもグリッドや文字の色とか文字（タイトル、ラベル含め全般）のフォントを変えられたり、ワードクラウドみたいなのも作れるみたい
これから触るけど、Pandasとかで分析してこれらのグラフでバッと出したりするんだろうなぁ〜多分
かっこええやん、それ