完全俺用、matplotlibチートシート

# 注意
* **個人用です**
* 解説はほぼしません。チートシートです
* 私の環境で”出来る”（最善とは限らない）だけなので、ご注意ください。
* 困ったことがあったら都度追記します

# 環境
* OS：Mac Mojave 10.14.5
* python：3.7.4
* matplotlib：3.1.1


# フォント変えたい（日本語にしたい）

## フォント一覧を取得
```python
import matplotlib.font_manager
[f.name for f in matplotlib.font_manager.fontManager.ttflist]
```

## フォント変更
上で出てきたやつから使いたいやつを選んでください。

``` python
# Macだったらヒラギノ使える
# hiragino sansであれば太文字などにもできる
plt.rcParams['font.family'] = 'Hiragino Sans'  
```


### この状態で使うと
```python
x = [i for i in range(10)]
y = [i**2 for i in range(10)]
y2 = [(i-9)**2 for i in range(10)]
plt.plot(x,y,label="放物線の右側")
plt.legend(fontsize=14)
plt.show()
```

![test1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/b918c53c-fac1-1ba4-60bc-59bebe249213.png)

# 右軸も使いたい

## 基本

```python
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()  

ax1.bar(x,y)
ax2.bar(x,y2,color="darkorange")
```

![test2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/975c209a-5ec6-8d26-9a0e-00fd7d0e78a7.png)

この場合は右軸（オレンジ）が左軸（青）より上のレイヤーになっている。

## 左軸を上にしたい

```python
fig, ax1 = plt.subplots()  
ax2 = ax1.twinx()  

ax1.set_zorder(ax2.get_zorder()+1)
ax1.patch.set_visible(False)  


ax1.bar(x,y)
ax2.bar(x,y2,color="darkorange")
```

![test3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/dd71a7c9-d660-e1a1-10be-e875c78a8c8b.png)

左軸（青）の方が上になる。


## 左右軸両グラフの凡例をつけたい

```python
fig, ax1 = plt.subplots() 
# 右軸描画が左軸描画より上になるので注意  
ax2 = ax1.twinx()  

P1 = ax1.bar(x,y)
P2 = ax2.bar(x,y2,color="darkorange")
labels = ["Left Axis", "Right Axis"]
plt.legend([P1,P2],
           labels,
           loc="upper center"
          )
plt.show()
```
![test4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/b0682c02-9973-a25a-624a-76f579783ea7.png)


* 凡例のポジションは以下を参考
* https://qiita.com/matsui-k20xx/items/291400ed56a39ed63462

棒グラフの時はこれで良かったが、折れ線の場合は以下のように修正が必要[^3]。

```python
x = [0,1,2,3]
y = [0,1,2,3]
y2 = [3,2,1,0]
fig, ax1 = plt.subplots() 
# 右軸描画が左軸描画より上になるので注意  
ax2 = ax1.twinx()  

#[0]が必要
P1 = ax1.plot(x,y)[0]
P2 = ax2.plot(x,y2,color="darkorange")[0]
labels = ["Left Axis", "Right Axis"]
plt.legend([P1,P2],
           labels,
           loc="upper center"
          )
plt.show()
```
![qiita_legend.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/e99a140c-eaf1-1984-3121-f7f9147e1dce.png)



# 日付軸を見やすくしたい
![test5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/522fa237-7925-03c3-3667-04b1b0650d8e.png)

これをなんとかしたい。

## ○○○Locatorを使って目盛りの間隔を制御

```python
import matplotlib.dates as mdates
# graph data 
#x3 = [datetime.datetime(2019,1,1,0,0) + relativedelta(hours=i) for i in range(1000)]
#y3 = [i**2/1000 for i in range(1000)]

fig, ax1 = plt.subplots() 
ax1.plot(x3,y3,label="放物線の右側")

xfmt = mdates.DateFormatter("%Y-%m-%d")

# DayLocatorで間隔を日数に
xloc = mdates.DayLocator(interval=10)
ax1.xaxis.set_major_locator(xloc)
ax1.xaxis.set_major_formatter(xfmt)

plt.legend(fontsize=14)
plt.show()
```
![test6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/a318ef45-b364-35f0-54f7-f3405a985a08.png)

公式Document[^1]によると、DayLocatorも含めて
* DayLocator
* HourLocator
* MinuteLocator
* MonthLocator
* SecondLocator
* WeekdayLocator

があるよう。

### bymonthdayで目盛りで表示する曜日を指定

```python
from matplotlib.dates import MO, TU, WE, TH, FR, SA, SU
xloc = mdates.WeekdayLocator(byweekday=MO)
```

とすれば月曜日を目盛りとしてくれる




## （一応）DateFormatterを使って表示を変更
上でもちょっと使っていましたが

```python
# graph data 
#x3 = [datetime.datetime(2019,1,1,0,0) + relativedelta(hours=i) for i in range(1000)]
#y3 = [i**2/1000 for i in range(1000)]

fig, ax1 = plt.subplots() 
ax1.plot(x3,y3,label="放物線の右側")

# DataFormatterで表示を変更
xfmt = mdates.DateFormatter("%y-%m-%d")
ax1.xaxis.set_major_formatter(xfmt)

plt.legend(fontsize=14)
plt.show()
```

![test7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/3af707a5-ae2c-72f2-2d2c-b3305c565e56.png)

　
%Yと%yの違いなどは公式doc[^2]を参照。

等間隔でないと少し違和感がありますね。
DateLocatorも使いましょう。

#x軸と平行、垂直な線を引く

## x軸と平行
```python
import matplotlib.dates as mdates

# graph data
#x3 = [datetime.datetime(2019,1,1,0,0) + relativedelta(hours=i) for i in range(1000)]
#y3 = [i**2/1000 for i in range(1000)]
fig, ax1 = plt.subplots() 
ax1.plot(x3,y3,label="放物線の右側")
xfmt = mdates.DateFormatter("%y-%m-%d")
xloc = mdates.DayLocator(interval=10)
ax1.xaxis.set_major_locator(xloc)
ax1.xaxis.set_major_formatter(xfmt)
xloc_minor = mdates.DayLocator(interval=5)
ax1.xaxis.set_minor_locator(xloc_minor)

#ここ
plt.hlines(y=500,xmin=x3[0],xmax=x3[-1],linestyles='dashed')
plt.legend(fontsize=14)
plt.show()
```

![test8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196857/115ce07a-fa31-2b90-989d-6da4e67aa1ae.png)

* x軸と垂直は plt.vlines(x=..., ymin=..., ymax=...) にすれば良い





[^1]: https://matplotlib.org/3.1.1/api/dates_api.html
[^2]: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
[^3]: https://riptutorial.com/matplotlib/example/10473/single-legend-shared-across-multiple-subplots