如何确保Highcharter桑基图Post节点按1-7顺序排列?
解决highcharter桑基图Post节点顺序混乱问题
问题
使用highcharter绘制Pre→Post的桑基图时,右侧Post节点的数字顺序偶尔会被打乱,期望Post节点严格按1到7的顺序排列,当前实现代码如下:
library(highcharter) library(dplyr) # prepare data dat <- prae_post_aktuell %>% select(q39_lq, post_q39_lq) %>% filter(!is.na(q39_lq), !is.na(post_q39_lq)) %>% mutate( q39_lq = factor(as.character(q39_lq), levels = as.character(1:7), ordered = TRUE), post_q39_lq = factor(as.character(post_q39_lq), levels = as.character(1:7), ordered = TRUE), from = paste0("Pre: ", q39_lq), to = paste0("Post: ", post_q39_lq) ) %>% count(from, to, name = "weight") # define color map color_map <- c( "1" = "#d73027", "2" = "#f46d43", "3" = "#fdae61", "4" = "#888800", "5" = "#a6d96a", "6" = "#66bd63", "7" = "#1a9850" ) # define all possible pre- / post-nodes in the right order pre_nodes <- paste0("Pre: ", 1:7) post_nodes <- paste0("Post: ", 1:7) node_order <- c(pre_nodes, post_nodes) # Reihenfolge explizit! # Order Sankey-data based on from / to dat <- dat %>% mutate( from = factor(from, levels = pre_nodes, ordered = TRUE), to = factor(to, levels = post_nodes, ordered = TRUE) ) %>% arrange(from, to) # create nodes in defined order nodes <- node_order |> lapply(function(x) { num <- gsub("[^0-9]", "", x) list( id = unname(x), color = unname(color_map[num]), name = unname(x) ) }) # create sankey diagram highchart() %>% hc_add_series( data = dat, type = "sankey", hcaes(from = from, to = to, weight = weight), nodes = nodes, name = "Sorge vor Anfällen (Pre → Post)" ) %>% hc_plotOptions( sankey = list( nodeWidth = 20, nodePadding = 15, curveFactor = 0.4, linkOpacity = 0.4 ), series = list(dataLabels = list(style = list(fontSize = "12px"))) ) %>% hc_title(text = "Veränderung der Lebensqualitäts Skala (Pre → Post)") %>% hc_tooltip(pointFormat = "Von <b>{point.from}</b> nach <b>{point.to}</b>: {point.weight}") %>% hc_chart(height = 600)
解决方法
Highcharts默认会根据节点间的流量自动调整节点顺序,要强制固定Post节点的顺序,只需在sankey的绘图选项中添加nodePositionBy: 'category',让图表严格遵循我们定义的nodes列表顺序排列。
修改后的完整代码:
library(highcharter) library(dplyr) # prepare data dat <- prae_post_aktuell %>% select(q39_lq, post_q39_lq) %>% filter(!is.na(q39_lq), !is.na(post_q39_lq)) %>% mutate( q39_lq = factor(as.character(q39_lq), levels = as.character(1:7), ordered = TRUE), post_q39_lq = factor(as.character(post_q39_lq), levels = as.character(1:7), ordered = TRUE), from = paste0("Pre: ", q39_lq), to = paste0("Post: ", post_q39_lq) ) %>% count(from, to, name = "weight") # define color map color_map <- c( "1" = "#d73027", "2" = "#f46d43", "3" = "#fdae61", "4" = "#888800", "5" = "#a6d96a", "6" = "#66bd63", "7" = "#1a9850" ) # define all possible pre- / post-nodes in the right order pre_nodes <- paste0("Pre: ", 1:7) post_nodes <- paste0("Post: ", 1:7) node_order <- c(pre_nodes, post_nodes) # 明确节点顺序 # Order Sankey-data based on from / to dat <- dat %>% mutate( from = factor(from, levels = pre_nodes, ordered = TRUE), to = factor(to, levels = post_nodes, ordered = TRUE) ) %>% arrange(from, to) # create nodes in defined order nodes <- node_order |> lapply(function(x) { num <- gsub("[^0-9]", "", x) list( id = unname(x), color = unname(color_map[num]), name = unname(x) ) }) # create sankey diagram highchart() %>% hc_add_series( data = dat, type = "sankey", hcaes(from = from, to = to, weight = weight), nodes = nodes, name = "Sorge vor Anfällen (Pre → Post)" ) %>% hc_plotOptions( sankey = list( nodeWidth = 20, nodePadding = 15, curveFactor = 0.4, linkOpacity = 0.4, nodePositionBy = "category" # 关键:强制按定义的节点顺序排列 ), series = list(dataLabels = list(style = list(fontSize = "12px"))) ) %>% hc_title(text = "Veränderung der Lebensqualitäts Skala (Pre → Post)") %>% hc_tooltip(pointFormat = "Von <b>{point.from}</b> nach <b>{point.to}</b>: {point.weight}") %>% hc_chart(height = 600)
说明
nodePositionBy: "category"会让桑基图的节点严格按照nodes列表的顺序排列,而非根据流量自动调整。- 你的代码已经正确定义了
node_order(先Pre1-7,再Post1-7),添加该配置后就能保证Post节点按1到7的顺序显示。
内容的提问来源于stack exchange,提问作者NinjaNuri
相关产品推荐
相关产品推荐

