R networkD3 package: node coloring in simpleNetwork()

后端 未结 4 427
甜味超标
甜味超标 2020-12-03 06:00

The networkD3 package (see here and here) allows a user to create simple interactive networks:

# Load package
library(networkD3)

# Create fake          


        
相关标签:
4条回答
  • 2020-12-03 06:14

    Peter Ellis's answer above might have worked at one time, but it seems the code has been updated in a new release. Instead of d3.scale.ordinal().range([]), you will have to use d3.scaleOrdinal().range([])

    0 讨论(0)
  • 2020-12-03 06:20

    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))
    

    0 讨论(0)
  • 2020-12-03 06:22

    You could do a similar thing as in the linked post, but here is an example using the visNetwork package. This package interfaces with vis.js, and makes really nice interactive graphs.

    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
    

    0 讨论(0)
  • 2020-12-03 06:25

    Peter Ellis' answer does the job, but this is an alternate approach, which imho is bit more concise and easier to understand...

    (Also, it should be noted that nodes can be in both the source and the target vectors at the same time, in which case, which color they should be, given your specification, is uncertain.)

    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)
    

    0 讨论(0)
提交回复
热议问题