この資料は,fukuoka.R #9で発表した「Rでインタラクティブなプロットを作ろう」のスライドをベースに,plotlyの部分を取り出してドキュメント形式に起こしたものです。スライドバージョンはこちらにあります。

なお,スライドからほぼそのまま起こしているため,ほぼ箇条書きとなっております。またwarningおよびmesseageは出ないように抑制しています。ご了承ください。

Rでインタラクティブなプロット

Rでプロット、何を使ってますか?

  • baseのplot?
  • ggplot2?
  • lattic?
  • その他パッケージ?

いろんな選択肢があります

できればグリグリ動かしたい

  • baseのplotやggplot2は“静止画”
    • 出力したらそれで固定
    • 軸範囲やデータ系列の変更はコードに戻る必要
  • できれば出力した後で動かしたい
    • しかしplotやggplot2では難しい

HTML + CSS + JSで実現しよう!

plotly

plotlyパッケージとは

  • plotlyというインタラクティブなchartsを作るパッケージ
    • 元は同社の可視化コンテンツにアクセスするためのパッケージ(要登録)
    • 現在はオープンソース化
  • htmlwigets系で一番GitHubの★を稼いでる
  • 以下の資料がおすすめ
    • R Graphing Library | Plotly
      • 公式サイトによるドキュメント。まずはここから。
    • plotly for R
      • gitbook形式で,より深い使い方が書いてあります。ここ読めばOK

インストール

# CRANから
install.packages("plotly")
# GitHubから
devtools::install_github("ropensci/plotly")
# githubinstallを使うなら
githubinstall::githubinstall("plotly")

Hello, plotly!

library(plotly)
library(magrittr)
plot_ly(iris, x = ~Sepal.Length, y = ~Sepal.Width, color = ~Species, type = "scatter")

plot_ly(iris, x = ~Species, y = ~Sepal.Length, type = "box")

特徴

  • 簡単にインタラクティブなplotが作れる
    • デフォルトでいい感じにしてくれる
  • 3Dや地図、ガントチャートも対応
    • D3.jsベースでかなり幅広い
  • プロット記述 %>% レイアウト設定記述
    • pipe演算子で送ると楽
  • type(グラフの種類)が重要
    • これによって指定できるオプションが変わってくる
    • ggplot2みたいに多様なgeomを使い分けるのではない
    • 系統的に分かれていく(後述)
      • 例えばpointとbubbleとlineはすべてtype = scatterから分岐

plotlyの基本(データ・タイプ)

キャンパス

p_empty <- plot_ly()
p_empty
  • 引数を与えないと,キャンパスのみ生成
  • 軸はとりあえず描かれているだけ
  • ここから要素を追加していきます

データ

plot_ly(data = iris)
  • 描写する際に使用するデータセット(data.frame)を指定しています
  • ただデータセットを指定しただけなので,特に何が描かれているわけではないです

x軸の指定

plot_ly(data = iris, 
        x = ~Sepal.Length,
        y = ~Sepal.Width)
  • 軸に割り当てる変数を指定すると描写
  • 変数を指定する場合,変数名の前に~が必要
  • x,yに割り当てられているデータから,自動的にscatterプロットが選択

グラフのタイプを指定

plot_ly(data = iris, 
        x = ~Species,
        y = ~Sepal.Length,
        type = "box")
  • 引数typeでグラフのタイプを指定
    • bar: 棒グラフ
    • box: 箱ひげ図
    • scatter: 散布図
    • pie: 円グラフ
    • sankey: sankey diagram
      etc…

データ系列の指定(split)

plot_ly(data = iris,
        x = ~Sepal.Length,
        y = ~Sepal.Width,
        split = ~Species,
        type = "scatter")
  • いわゆるggplot2のgroupみたいなもの
  • splitで指定した変数で系列を分割
    • 離散変数で使ってください

データ系列の指定(color)

plot_ly(data = iris,
        x = ~Sepal.Length,
        y = ~Sepal.Width,
        color  = ~Petal.Length,
        type = "scatter")
  • いわゆるggplot2のcolorみたいなもの
  • colorで指定した変数で色分け
    • 連続でも離散でもOK

plotlyの基本(軸・凡例・タイトルなど)

軸や凡例

  • こういったプロパティ項目は追加設定
    • plotlyのオブジェクトを作成
    • それにlayout関数をかける
  • 以下に設定を追加していきます:

軸周りの設定

plot_ly(data = iris,
        x = ~Sepal.Length,
        y = ~Sepal.Width,
        split = ~Species,
        type = "scatter") %>% 
  layout(xaxis = list(
    showgrid = F,
    rangemode = "tozero",
    nticks = 6,
    title = "ほげ"
  ))
  • xaxis引数に設定したい内容をlist型で
  • Y軸に設定したい場合はyaxis引数へ
  • たくさんあるので詳しくは公式サイトのreference

凡例(legend)の設定

plot_ly(data = iris,
        x = ~Sepal.Length,
        y = ~Sepal.Width,
        split = ~Species,
        type = "scatter") %>% 
  layout(legend = list(
    orientation = "h",
    yanchor = "bottom"
  ))

タイトルなど

plot_ly(data = iris,
        x = ~Sepal.Length,
        y = ~Sepal.Width,
        color = ~Species,
        type = "scatter") %>% 
  layout(title = "たいとる",
         paper_bgcolor = "#aaf",
         plot_bgcolor = "#66d",
         showlegend = FALSE)

plotlyの基本
(重ね書き・複数プロット)

重ね書き

df <- data.frame(
  x = c(1:50),
  y1 = rnorm(50, mean = 5),
  y2 = rnorm(50, mean = 0)
)
plot_ly(df, x = ~x, y = ~y1,
        name = "kosaki",
        type = "scatter", mode = "lines+marker") %>% 
  add_trace(y = ~y2,
            name = "chitoge",
            mode = "markers")
  • add_trace関数で新たに描写オブジェクトを追加
    • ggplot2でgeom重ね書きに近い
    • dataやaes的なのは継承可

複数プロット(個別で作成)

p1 <- plot_ly(df, x = ~x, y = ~y1,
              type = "scatter",
              mode = "markers")
p2 <- plot_ly(df, x = ~x, y = ~y2,
              type = "scatter",
              mode = "lines")
subplot(p1, p2, nrows = 2)
  • subplotで束ねることが可能
    • nrows引数で行数を指定
    • その後pipeでlayoutを繋げば、全体でのlayout設定が可能

複数プロット(条件別で)

df_tidy <- df %>%  
  tidyr::gather(var, value, -x)
plot_ly(df_tidy,
        x = ~x, y = ~value,
        color = ~var,
        yaxis = ~var) %>% 
  add_lines() %>% 
  subplot(nrows = 2)
  • plot_lyyaxisでY軸のIDを準備
    • あとはggplot2のfacetみたいに自動でやってくれる

ggplot2 to plotly

ggplotlyがある

library(ggplot2)
gg <- ggplot(df_tidy, aes(x, value, group = var)) +
  geom_point(aes(color = var))
ggplotly(gg)
  • なんとggploly関数で一発変換
    • かなりマニアックなものをしてなければすんなりOK
    • どれが効かないかは把握しきれてないです…

facetもOK

gg_facet <- ggplot(df_tidy,
                   aes(x, value, group = var)) +
  geom_point(aes(color = var)) +
  facet_wrap(~var, nrow = 2)
ggplotly(gg_facet)
  • facetされていてもちゃんと出します
    • ただし、plotlyのオブジェクトとしては分かれていない
    • この点には注意

plotlyの出力方法

R Markdown, Shiny

  • そのままでOK
  • この資料でもそのまま出しています
  • CSSで調整も可能
    • classは.plotly
    • idはハッシュ値

htmlファイル

  • htmlファイルとして可能
    • いわゆるウィジットとして使える
    • あとはiframeとかで埋め込めばOK
  • RStudioのViewerから[Export]-[Save As a html…]
  • もしくはhtmlwidgets::saveWidget

静止画像で

  • 静的な出力も可能
    • plotly::exportを使う
    • RStudioのViewerに出して、[Export]のメニューから
  • もちろん「ただの画像」として出す
    • 正直あんまり意味ない…

ギャラリー(短縮版)

bar chart

Animals <- c("giraffes", "orangutans", "monkeys")
SF_Zoo <- c(20, 14, 23)
LA_Zoo <- c(12, 18, 29)
data <- data.frame(Animals, SF_Zoo, LA_Zoo)

plot_ly(data, x = ~Animals, y = ~SF_Zoo, type = 'bar', name = 'SF Zoo') %>%
  add_trace(y = ~LA_Zoo, name = 'LA Zoo') %>%
  layout(yaxis = list(title = 'Count'), barmode = 'stack')

box plot

plot_ly(y = ~rnorm(50), type = "box") %>%
  add_trace(y = ~rnorm(50, 1))

heatmap

plot_ly(z = volcano, type = "heatmap")

3D surface plot

plot_ly(z = ~volcano) %>% add_surface()

さいごに

使いドコロは?

  • htmlベースなドキュメントに埋め込む
    • インタラクティブなので、インパクトが大きい
  • ダッシュボードに最適
  • Shinyでアプリ
    • htmlwidgetsはShinyでこそ効果を発揮

留意事項

  • データがドキュメントに保持される
    • scriptタグ内に(だいたい)json形式で埋め込まれる
      • 公開する際は注意
  • データ量が多いと重くなる
    • ブラウザ&マシンに依存する
    • クライアント側で処理するため