インタラクティブな可視化ができるrbokehを触ってみる

先日pythonの可視化ライブラリの１つであるbokehのR版であるrbokehを触る機会があったのでまとめてみました。

触った感じはggplotのように<b>レイヤーを重ねて</b>いく感じで可視化をできるし、hoverで表示するデータの設定などがplotlyなどよりも簡単だと感じたので、結構良かったです。しかし、Rのインタラクティブな可視化では依然、plotlyやggplotlyが主流ですし、今後rbokehがとって変わるまでは感じませんでしたし、ググった時のヒットするページなんかもみてもあまり需要はなさそうです。
自分もこれから、たくさん使用していくかは微妙ですが、選択肢の一つとして使えることに越したことはナイト思うので、基本的ななエッセンスの部分をこの記事にまとめてまた触るたびに見返したいと思います。

# 準備

```{r}
# install.packages("rbokeh")
library(tidyverse)
library(rbokeh)
library(gapminder)
data(gapminder)

gapminder_07 = filter(gapminder, year == max(year)) #2007年データ
gapminder_asia = filter(gapminder, continent == "Asia") #アジア諸国データ
gapminder_asia_07 = filter(gapminder_asia, year == max(year)) # 2007年に限定したアジア諸国データ
```

# 基本的な可視化

基本的な構文はggplotでの可視化にかなり近いです。

```{r}
## ggplot
ggplot() +
  geom_...(aes(data, x, y))

## rbokeh
figure() %>%
  ly_...(data, x, y)
```

上のように、rbokehでは可視化を始める際に一番上に、`figure()`として始めたり、`%>%`で繋いでいったりと違う点も多いですが、基本的にはggplotで可視化ができる人はすぐに慣れると思います。

## ly_lines(): 折れ線グラフ

```{r}
figure(legend_location = NULL) %>% 
  ly_lines(data = gapminder_asia,
           x = year, y = pop, color = country)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/e5468f06-3b99-ef51-ad3c-1d853294c6a4.png)

これはアジア諸国の人口の推移をプロットしています。上でも述べていますが、基本的には同じです。`plotly`などと違って凡例の表記がプロットの中に表示されてしまうため、`legend_location=NULL`と明記し、凡例の表示を便宜的にオフにしました。

## ly_points(): 散布図

```{r}
figure(legend_location = "bottom_right") %>% 
  ly_points(x = gdpPercap, y = lifeExp, color = continent,
            data = gapminder_07,
            hover = c(country, gdpPercap, lifeExp))
```

![Screen Recording 2019-05-10 at 03.27 PM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/3778b76c-9c71-8b8c-b9e7-ef7b49d511ce.gif)

## ly_abline(): 回帰直線の描画

```{r}
figure() %>% 
  ly_points(x = gdpPercap, y = lifeExp,
            data = gapminder_07) %>% 
  ly_abline(lm(data = filter(gapminder, year == 2007), lifeExp ~ gdpPercap))
```

![bokeh_plot (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/37960895-1829-9a90-31ef-f3b0ec7135ec.png)

散布図内に回帰直線を描画したい場合には、少し厄介ですが、`ly_abline()`の中で`lm()`で回帰式を定義することが必要です。

## 線グラフと散布図を重ねる

```{r}
figure(legend_location = NULL) %>% 
  ly_lines(data = gapminder_asia,
           x = year, y = pop, color = country,
           hover = c(year, pop)) %>% 
  ly_points(data = gapminder_asia,
           x = year, y = pop, color = country, fill_color = "white",
           hover = c(year, pop))
```

![Screen Recording 2019-05-10 at 03.30 PM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/e8bd3c5b-a6f8-5b95-6fb6-c6a8cf663671.gif)

このように、`ly_lines()`と`ly_points()`レイヤーごとに重ねることによって折れ線グラフと散布図を重ねて表示させることも可能です。そして`fill_color`を指定することにより、点ごとの枠組みのみを残して、空洞にし、見え方を変更させるオプションもあります。

## hoverに関して

`hover`は指定の仕方が数パターンあります。使いこなすことによってグラフの説明力をあげることができるし、見栄えもよくなるのでまとめて見ました。例に用いるのは一つ上で表示した散布図グラフです。

ちなみに何も指定しない場合には、マウスホバーしてもデータは表示されません。

一番シンプルなのはベクトルで指定してあげること。
`hover = c(要素1, 要素2)`のような感じで指定すると以下のようにいい感じになります。

```{r}
figure(legend_location = NULL) %>% 
  ly_points(x = gdpPercap, y = lifeExp, color = country,
            data = gapminder_07,
            hover = c(country, gdpPercap, lifeExp))
```

![Screen Recording 2019-05-10 at 03.35 PM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/ce96986d-ff1e-8245-e058-c978c063e0b5.gif)


ですがこれよりもより詳細に指定することが可能です。例にあげると、現在は表示されるデータがカラム名のまま`gdpPercap: XXX`のように表示されていますが、これを`GDP Per Capita: XXX`のように表示される文字などを指定したい場合には`hover = "GDP Per Capita: @gdpPercap"`のように記述することで自由にできます。`""`ダブルクオテーションでくくり、データとして出力したい部分の前に`@`をおきます。

さらにhtml形式でも書くことができ、文字を太字ににしたいときは`<b>文字</b>`などでくくることができます。

`<b>@country</b><br><b>GDP Per Capita</b>: @gdpPercap<br><b>Life Expectancy</b>: @lifeExp"`

上記のように記述すると下記のように表示させることが可能です。


```{r}
figure(legend_location = NULL) %>% 
  ly_points(x = gdpPercap, y = lifeExp, color = country,
            data = gapminder_07,
            hover = "<b>@country</b><br><b>GDP Per Capita</b>: @gdpPercap<br><b>Life Expectancy</b>: @lifeExp")
```

![Screen Recording 2019-05-10 at 03.37 PM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/51b33398-3608-de8f-754e-213de60009b3.gif)


## ly_bar(): 棒グラフ

```{r}
gather_iris = iris %>% 
  group_by(Species) %>% 
  summarise(
    ave_Sepal.Length = mean(Sepal.Length),
    ave_Sepal.Width = mean(Sepal.Width),
    ave_Petal.Length = mean(Petal.Length),
    ave_Petal.Width = mean(Petal.Width)) %>% 
  gather(key, values, -Species)
figure(legend_location = "top_left") %>% 
  ly_bar(data = gather_iris, x = Species, y = values,
         color = key, position = "dodge")
```

![bokeh_plot (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/945aa60c-901a-a0d6-23cb-72b239b8a365.png)

こちらはIrisデータを用いた可視化事例です。棒グラフも、ggplotのように`position`で思うように表示の仕方を変更することが可能みたいです。他にも`fill`やなども使用可能です。


## figure内プロット情報の修正

```{r}
figure(legend_location = NULL,
       title = "Transition of Population of Asian countries from 1950 to 2007",
       theme = bk_ggplot_theme(),
       xlab = "Year", ylab = "Population") %>% 
  ly_lines(data = gapminder_asia,
           x = year, y = pop, color = country)
```

![bokeh_plot (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/a1aeaf02-c881-7de1-5a6d-ee5bc36e19a1.png)

最後に、プロットする際の、軸名やメインタイトルの指定方法です。基本的には、`figure()`内で指定します。`title`, `x/ylab`, `x/ylim`, `legend_location`などが指定可能です。

上のプロットでは`theme = bk_ggplot_theme()`を指定することでggplotっぽい見栄えにしてみました。


# まとめ

書き方やレイヤーごとにプロットを重ねていくところなどはggplotに似ていますが、ほぼ必ず`%>%`オペレータを用いるところなどは、なかなかR始めたての人にはおすすめできなさそうです。

それと、最初にも述べていますが現在はplotlyなどがインタラクティブな可視化では主流のためそれほど、自分にとっても使用頻度は低いままだと思いますが、なんかの機会に使うことがあればまたこの記事を見返したいと思います。

# 参考文献

+ [R Interface to Bokeh](https://hafen.github.io/rbokeh/#hover)