[Python]bokehのグラフをmatplotlibと同じ色で描画(bokeh.palettes)

自分はPythonでのグラフ描画に，インタラクティプなグラフの保存ができ，ストリーミングデータも扱える[bokeh](https://docs.bokeh.org/en/latest/index.html)を利用しています．今回はbokehでmatplotlibのデフォルトのラインカラー(に似た色)を使えるようにします．


```python
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import numpy as np
```


```python
import bokeh.plotting
from bokeh.io import output_notebook, show
output_notebook()
from bokeh.palettes import d3
```

まず，可視化するデータとして[こちら](https://www.dropbox.com/s/wljforxbz0rqdqq/naive_multi_10.csv?dl=1)の株価データを利用します．このデータは日経平均採用銘柄から選んだ10銘柄の2020年11月4日から2020年11月30日までの分足の始値です．


```python
df = pd.read_csv("naive_multi_10.csv")
df
```

<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>1803</th>
      <th>2802</th>
      <th>2503</th>
      <th>3402</th>
      <th>4502</th>
      <th>7013</th>
      <th>6702</th>
      <th>7203</th>
      <th>7733</th>
      <th>8001</th>
    </tr>
    <tr>
      <th>timestamp</th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>2020-11-04 09:06:00</th>
      <td>742.0</td>
      <td>2191.0</td>
      <td>1957.5</td>
      <td>498.200012</td>
      <td>3329.0</td>
      <td>1334.0</td>
      <td>12575.0</td>
      <td>7019.0</td>
      <td>2018.0</td>
      <td>2576.5</td>
    </tr>
    <tr>
      <th>2020-11-04 09:07:00</th>
      <td>744.0</td>
      <td>2189.0</td>
      <td>1957.5</td>
      <td>501.700012</td>
      <td>3332.0</td>
      <td>1335.0</td>
      <td>12595.0</td>
      <td>7020.0</td>
      <td>2023.5</td>
      <td>2579.5</td>
    </tr>
    <tr>
      <th>2020-11-04 09:08:00</th>
      <td>744.0</td>
      <td>2195.5</td>
      <td>1958.5</td>
      <td>502.600006</td>
      <td>3332.0</td>
      <td>1336.0</td>
      <td>12575.0</td>
      <td>7019.0</td>
      <td>2027.5</td>
      <td>2581.5</td>
    </tr>
    <tr>
      <th>2020-11-04 09:09:00</th>
      <td>745.0</td>
      <td>2193.0</td>
      <td>1957.5</td>
      <td>505.100006</td>
      <td>3332.0</td>
      <td>1342.0</td>
      <td>12575.0</td>
      <td>7019.0</td>
      <td>2030.0</td>
      <td>2583.0</td>
    </tr>
    <tr>
      <th>2020-11-04 09:10:00</th>
      <td>746.0</td>
      <td>2194.0</td>
      <td>1956.5</td>
      <td>504.700012</td>
      <td>3339.0</td>
      <td>1340.0</td>
      <td>12590.0</td>
      <td>7020.0</td>
      <td>2026.5</td>
      <td>2584.5</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>2020-11-30 14:55:00</th>
      <td>793.0</td>
      <td>2186.0</td>
      <td>2278.0</td>
      <td>576.799988</td>
      <td>3731.0</td>
      <td>1553.0</td>
      <td>14450.0</td>
      <td>7033.0</td>
      <td>2263.0</td>
      <td>2806.0</td>
    </tr>
    <tr>
      <th>2020-11-30 14:56:00</th>
      <td>794.0</td>
      <td>2180.0</td>
      <td>2274.0</td>
      <td>576.799988</td>
      <td>3735.0</td>
      <td>1554.0</td>
      <td>14435.0</td>
      <td>7034.0</td>
      <td>2262.0</td>
      <td>2809.5</td>
    </tr>
    <tr>
      <th>2020-11-30 14:57:00</th>
      <td>794.0</td>
      <td>2181.5</td>
      <td>2276.5</td>
      <td>576.799988</td>
      <td>3738.0</td>
      <td>1555.0</td>
      <td>14455.0</td>
      <td>7035.0</td>
      <td>2262.5</td>
      <td>2809.0</td>
    </tr>
    <tr>
      <th>2020-11-30 14:58:00</th>
      <td>794.0</td>
      <td>2181.5</td>
      <td>2274.5</td>
      <td>577.200012</td>
      <td>3735.0</td>
      <td>1556.0</td>
      <td>14460.0</td>
      <td>7033.0</td>
      <td>2263.5</td>
      <td>2808.5</td>
    </tr>
    <tr>
      <th>2020-11-30 14:59:00</th>
      <td>793.0</td>
      <td>2174.5</td>
      <td>2269.5</td>
      <td>575.799988</td>
      <td>3728.0</td>
      <td>1553.0</td>
      <td>14465.0</td>
      <td>7019.0</td>
      <td>2257.0</td>
      <td>2803.0</td>
    </tr>
  </tbody>
</table>
<p>4390 rows × 10 columns</p>
</div>


## matplotlibで描画

シンプルにmatplotlibで描画します．matplotlibは`ax.plot`を呼ぶたびに自動で色が割り当てられます．明示したい場合は`color`を`"C0"`，`"C1"`のように指定します．

```python
fig, ax = plt.subplots(figsize=(20,10))

for column_name in df.columns:
    x = np.arange(0,len(df.index))
    y = df.loc[:,column_name] / df.loc[df.index[0],column_name]
    ax.plot(x, y, label=column_name)

ax.legend()
```

<img src="https://dl.dropboxusercontent.com/s/lic9mi9rthvf6gw/output_8_1.png">

## bokehで描画

ここからが本題です．`bokeh.palettes`から`d3`をインポートします．`d3`はカラコードのリストからなる辞書であり，`"Category10"`や`"Category20"`などが利用できます．詳しくは[こちら](https://docs.bokeh.org/en/latest/docs/reference/palettes.html)にあります．そのうち`"Category10"`が最もmatolotlibのデフォルトのラインカラーに近いため，これを利用します．

```python
colors = d3["Category10"][10]

p = bokeh.plotting.figure(plot_width=1200,plot_height=600)

for i, column_name in enumerate(df.columns):
    x = np.arange(0,len(df.index))
    y = df.loc[:,column_name] / df.loc[df.index[0],column_name]
    p.line(x=x, y=y, line_color=colors[i], legend_label=column_name)
    
show(p)
```

<img src="https://dl.dropboxusercontent.com/s/rzkoultgozfjr8k/bokeh_plot%20%281%29.png?dl=0">


## まとめ
- `bokeh.palettes.d3`の`"Category10"`のカラーコードのリストを利用することで，matplotlibのデフォルトのラインカラーを再現しました．