我正在使用 ranked-choice voting R 中的数据,并希望使用 Sankey 图绘制它(here 是一个例子)。桑基图默认为每个候选人用颜色编码的节点,但我想改为在节点内放置每个候选人的图像。
我有 5 位候选人:A、B、C、D 和 E,以及 27 位选民的优先排序(通过他们的 ID 标识:1、2、3、...、27)。这是我的初始数据:
rcv_data <-
structure(list(pref_voter_id = 1:27, `1` = c("A", "B", "C", "C",
"C", "D", "A", "C", "C", "C", "B", "C", "C", "E", "A", "B", "B",
"A", "B", "C", "C", "C", "B", "E", "D", "B", "E"), `2` = c("C",
"A", "A", "B", "A", "C", "E", "B", "A", "D", "C", "D", "D", "A",
"C", "D", "C", "E", "C", "D", "B", "A", "A", "A", "B", "C", "B"
), `3` = c("B", "C", "D", "E", "B", "E", "B", "A", "B", "A",
"E", "A", "E", "C", "E", "C", "D", "B", "D", "B", "A", "D", "C",
"C", "E", "D", "D"), `4` = c("E", "E", "B", "A", "D", "B", "D",
"D", "D", "B", "D", "B", "B", "D", "B", "E", "A", "D", "E", "A",
"D", "B", "E", "B", "A", "E", "C"), `5` = c("D", "D", "E", "D",
"E", "A", "C", "E", "E", "E", "A", "E", "A", "B", "D", "A", "E",
"C", "A", "E", "E", "E", "D", "D", "C", "A", "A")), row.names = c(NA,
-27L), class = c("tbl_df", "tbl", "data.frame"))
第 1、2、3、4、5 列对应每个选民的“第一选择”、“第二选择”、...、“第五选择”。
我正在使用 networkD3
用于在 R Markdown HTML 文档中创建 Sankey 图的包。将数据转换为适合 networkD3::sankeyNetwork
的格式函数(即在节点和边方面),需要使用 rcv
进行一些争论包和 rcv::makde_d3list
功能:
library(dplyr)
library(tidyr)
library(rcv)
library(networkD3)
rcv_data %>%
pivot_longer(2:6, names_to = "vote_rank", values_to = "candidate") %>%
rcv::rcv_tally(n_winners = 0) %>% # n_winners is 0 for the diagram to display an extra round
filter(candidate != "NA") %>% # I don't want "NA" to appear in the diagram
rcv::make_d3list() %>%
{networkD3::sankeyNetwork(Links = .$values, Nodes = .$names,
Source = "source", Target = "target",
Value = "value", NodeID = "candidate",
units = "voters", fontSize = 12, nodeWidth = 50)}
现在,我有一些文件 A.jpg、B.jpg、C.jpg、D.jpg 和 E.jpg,其中包含 5 位候选人的照片。我希望节点包含候选人的这些照片,而不是简单地进行颜色编码,即我想要候选人 C 的图像而不是深蓝色节点,而不是深橙色节点我想要候选人 A 的图像等。
我怀疑有两种途径可以解决问题:
networkD3::sankeyNetwork
仅提供更改节点颜色的功能,但使用其他 R 包可能还有其他解决问题的方法?我知道 visNetwork
package 允许将图像添加为节点,但它似乎不支持 Sankey 图(?)。htmlwidgets::onRender
函数使人们能够通过将图形保存到对象中来向图形添加额外的 JavaScript 代码,例如graph <- [code above]
, 然后像 htmlwidgets::onRender(graph, JS(...))
这样写 JavaScript .但是,我不确定 ...
中应该包含什么部分 - 如何访问节点并将它们按组附加到适当的图像?最佳答案
这里是一个添加图像到SVG中每个节点组的例子。仍有许多问题需要解决,例如图像的适当大小和位置,但这为添加它们提供了基础...
library(networkD3)
library(htmlwidgets)
nodes <- data.frame(name = c("a", "b", "c", "d"))
links <- data.frame(source = c(0, 0, 1, 1),
target = c(2, 3, 2, 3),
value = c(1, 3, 2, 4)
)
sn <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
Target = "target", Value = "value", NodeID = "name")
js <-
'
function(el) {
d3.select(el)
.selectAll(".node")
.append("image")
.attr("xlink:href", d => "https://pngimg.com/uploads/letter_" + d.name + "/letter_" + d.name + "_PNG4.png")
}
'
htmlwidgets::onRender(sn, js)
关于r - 如何使用 R 中的 rcv 和 networkD3 包在 D3 Sankey 图的节点中添加图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63862385/