Plotly R中如何用subplot实现桑基图并排或上下布局?
在Plotly R中实现桑基图的并排或上下布局
问题描述
尝试使用Plotly R的subplot函数将两个桑基图上下或并排展示时,出现图重叠的问题,无法正常布局。可复现代码如下:
library(plotly) fig1 <- plot_ly( type = "sankey", orientation = "h", node = list( label = c("A1", "A2", "B1", "B2", "C1", "C2"), color = c("blue", "blue", "blue", "blue", "blue", "blue"), pad = 15, thickness = 20, line = list( color = "black", width = 0.5 ) ), link = list( source = c(0,1,0,2,3,3), target = c(2,3,3,4,4,5), value = c(8,4,2,8,4,2) ) ) fig2 <- plot_ly( type = "sankey", orientation = "h", node = list( label = c("A1", "A2", "B1", "B2", "C1", "C2"), color = c("blue", "blue", "blue", "blue", "blue", "blue"), pad = 15, thickness = 20, line = list( color = "black", width = 0.5 ) ), link = list( source = c(0,1,0,2,3,3), target = c(2,3,3,4,4,5), value = c(8,4,2,8,4,2) ) ) plotly::subplot(fig1, fig2, nrows = 2)
运行后两个桑基图重叠,无法正常显示布局。
解决方案
由于subplot函数对桑基图的布局支持存在问题,可通过手动设置每个桑基图的domain参数,结合plotly::layout实现上下或并排布局:
1. 上下布局(纵向排列)
为每个桑基图分配纵向区域,比如第一个图占顶部50%,第二个占底部50%:
library(plotly) # 第一个桑基图:占据顶部半区 fig1 <- plot_ly( type = "sankey", orientation = "h", domain = list(y = c(0.5, 1)), node = list( label = c("A1", "A2", "B1", "B2", "C1", "C2"), color = rep("blue", 6), pad = 15, thickness = 20, line = list(color = "black", width = 0.5) ), link = list( source = c(0,1,0,2,3,3), target = c(2,3,3,4,4,5), value = c(8,4,2,8,4,2) ) ) # 第二个桑基图:占据底部半区 fig2 <- plot_ly( type = "sankey", orientation = "h", domain = list(y = c(0, 0.5)), node = list( label = c("A1", "A2", "B1", "B2", "C1", "C2"), color = rep("blue", 6), pad = 15, thickness = 20, line = list(color = "black", width = 0.5) ), link = list( source = c(0,1,0,2,3,3), target = c(2,3,3,4,4,5), value = c(8,4,2,8,4,2) ) ) # 合并图表并调整布局 fig <- fig1 %>% add_trace(data = fig2$x$data[[1]]) fig <- fig %>% layout( showlegend = FALSE, title = "上下排列的桑基图" ) fig
2. 并排布局(横向排列)
设置每个桑基图的domain的x轴范围,比如第一个占左半区,第二个占右半区:
library(plotly) # 第一个桑基图:占据左半区 fig1 <- plot_ly( type = "sankey", orientation = "h", domain = list(x = c(0, 0.5)), node = list( label = c("A1", "A2", "B1", "B2", "C1", "C2"), color = rep("blue", 6), pad = 15, thickness = 20, line = list(color = "black", width = 0.5) ), link = list( source = c(0,1,0,2,3,3), target = c(2,3,3,4,4,5), value = c(8,4,2,8,4,2) ) ) # 第二个桑基图:占据右半区 fig2 <- plot_ly( type = "sankey", orientation = "h", domain = list(x = c(0.5, 1)), node = list( label = c("A1", "A2", "B1", "B2", "C1", "C2"), color = rep("blue", 6), pad = 15, thickness = 20, line = list(color = "black", width = 0.5) ), link = list( source = c(0,1,0,2,3,3), target = c(2,3,3,4,4,5), value = c(8,4,2,8,4,2) ) ) # 合并图表并调整布局 fig <- fig1 %>% add_trace(data = fig2$x$data[[1]]) fig <- fig %>% layout( showlegend = FALSE, title = "并排排列的桑基图" ) fig
原理说明
domain参数用于指定图表在画布中的占比范围,取值为0到1之间的数组。纵向布局时控制y轴范围,横向布局时控制x轴范围,通过为每个桑基图分配独立区域,避免重叠问题。
内容的提问来源于stack exchange,提问作者Quinten
相关产品推荐
相关产品推荐

