Python matplotlibのマニアックなメモ

# matplotlib 自分用備忘録

やろうとしてる事がニッチ過ぎて調べてもなかなか見つからない…
なんとか解決策を見つけたけどもう一度同じ事を調べる気力はない…

自分がかゆいと思った所に手が届くようになった解決策たちを記録します。

__※ コードをコピペしたらそのまま動くかどうかは保証できません。__
__※ それでもある程度matplotlibに慣れている人たちなら大丈夫だと思います。__
__※ もともと自分用に部分的にコピペできるように書こうと思ったものなのでそこらへんは許してください…__

---

## グラフの解像度とdpiを指定する

```Python
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(w/dpi, h/dpi), dpi=dpi, facecolor='white')
```

`w, h = 1920, 1080` と指定すればFHDモニター一杯のグラフが作れる


## グラフにテキストを挿入

![グラフにテキスト挿入_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271103/1f2fe784-98fd-5cc5-cbdc-d5a66dde2102.png)


```Python
# フォントサイズを変更
plt.rcParams['font.size'] = '5'

fig = plt.figure(figsize=(w/dpi, h/dpi), dpi=dpi, facecolor='white')
ax = fig.add_subplot(111)

# グラフ左上に原点左上&左寄せのテキストを表示
plt.text(0.01, 0.98,
          'left top',
          horizontalalignment='left',
          verticalalignment='top',
          size=10, # fontsize
          ha='left', va='top',
          transform=ax.transAxes, zorder=1)

# 右上
plt.text(0.99, 0.98,
          'right top',
          horizontalalignment='right',
          verticalalignment='top',
          size=10,
          ha='right', va='top',
          transform=ax.transAxes, zorder=1)

# 左下
plt.text(0.01, 0.01,
          'left bot',
          horizontalalignment='left',
          verticalalignment='bottom',
          size=10,
          ha='left', va='bottom',
          transform=ax.transAxes, zorder=1)

# 右下
plt.text(0.98, 0.01,
          'right bot',
          horizontalalignment='right',
          verticalalignment='bottom',
          size=10,
          ha='right', va='bottom',
          transform=ax.transAxes, zorder=1)

```


## グラフ部分のみを指定した解像度ぴったりで出力したい
余白も軸もラベルも全て消したい、グラフだけ出力したい(語彙力)

仕事で機械学習用の元データを作成するときに手こずったかゆい所

作りたかったのは↓こんな感じの黒背景にRGB1本ずつのグラフ
![グラフ部分のみを指定した解像度ぴったりで出力したい_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271103/e60c6f6a-416d-4e30-a69a-518580aa9b5a.png)
サイズは60px * 60px

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

w , h = 60, 60
dpi = 300
aa = True

plt.clf()
fig = plt.figure(figsize=(w/dpi, h/dpi), dpi=dpi)
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax3 = ax1.twinx()

# 全ての軸を非表示
ax = plt.gca()
plt.axis('off')
ax.axis('off')
ax1.axis('off')
ax2.axis('off')

ax1.plot(np.random.rand(60), lw=lw, color=[1.0, 0.0, 0.0], antialiased=aa)
ax2.plot(np.random.rand(60), lw=lw, color=[0.0, 1.0, 0.0], antialiased=aa)
ax3.plot(np.random.rand(60), lw=lw, color=[0.0, 0.0, 1.0], antialiased=aa)

plt.xlim([0, 59])
# 上下左右の余白を削除
plt.subplots_adjust(left=0, right=1, bottom=0, top=1)

# グラフの枠も削除
plt.box(False)

plt.savefig(pathfile, dpi=dpi, facecolor='black')

plt.clf()
plt.close(fig)
```

↓ 保存結果
![解像度ぴったりで出力したい_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271103/2df811ad-9298-aab1-dc7a-e3b1fa1115f3.png)
これなら機械学習にも使える(はず)！


## グラフ保存した時にラベルやタイトルが見切れないようにする

`w, h, dpi`を自分で指定してグラフ保存すると
x, yのラベルやタイトルが切れちゃう…
![見きれない_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271103/a9741310-c479-5884-6ffe-3a90f1de9b45.png)


そんな時はコレ

```Python
plt.savefig(pathfile, dpi=dpi, facecolor='white', bbox_inches='tight', pad_inches=0.1)  
```
`bbox_inches='tight'`と`pad_inches=0.1`が重要です


↓ 保存結果
![見きれない_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271103/2f5341fd-8fa1-cfd5-eedd-8bf19327a971.png)


`pad_inches`の値を大きくすると指定した解像度よりも大きくなるので注意してください

↓ `pad_inches`を`0.5`にした場合の保存結果
![見きれない_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271103/37cfec07-8447-deee-9a81-1cbf7f68a519.png)


## 追記予定のかゆい所  

- 折れ線グラフで指定した値より大きい or 小さい 部分の線の色を変更したい
 - 資産曲線などで損益が0円を下回る部分を赤色にしたい時とか...


この他にもあったら都度追記していきます