第 10 章 交互式网页图形

echarts4r 包基于 Apache ECharts (incubating),ECharts 的 Python 接口 pyecharts 也非常受欢迎,基于 apexcharts.jsapexcharter

billboarder

dygraphs 包基于 dygraphs 可视化库,将时序数据可视化,更多情况见 https://dygraphs.com/

leaflet 提供 leaflet 的 R 接口

timevis 创建交互式的时间线的时序可视化,它基于 Visvis-timeline 模块,支持 shiny 集成。

ECharts2Shiny 包也是将 ECharts 嵌入 shiny 框架中。

对于想了解 htmlwidgets 框架,JavaScript 响应式编程的读者,推荐 John Coene 新书 JavaScript for R

学习 plotlyhighcharter 为代表的 基于 JavaScript 的 R 包,共有四重境界:第一重是照着帮助文档的示例,示例有啥我们做啥;第二重是明白帮助文档中 R 函数和 JavaScript 函数的对应关系,能力达到 JS 库的功能边界;第三重是深度自定义一些扩展性的 JS 功能,放飞自我;第四重是重新造轮子,为所欲为。下面的介绍希望能帮助读者到达第二重境界。

plotly 是一个功能非常强大的绘制交互式图形的 R 包,支持图片下载、背景图片22、工具栏23和注释24 等一系列细节的自定义控制。下面结合 JavaScript 库 plotly.js 一起介绍,帮助文档 ?config 没有太详细地介绍,所以我们看看 config() 函数中参数 ... 和 JS 库 plot_config.js 中的功能函数是怎么对应的。图10.1 中图片下载按钮对应 toImageButtonOptions 参数, 看 toImageButtonOptions 源代码,可知 它接受任意数据类型,对应到 R 里面就是列表。 watermarkdisplaylogo 都是传递布尔值(TRUE/FALSE),具体根据 JS 代码中的 valType (参数值类型)决定,其它参数类似。另一个函数 layout 和函数 config() 是类似的,怎么传递参数值是根据 JS 代码来的。

toImageButtonOptions: {
    valType: 'any',
    dflt: {},
    description: [
        'Statically override options for toImage modebar button',
        'allowed keys are format, filename, width, height, scale',
        'see ../components/modebar/buttons.js'
    ].join(' ')
},
displaylogo: {
    valType: 'boolean',
    dflt: true,
    description: [
        'Determines whether or not the plotly logo is displayed',
        'on the end of the mode bar.'
    ].join(' ')
},
watermark: {
    valType: 'boolean',
    dflt: false,
    description: 'watermark the images with the company\'s logo'
},
library(plotly, warn.conflicts = FALSE)
plot_ly(diamonds,
  x = ~clarity, y = ~price,
  color = ~clarity, colors = "Set1", type = "box"
) %>%
  config(
    toImageButtonOptions = list(
      format = "svg", filename = paste("plot", Sys.Date(), sep = "_")
    ),
    watermark = F,
    displaylogo = FALSE, # 移除 Plotly 的 logo
    locale = "zh-CN", # 汉化
    # modeBarButtonsToRemove = c(
    #   "zoom2d", "zoomIn2d", "zoomOut2d", "autoScale2d", "resetScale2d", "pan2d",
    #   "hoverClosestCartesian", "hoverCompareCartesian", "toggleSpikelines"
    # ), # 去掉任意一个按钮
    displayModeBar = FALSE, # 去掉整个顶部工具栏
    showLink = FALSE
  ) %>%
  layout(
    images = list(
      source = "https://images.plot.ly/language-icons/api-home/r-logo.png",
      xref = "paper",
      yref = "paper",
      x = 1.0,
      y = 0.25,
      sizex = 0.2,
      sizey = 0.2,
      opacity = 0.5
    ),
    annotations = list(
      text = "watermark", # 文本注释
      font = list(
        size = 40, # 字号
        color = "red", # 颜色
        family = "Times New Roman" # 字族
      ),
      opacity = 0.2, # 字体透明度
      xref = "paper",
      yref = "paper",
      x = 0.5,
      y = 0.5,
      showarrow = FALSE # 去掉箭头指示
    )
  )

图 10.1: 自定义细节

函数 ggplotly() 将 ggplot 对象转化为交互式 plotly 对象

gg <- ggplot(faithful, aes(x = eruptions, y = waiting)) +
  stat_density_2d(aes(fill = ..level..), geom = "polygon") +
  xlim(1, 6) +
  ylim(40, 100)

静态图形

gg

转化为 plotly 对象

ggplotly(gg)

添加动态点的注释,比如点横纵坐标、坐标文本,整个注释标签的样式(如背景色)

ggplotly(gg, dynamicTicks = "y") %>%
  style(., hoveron = "points", hoverinfo = "x+y+text", 
        hoverlabel = list(bgcolor = "white"))