在 plotly 中自动创建子图(例如 R 中的分面)

Automatically creating subplots in plotly (e.g. Facetting in R)

我对使用 tidyverse 和 ggplot 非常满意。我正在尝试生成一个交互式图形以使用 flexdashboard 进行部署。因此,我试图在 plotly 中生成我常用的 ggplots。

假设我有以下数据框:

data.frame(id = c(1:5),
           product = c("product1","product2","product1","product3","product2"),
           variable = c("var1","var1","var3","var2","var1"),
           price = c(100,120,140,90,80))

输出:

  id  product variable price
1  1 product1     var1   100
2  2 product2     var1   120
3  3 product1     var3   140
4  4 product3     var2    90
5  5 product2     var1    80

如果我想在绘图上显示所有这些,我会在 ggplot 中执行以下操作:

library(tidyverse)
library(hrbrthemes)

data.frame(id = c(1:5),
           product = c("product1","product2","product1","product3","product2"),
           variable = c("var1","var1","var3","var2","var1"),
           price = c(100,120,140,90,80)) %>%
  ggplot(aes(x = id, y = price, color = variable)) +
  geom_point() +
  facet_wrap(~product) +
  theme_ft_rc()

哪个会产生:

我知道我可以通过使用 subplot() 功能。问题是我有 14-28 个类别可以绘制为构面。据我所知,这意味着我必须制作 14-28 个地块,然后将它们排列在一个网格中。这似乎有点乏味,我想知道是否有更有效的方法来实现这一点,例如 ggplot 中的 facet 选项。我还在另一个 post:

上得到了一段代码
library(plotly)

dataframe <- data.frame(id = c(1:5),
           product = c("product1","product2","product1","product3","product2"),
           variable = c("var1","var1","var3","var2","var1"),
           price = c(100,120,140,90,80)) %>%
  pivot_wider(names_from = "product", values_from = "price")

vars <- setdiff(names(dataframe),"id")

plots <- lapply(vars, function(var){
   plot_ly(dataframe, x = ~id, color =~variable, y = as.formula(paste0("~",var))) %>%
  add_bars(name = var)
 })
 subplot(plots, nrows = length(plots), shareX = TRUE, titleX = FALSE)

产生:

并且需要将 tidyr 的 pivot_wider() 函数与示例框架中的 product 列一起使用。但是,我的真实列包含数字和字符,在使用上述示例代码时会产生错误。变量列也以一种奇怪的方式显示。这个问题是否有解决方法,或者真正为每个图手动编写代码的最佳方法是什么?

根据您的第一个示例(我刚刚删除了您的主题样式),它是这样工作的。

df <- data.frame(
  id = c(1:5),
  product = c("product1","product2","product1","product3","product2"),
  variable = c("var1","var1","var3","var2","var1"),
  price = c(100,120,140,90,80)
)

plot <- ggplot(df, aes(x = id, y = price, color = variable)) +
  geom_point() +
  facet_wrap(~product)

ggplotly(plot)

唯一的区别是我没有用 %>% 链接,因为当我在下面尝试这个时似乎会阴谋地抛出一个错误:

data.frame(
  id = c(1:5),
  product = c("product1","product2","product1","product3","product2"),
  variable = c("var1","var1","var3","var2","var1"),
  price = c(100,120,140,90,80)
) %>% ggplot(aes(x = id, y = price, color = variable)) +
  geom_point() +
  facet_wrap(~product) %>% ggplotly()

# Error in UseMethod("ggplotly", p) : 
#   no applicable method for 'ggplotly' applied to an object of class "c('FacetWrap', 'Facet', 'ggproto', 'gg')"

带有自定义工具提示的扩展示例

你可以随心所欲地设计它,我添加了价格格式,为了好玩,它在工具提示中将产品和变量合并为一行。

custom_tooltip <- paste0("ID: ", df$id, "\n", "Product: ", df$product, " (", df$variable, ")\n", "Sold for: £ ", df$price)

plot <- ggplot(df, aes(x = id, y = price, color = variable)) +
  geom_point(aes(text = custom_tooltip)) +
  facet_wrap(~product)

ggplotly(plot, tooltip = c("text"))