コピペで使える!Bokehで時系列データの可視化をしよう!

# 概要
* Bokehによるエネルギーデータの可視化
* pandasの使い方は下記を参照するとすごく幸せになれます。
 * [データ分析で頻出のPandas基本操作](https://qiita.com/ysdyt/items/9ccca82fc5b504e7913a)
 * [StatsFragments](http://sinhrks.hatenablog.com/archive/category/pandas)
* [初心者による「Python初心者がコピペで使える!時系列データの可視化!」](https://qiita.com/snuow/items/fe58b8f5e230f5dc48a4)でのBokeh分になります。

# importライブラリ
```python:import
from bokeh.io import output_notebook, show
from bokeh.plotting import figure, output_file, show
from bokeh.layouts import column
from bokeh.models import DataSource,RangeTool,HoverTool
import bokeh.palettes as bp
output_notebook()
import pandas as pd
import numpy as np
```

# 使用データ
```python:使用データ
# データの読み込み
df = pd.read_csv(r'sample_data.csv',names=['date','pointA','pointB','pointC'],skiprows=[0],engine='python',index_col=[0],parse_dates=[0])
df.index.freq = 'H'
df.dropna().head()
```
<img src= https://qiita-image-store.s3.amazonaws.com/0/148213/d386fb31-bd8f-3fbe-ceee-cf7dd8c1b480.png width=50%>



# Bokehによるグラフ
* Bokehによる線グラフ
* bokehによる線グラフは下記のコードで実装できます。
* 適宜変数の値は変更してもらえればと思います。

```python:グラフの設定
# 適宜'pointA'などの文字列を変更してください。
pointA = 'pointA'
pointB = 'pointB'
pointC = 'pointC'

# グラフの設定
p = figure(title='タイトル',         # タイトルを入力
           x_axis_type='datetime',   # x軸が時系列のindexを持っている場合、datetimeを指定 
           x_axis_label='timestamp', # x軸のラベル
           y_axis_label='EP',        # y軸のラベル
           x_range = [df.index[0],df.index[168]], # x軸のレンジ(list型)
           y_range = [0,2000],         # y軸のレンジ（list型)
           width=800,height=350,     # グラフの幅と高さの指定
          )

#適宜追加したいグラフ分だけp.line()を追加してください。
# pointAの線グラフを追加
p.line(x=df.index,y=df.loc[:,pointA],color='red',legend=pointA)
# pointBの線グラフを追加
p.line(x=df.index,y=df.loc[:,pointB],color='blue',legend=pointB)
# pointCの線グラフを追加
p.line(x=df.index,y=df.loc[:,pointC],color='green',legend=pointC)
# pointCのマーカーを追加
p.circle(x=df.index,y=df.loc[:,pointC],color='green',fill_color='white',legend=pointC)

# rangetoolの作成
# rangetoolは、上記で追加したグラフの描画範囲をスライダーで変更することができます。
# rangetool用のグラフの設定を追加
select = figure(title="上段のグラフの表示範囲をスライダーで指定できます",
                plot_height=130, plot_width=800, y_range=p.y_range,
                x_axis_type="datetime", y_axis_type=None,
                tools="", toolbar_location=None, background_fill_color="#efefef")

# Rangetoolの設定
range_rool = RangeTool(x_range=p.x_range) # Rangetoolのx_rangeの範囲を設定（p.x_range)
range_rool.overlay.fill_color = "navy"    # overlay.fill_colorはスライダーの色を指定
range_rool.overlay.fill_alpha = 0.2       # 透明度の指定

select.line(x=df.index,y=df.loc[:,pointA])# p.lineと同様に、x軸とy軸の設定
select.ygrid.grid_line_color = None
select.add_tools(range_rool)              # range_roolを追加
select.toolbar.active_multi = range_rool

# グラフの描画
show(column(p,select))
```
![20181230.gif](https://qiita-image-store.s3.amazonaws.com/0/148213/1ed0bce9-550a-a84c-a10f-7b4d7ea8753c.gif)


* Bokehによる棒グラフ
* 1dayにリサンプリングして棒グラフにしています。

```python:1monthdata
# 1データdayの可視化(棒グラフ)
day_df = df.resample('D').sum()

# グラフの設定
p2 = figure(title='タイトル',         # タイトルを入力
           x_axis_type='datetime',   # x軸が時系列のindexを持っている場合、datetimeを指定 
           x_axis_label='timestamp', # x軸のラベル
           y_axis_label='EP',        # y軸のラベル
           width=800,height=350     # グラフの幅と高さの指定
            
          )

# caution
# bokehのx_axis_typeはmsの分解能をもっているため、barの太さを1日分にするには
# 下記のようにms → 1dayに直す必要がある。
day_width = 1000* 3600 * 20 # ms * hour * 1day(隙間をあけるために20にしています)

# pointAの棒グラフを追加
p2.vbar(x=day_df.index,top=day_df.loc[:,pointA],color='red',legend=pointA,width=day_width)
# pointBの棒グラフを追加
p2.vbar(x=day_df.index,top=day_df.loc[:,pointB],color='blue',legend=pointB,width=day_width)
# pointCの棒グラフを追加
p2.vbar(x=day_df.index,top=day_df.loc[:,pointC],color='green',legend=pointC,width=day_width)
# pointCのマーカーを追加
p2.line(x=day_df.index,y=day_df.loc[:,pointC],legend=pointC,color='black')

show(p2)

```
![bokeh_plot.png](https://qiita-image-store.s3.amazonaws.com/0/148213/e6970306-d60f-ae74-923e-b8b202301b43.png)


# まとめ
* Bokehでデータを可視化し、スライドバーを導入することで、データフレームを細かく分割せずに一気に長期間を確認することができる。
* 報告書等にまとめる際は、適宜画像を保存する必要がある。
* Bokehはすごく便利なことがわかった！今度からこれ使おう。