Plotly自动创建子图(类似R中facet分面)的高效实现方案咨询
解决方案
最优方案:直接用ggplotly()转换现有ggplot代码
你本来就熟悉ggplot语法,直接转换是成本最低、完全兼容facet逻辑的方案,不需要额外处理分面逻辑,14-28个分面也会自动排布,完全不需要手动写每个子图代码,也不会出现宽表转换带来的类型冲突问题。
示例代码:
library(tidyverse) library(hrbrthemes) library(plotly) # 原有数据和ggplot代码完全不用修改 p <- 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() # 仅需一行代码转成交互plotly对象,完美保留分面效果 ggplotly(p)
该方案所有原有ggplot的自定义配置(主题、配色、映射逻辑)都可以完整保留,适配flexdashboard部署没有任何问题。
原生plotly语法替代方案(无需转宽表)
如果你需要用原生plotly语法实现,不需要转换宽表,直接按分面字段product的唯一值循环生成长表子图即可,不会出现字符/数字列冲突、variable列显示异常的问题:
library(plotly) library(tidyverse) # 直接使用原始长表数据 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)) # 获取所有分面类别 product_list <- unique(df$product) # 循环生成子图,通过筛选长表数据对应分面内容 plots <- lapply(product_list, function(p){ filter(df, product == p) %>% plot_ly(x = ~id, y = ~price, color = ~variable, type = 'scatter', mode = 'markers', text = ~paste("产品:", p, "<br>变量:", variable, "<br>价格:", price)) %>% layout(title = p) }) # 按需求调整nrows参数控制网格行数,自动排列所有分面 subplot(plots, nrows = 2, shareX = TRUE, shareY = TRUE, titleY = TRUE)
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

