R networkD3包:simpleNetwork()中的节点着色

时间:2016-02-08 22:02:44

标签: javascript r htmlwidgets networkd3

networkD3包(请参阅herehere)允许用户创建简单的互动网络:

# Load package
library(networkD3)

# Create fake data
src <- c("A", "A", "A", "A",
        "B", "B", "C", "C", "D")
target <- c("B", "C", "D", "J",
            "E", "F", "G", "H", "I")
networkData <- data.frame(src, target)

# Plot
simpleNetwork(networkData)

有没有办法指定我希望src向量中的所有元素都是某种颜色,同时允许target向量中的所有元素都是不同的颜色?这样我就可以在视觉上区分网络中src节点和target节点。

simpleNetwork()目前似乎不支持此功能(但我希望有人能帮助我使用自制程序脚本):

enter image description here

类似但不相关的问题是asked here

4 个答案:

答案 0 :(得分:10)

Here's how to control colour of nodes with forceNetwork. Notice this still won't tell you the direction of the links because some nodes are source for some links and target for others - so you'll need to rethink that logic somehow. But anyway, here's controlling colour of nodes.

# Load package
library(networkD3)
library(dplyr) # to make the joins easier

# Create fake data
src <- c("A", "A", "A", "A",
         "B", "B", "C", "C", "D")
target <- c("B", "C", "D", "J",
            "E", "F", "G", "H", "I")
networkData <- data.frame(src, target, stringsAsFactors = FALSE)

nodes <- data.frame(name = unique(c(src, target)), stringsAsFactors = FALSE)
nodes$id <- 0:(nrow(nodes) - 1)


# create a data frame of the edges that uses id 0:9 instead of their names
edges <- networkData %>%
   left_join(nodes, by = c("src" = "name")) %>%
   select(-src) %>%
   rename(source = id) %>%
   left_join(nodes, by = c("target" = "name")) %>%
   select(-target) %>%
   rename(target = id)

edges$width <- 1

# make a grouping variable that will match to colours
nodes$group <- ifelse(nodes$name %in% src, "lions", "tigers")

# simple with default colours
forceNetwork(Links = edges, Nodes = nodes, 
             Source = "source",
             Target = "target",
             NodeID ="name",
             Group = "group",
             Value = "width",
             opacity = 0.9,
             zoom = TRUE)

# control colours with a JS ordinal scale
# edited 20 May 2017 with updated code from Renal Chesak's answer:
ColourScale <- 'd3.scaleOrdinal()
            .domain(["lions", "tigers"])
           .range(["#FF6900", "#694489"]);'

forceNetwork(Links = edges, Nodes = nodes, 
             Source = "source",
             Target = "target",
             NodeID ="name",
             Group = "group",
             Value = "width",
             opacity = 0.9,
             zoom = TRUE,
             colourScale = JS(ColourScale))

enter image description here

答案 1 :(得分:4)

彼得埃利斯的上述答案可能曾经有过一次,但似乎代码已在新版本中更新。您必须使用d3.scaleOrdinal().range([])

,而不是grayRef.addListenerForSingleValueEvent

答案 2 :(得分:1)

您可以执行与链接帖子类似的操作,但这是使用visNetwork包的示例。这个包与vis.js接口,并且制作了非常好的交互式图形。

library(visNetwork)
id <- unique(c(src, target))                                  # node ids
nodes <- data.frame(id, group=+(id %in% src),                 # add a grouping for src/target
  label=id, title=sprintf('<p>Node %s</p>', id))              # add some labels
g <- visNetwork(nodes=nodes, edges=networkData, width="75%")  # make graph
visExport(visHierarchicalLayout(g))                           # make it tree-like

enter image description here

答案 3 :(得分:1)

彼得埃利斯的答案完成了这项工作,但这是一种替代方法,它更简洁,更容易理解......

(另外,应该注意的是,节点可以同时位于sourcetarget向量中,在这种情况下,根据您的规范,它们应该是哪种颜色,不确定的。)

library(networkD3)

src <- c("A", "A", "A", "A", "B", "B", "C", "C", "D")
target <- c("B", "C", "D", "J", "E", "F", "G", "H", "I")
networkData <- data.frame(src, target, stringsAsFactors = FALSE)

# make a nodes data frame out of all unique nodes in networkData
nodes <- data.frame(name = unique(c(networkData$src, networkData$target)))

# make a group variable where nodes in networkData$src are identified
nodes$group <- nodes$name %in% networkData$src

# make a links data frame using the indexes (0-based) of nodes in 'nodes'
links <- data.frame(source = match(networkData$src, nodes$name) - 1,
                    target = match(networkData$target, nodes$name) - 1)

forceNetwork(Links = links, Nodes = nodes, Source = "source",
             Target = "target", NodeID ="name", Group = "group",
             opacity = 1, opacityNoHover = 1)

enter image description here