2016-02-08 17 views
8

networkD3パッケージは、(herehereを参照してください)簡単なインタラクティブなネットワークを作成をユーザーに許可する:R networkD3パッケージ:simpleNetwork内のノードの色()

# 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ベクターのすべての要素を異なる色にすることができるか?これにより、ネットワーク内のtargetノードからノードsrcを視覚的に区別することができます。

この機能は現在simpleNetwork()ではサポートされていないようです(私は誰かが自作のスクリプトで私を助けることができる願っています):

enter image description here

関連ではないが類似の質問がasked hereました。

+1

はそれをです...私見はもう少し簡潔で理解しやすい別のアプローチであり、同じパッケージ内で 'forceNetwork()'を使っても構いませんか?グループとJavaScriptスケールで色をコントロールできます。あなたが熱心であれば、私は完全な答えをすることができます。 –

+0

@PeterEllisはい、それは非常に役に立つでしょう。 – warship

+0

おそらく関連する質問は、あらかじめ指定された色でノードを色付けする必要があります:http://stackoverflow.com/questions/38793947/r-colouring-scheme-in-networkd3-vs-igraph?noredirect=1#comment65115769_38793947 –

答えて

7

ここforceNetworkでノードの色を制御する方法を説明します。いくつかのノードがいくつかのリンクのソースであり、他のノードのターゲットであるため、これはリンクの方向を教えてくれないことに注意してください。そうすれば、そのロジックを何とか考え直す必要があります。しかし、とにかく、ここではノードの色を制御しています。上記

# 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

+2

すべてのノードにラベルを付けるとよいでしょう。あなたは、(srcと 'target'の両方のために)ノードをオンホバーのアクセシビリティの代わりに自動的に表示させる方法を示す答えを広げてください。 – warship

+0

これには 'opacityNoHover'という引数があります。ノードラベルを常に表示するには、 'opacityNoHover = 1'を使用してください。 –

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

+0

非常にクール。私はあなたが 'networkD3'で似たようなものを見つけることを願っています:-) +1 – warship

4

ピーター・エリスの答えは、一度に働いているかもしれないが、コードが新しいリリースで更新されているようです。代わりにd3.scale.ordinal().range([])の、あなたが使用する必要がありますd3.scaleOrdinal().range([])

+2

ありがとうございます。私はこのコンビネーションを非常に頻繁に使用せず、あなたの答えの3年後に変更を見ました。私自身の仕事でなぜこれがもううまくいかないのか疑問に思った時です!私は元の答えを編集しました。 –

1

ピーター・エリス答えは仕事をしていませんが、これは

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) 
関連する問題