matplotlib入門

独特のお作法があって初心者が引っかかりがちなmatplotlibの入門記事です

## 試行環境
windows10
jupyter notebook

## 使うデータ
なんでも良いですが、iris使っときます

```python:python
import pandas as pd
from sklearn.datasets import load_iris

iris = load_iris()
data = pd.DataFrame(iris.data, columns=iris.feature_names)
data.head()
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/acc871a9-9901-048b-e717-960289b94857.png)

## 1. グラフいろいろ
基本的に全部matplotlib.pyplotを使います。また、jupyter notebookで表示する為に%matplotlib inlineとしておきます。（最近は%matplotlib inlineしなくても2回目以降表示されるようになったようですが一応やっときます）

```python:python
import matplotlib.pyplot as plt
%matplotlib inline
```
グラフを描くだけなら1行で書けます

```python:python
plt.hist(data['sepal length (cm)'], bins=10) # ヒストグラム
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/c9433f47-a304-b65d-f124-05cc52245981.png" width=50%>

```python:python
plt.plot(data['sepal length (cm)'])
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/1c285761-8fa5-ec00-bf06-9b8183bda849.png" width=50%>

```python:python
plt.scatter(data['sepal length (cm)'], data['sepal width (cm)'])
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/d75a6a38-f619-3f6e-239f-5bfb88309673.png" width=50%>

```python:python
import numpy as np
tmp = data['sepal length (cm)'].head(20)
plt.bar(np.arange(len(tmp)), tmp)
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/d064df3e-b1a3-c961-39c4-f659219a9496.png" width=50%>

## 2. グラフを整える
最初にmatplotlibのお作法を確認しておきましょう。matplotlib.pyplotは最初に呼ばれた時にpyplotオブジェクトを作ります。以降は作られたオブジェクトに変更が加わっていきます。さっきまでの書き方だとplt.scatter()で作ったpyplotオブジェクトがそのまま表示していましたが、表示する前に同じオブジェクトに変更指示を与えれば形や軸ラベルなどを変更できます。

```python:python
plt.figure(figsize=(4, 4), dpi=80)  # 縦横サイズと解像度を指定
plt.plot(data['sepal length (cm)']) # プロットする
plt.title('title')                  # タイトル
plt.xlabel('sepal length (cm)')     # Ｘラベル
plt.ylabel('value')                 # Ｙラベル
plt.xlim(0, 150)                    # Ｘ軸の範囲
plt.ylim(0, 10)                     # Ｙ軸の範囲
plt.xticks(np.arange(0,151,25))     # Ｘ軸目盛りを指定
plt.yticks(np.arange(0,11,2))       # Ｙ軸目盛りを指定
plt.legend(loc='upper right')       # 凡例を表示
plt.show()                          # グラフを表示
```
![ダウンロード (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/d1f3e3e5-7228-f06a-d0e8-f6855557d26d.png)

## 3. グラフの重ね書き
同じpyplotオブジェクトに続けてプロットすれば重ねてプロットすることができます。プロットする度にパレットの色を順番に適用してくれるのでいちいち色を指定しなくてもそれっぽく表示してくれます。

```python:python
plt.figure(figsize=(4, 4), dpi=80)
plt.plot(data['sepal length (cm)']) # プロットする
plt.plot(data['sepal width (cm)']) # プロットする
plt.title('title')
plt.xlabel('sepal length (cm)')
plt.ylabel('value')
plt.xlim(0, 150)
plt.ylim(0, 10)
plt.xticks(np.arange(0,151,25))
plt.yticks(np.arange(0,11,2))
plt.legend(loc='upper right')
plt.show()
```
![ダウンロード (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/2a6c5469-777a-653b-5ea6-c56c0268e358.png)

## 4. グラフを複数まとめて表示する
plt.subplot()でsubplotオブジェクトをつくって、そこにプロットを書いていけば複数プロットをまとめて表示できます。plt.subplot(231)だと縦に2個、横に3個で配置する内の1番目のsubplotオブジェクトを作ります。

```python:python
plt.figure(figsize=(4, 6), dpi=80)  # 縦横サイズと解像度を指定
plt.subplots_adjust(wspace=0.4, hspace=0.45)

ax = plt.subplot(211)               # サブプロットの１個目
ax.plot(data['sepal length (cm)'])
ax.set_title('title')
ax.set_xlabel('sepal length (cm)')
ax.set_ylabel('value')        
ax.set_xlim(0, 150)               
ax.set_ylim(0, 10)                
ax.set_xticks(np.arange(0,151,25))
ax.set_yticks(np.arange(0,11,2))
ax.legend(loc='upper right')      

ax = plt.subplot(212)               # サブプロットの２個目
ax.plot(data['sepal width (cm)'])
ax.set_title('title')
ax.set_xlabel('sepal length (cm)')
ax.set_ylabel('value')
ax.set_xlim(0, 150)
ax.set_ylim(0, 10)
ax.set_xticks(np.arange(0,151,25))
ax.set_yticks(np.arange(0,11,2))
ax.legend(loc='upper right')

plt.show()  # グラフを表示
```
![ダウンロード (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/8580fde3-0b06-ed9b-3393-7fbe46dab3bd.png)
ちなみにsubplotオブジェクトは維持してなくても良いので以下のような書き方もできます。

```python:python
plt.figure(figsize=(8, 8), dpi=80)
plt.subplots_adjust(wspace=0.3, hspace=0.35)

for k, each in enumerate(data.columns):
    ax = plt.subplot(221+k)
    ax.plot(data[each])
    ax.set_title(str(k+1))
    ax.set_xlabel(each)
    ax.set_ylabel('value')
    ax.set_xlim(0, 150)
    ax.set_ylim(0, 10)
    ax.set_xticks(np.arange(0,151,25))
    ax.set_yticks(np.arange(0,11,2))
    ax.legend(loc='upper right')

plt.show() 
```
![ダウンロード (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/355cb86c-2a5e-fc8e-5ec6-9ab8e836a6b5.png)
論文で見るようなプロットも簡単に作れますね。

## 5. スタイルを使う
styleを適用してデザインをまとめて変更できます

```python:python
plt.style.use('ggplot')
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/ed3a54b0-6588-74a3-6d7c-178eb89da867.png" width=50%>

```python:python
plt.style.use('fivethirtyeight')
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/20b461f7-41a9-bdb0-c5ae-3bb75d5e46b6.png" width=50%>

```python:python
plt.style.use('grayscale')
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/45e0bbcf-3eee-b35d-39fe-dbe467f3bcaa.png" width=50%>

## 6. 日本語表示を出来るようにする
matplotlibは標準だと日本語表示が出来ませんので日本語を使おうとすると豆腐だらけになります
![ダウンロード (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/057a9e80-54bb-607e-4a6e-e3d75980b7a0.png)
日本語表示が出来るようにする方法は色々ありますが、一番簡単なのはjapanize_matplotlibを使うことです。このpackageは内部に日本語フォントをもっていて呼ばれた時にfontを指定してくれます。ただし、plt.style.use()を使うとfontを指定し直してしまいますのでjapanize_matplotlibを呼ぶのはplt.style.use()より後にします。

```python:python
import japanize_matplotlib
```
詳しくはこちらを参照
https://qiita.com/uehara1414/items/6286590d2e1ffbf68f6c

## 7. 画像を保存する
plt.show()する前にplt.savefig()で保存できます。以下だとcodeのあるフォルダにtest.pngとして書き出します。標準だとtitleやlabelが出力されない事があるのでbbox_inches='tight'で描画範囲に合わせて書き出されるようにします。

```python:python
plt.savefig('./test.png', dpi=150, bbox_inches='tight')
```



## もっと詳しく知りたい人は

公式ドキュメント
https://matplotlib.org/gallery/index.html

legendについてはここが詳しいです
http://pynote.hatenablog.com/entry/matplotlib-legend

styleについてはこの辺
https://matplotlib.org/3.1.0/gallery/style_sheets/style_sheets_reference.html
https://qiita.com/eriksoon/items/b93030ba4dc686ecfbba