Logo
Section 1 / 2

使用 ggiraph 包实现交互式图表

学习如何使用 ggiraph 包为 ggplot2 中的任何静态可视化添加交互功能。

导入

使用 ggiraph 包实现交互式图表

学习如何使用 ggiraph 包为 ggplot2 中的任何静态可视化添加交互功能。

我们可以使用 ggplot2 创建视觉上吸引人的静态图表。让我们探索如何为 ggplot 图表添加并增强交互性。

为什么要在 ggplot 图表中添加交互性?

虽然静态可视化通常足以讲述数据故事,但在处理大型或复杂数据集时,可能无法有效传达信息。为了解决这一局限性,为 ggplot2 图表添加交互性可以让我们以多种方式与数据互动,例如缩放、平移以及悬停查看数据点。一个用于实现交互性的流行包是 ggiraph 包。

开始使用 ggiraph 包

ggiraph 包是 ggplot2 的扩展,允许我们在 R 中创建动态且交互式的图形,适用于 R Markdown 文档和 Shiny 应用程序。它基于 ggplot2 的功能,并为其函数添加了 _interactive 后缀。

ggiraph 包使用专门针对 SVG 的 R 图形设备,使添加交互组件变得简单,如工具提示、动画和 JavaScript 操作。我们可以使用 ggiraph 包的交互式几何对象、比例尺、分面、图例和主题来创建交互式图表。

让我们通过以下代码加载 ggiraph 包:

1library(ggiraph)

ggiraph 包中的交互函数

几乎所有的 ggplot2 元素都可以通过 girafe() 函数转换为交互式 ggiraph 图形。ggiraph 包通过以下交互式函数扩展了 ggplot2 的功能:

  • 交互式几何对象函数:包括 geom_point_interactive()、geom_col_interactive() 和 geom_density_interactive() 等。
  • 交互式比例尺函数:包括 scale_color_interactive()、scale_color_brewer_interactive() 和 scale_manual_interactive() 等。
  • 交互式分面函数:包括 facet_wrap_interactive() 和 facet_grid_interactive()。
  • 交互式图例函数:包括 guide_colourbar_interactive()、guide_colorsteps_interactive() 和 guide_legend_interactive() 等。
  • 交互式主题元素函数:包括 element_line_interactive()、element_rect_interactive() 和 element_text_interactive()。

为了实现交互性,ggiraph 包使用三个主要美学属性:

  • tooltip:当悬停在某个元素上时,显示该元素的额外信息。
  • data_id:数据集中的一列,为每个元素分配唯一标识符。某些功能(如悬停时显示信息)需要此字段。
  • onclick:点击元素时执行 JavaScript 函数的功能。

在使用 ggiraph 包的函数之前,我们先通过以下代码设置所有图表的默认主题:

1theme_set(theme_bw() + 2 theme(legend.position = "bottom", 3 panel.grid = element_blank()))
  • 第1行:我们使用 theme_set() 函数将默认灰度主题更改为 theme_bw()。
  • 第2–3行:我们在 theme() 函数中将 legend.position 设置为 "bottom",并通过 element_blank() 函数移除网格线。

使用 ggiraph 包创建交互式散点图

让我们使用 Cars93 数据集和 girafe() 函数创建一个交互式散点图,代码如下:

No configuration found for ID: 8a43840232fe0698bdd1c49a7e1fe5848c3ef26372e2e57211b23428fc85221d

  • 第1行:我们使用 ggplot() 函数初始化一个新的 ggplot 对象,并传入 Cars93 数据集的名称。我们将图表存储在名为 scatter_plot 的对象中。行末的 + 操作符用于继续向 ggplot 对象追加后续图层。
  • 第2行:我们使用 geom_point_interactive() 函数创建带有交互点的散点图。这里,我们使用 aes() 函数将 EngineSize 变量映射到 x 轴,将 Price 变量映射到 y 轴,并通过 color 参数按 Origin 变量分组。
  • 第3行:我们通过 size 参数将点的大小设为 2,通过 alpha 参数将透明度设为 0.5。
  • 第4行:我们将 tooltip 参数设为 Manufacturer 变量,使得悬停在每个点上时会显示该变量的值。同时将 data_id 参数设为 Manufacturer。
  • 第5行:我们使用 scale_color_manual_interactive() 函数为图表设置特定颜色。
  • 第6行:我们创建一个名为 mygraph 的新对象,并使用 <- 赋值操作符将 girafe() 对象(即 scatter_plot 的交互版本)存储其中。

使用 ggiraph 包创建交互式条形图

接下来,我们将基于 Cars93 数据集的 Origin 列创建一个交互式条形图。

No configuration found for ID: 8a94b2819a92e335f6de2fbf8d8c46e26f157aef9440f8fb702e0c5f25d2589e

  • 第2行:我们使用 geom_bar_interactive() 函数创建带有交互条形的条形图。这里,我们使用 aes() 函数将 Type 变量映射到 x 轴。通过 fill 参数按 Origin 变量分组,并将 data_id 参数设为 Origin 以指定分组变量。
  • 第3行:我们使用 sprintf() 函数格式化工具提示文本,将填充颜色(fill)与计数值(after_stat(count))结合。size 参数设为 3,用于调整条形的粗细。

使用 ggiraph 实现交互式分面

接下来,我们将使用 facet_wrap_interactive() 和 labeller_interactive() 函数构建交互式分面。

No configuration found for ID: 47cb3a202848855f521c394da173a7605436e355c1bb1562a555d8a9741bbe24

  • 第2行:我们使用 facet_wrap_interactive() 函数创建一个分面网格图。通过 ncol 参数指定分面网格的列数为 2,因此网格将包含两列。
  • 第3行:我们将 interactive_on 参数设为 text,表示当与分面网格中的文本元素交互时触发交互效果。
  • 第4行:我们通过在 vars 参数中指定 DriveTrain 变量,将数据按其唯一值分割并分别显示在不同的子图中。
  • 第5–6行:我们使用 labeller_interactive() 函数设置分面标签的标签器。它创建一个交互式工具提示,显示文本 This is DriveTrain =>,后接每个分面对应的 DriveTrain 值。

带可点击数据点的交互式散点图

接下来,我们将使用 ggiraph 包中的 onclick 参数在图表中触发动作。当点击图形元素(如点或条形)时,onclick 参数接受一个 JavaScript 函数以执行相应操作。这要求数据集中包含一个字符串列,其中包含正确的 JavaScript 指令。

为了演示 ggiraph 包中 onclick 参数的交互功能,我们将使用一个虚拟住房数据集,其中包含不同州的房屋信息。该数据集包括州代码、各州人口、每栋房屋的房间数量以及相应的中位房价。所有这些数据已存在于名为 df 的数据框中。

让我们使用 head() 函数打印数据框的前几行:

1head(df)

通过在 ggiraph 包中使用 onclick 参数,我们可以使用上述 housing 数据集创建一个交互式散点图。

No configuration found for ID: ff2174e9134e947918f24a3e3a9c18f264dcb4cbeebba449e344450906c34307

  • 第3行:我们在 geom_point_interactive() 函数中将 hover_nearest 参数设为 TRUE,以便在悬停于图表时对最近的点应用悬停效果。
  • 第4行:我们将 tooltip 参数设为 state 列,即悬停在某一点时,工具提示将显示对应州的名称。
  • 第5行:我们使用 onclick 参数配合 sprintf() 函数,指定一个 JavaScript 函数,该函数将在浏览器中打开一个新窗口或标签页,跳转至对应州的维基百科页面。字符串中的 %s 占位符将动态替换为州名。

创建图表面板

使用 Plotly 为 ggplot2 地图添加交互功能