In visNetwork, by default text doesn't go inside nodes, instead it appears below it:
require(visNetwork, quietly = TRUE)
nodes <- data.frame(id = 1:3, label=2014:2016 ,value=1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
Seems like the only way to solve this issue is to use set shape property to circle:
require(visNetwork, quietly = TRUE)
nodes <- data.frame(id = 1:3, label=2014:2016 ,value=1:3,shape='circle')
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
The problem is that, as you can see in the figure above, now with labels inside circle scaling nodes using value property don't work.
So the question is how to have both options ("scale" and "text inside") at the same time?
PS: What a pity, there is no visNetwork tag!
I found a tricky way to solve this bug. setting up font.size instead of value property works fine. You need to scale it for best visualization. For instance I scale it 10 times bigger:
require(visNetwork, quietly = TRUE)
nodes <- data.frame(id = 1:3, label=2014:2016 ,font.size =(1:3)*10,shape='circle')
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
I've found another way, adding spaces on bot sides of the label.
That will keep all fonts the same size.
n <- 5L
nodes <- data.frame(id = 1:3, label=paste0(strrep(" ",n), 2014:2016,
strrep(" ",n)) ,value=1:3,shape='circle')
edges <- data.frame(from = c(1,2), to = c(1,3))
visNetwork(nodes, edges, width = "100%")
If the length of the labels is not the same you may want to try other criteria.
Related
I have a network diagram with a fairly large amount of nodes (~600), each node having some data, including an ID and its name.
I want to be able to run a very simple function when double-clicking on a specific node.
For that purpose, I have followed the instructions from this thread.
Using the code provided:
library(shiny)
library(visNetwork)
ui <- fluidPage(
visNetworkOutput('network')
)
server <- function(input, output, session) {
getDiagramPlot <- function(nodes, edges){
v <- visNetwork(
nodes,
edges
) %>%
visPhysics(stabilization = TRUE, enabled = TRUE) %>%
visOptions(highlightNearest = list(enabled = T, degree = 1, hover = F), autoResize = TRUE, collapse = FALSE) %>%
visEdges(color = list(highlight = "red")) %>% # The colour of the edge linking nodes
visLayout(improvedLayout = TRUE) %>%
visEdges(arrows = edges$arrows) %>%
visInteraction(multiselect = F) %>%
visEvents(doubleClick = "function(nodes) {
Shiny.onInputChange('current_node_id', nodes.nodes);
;}")
return(v)
}
testFunction <- function(node_id){
print(paste("The selected node ID is:", node_id))
}
nodes <- data.frame(id = 1:3, label = 1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))
output$network <- renderVisNetwork(
getDiagramPlot(nodes, edges)
)
observeEvent(input$current_node_id,{
testFunction(input$current_node_id)
})
}
shinyApp(ui, server)
The codes works well but when I replace the simple nodes and edges dataframe provided as example by my data (much larger network) then the code doesn't work anymore (nothing gets printed in the console when I double-click on any nodes).
Would anyone know why the code is not running with my data ?
Here is the adjustments that should be done to the code below:
load("NodesEdges.RData")
# nodes <- data.frame(id = 1:3, label = 1:3)
# edges <- data.frame(from = c(1,2), to = c(1,3))
Best wishes,
C.
I have tried:
adding more columns to the example nodes/edges (group, value, color, etc.) and the codes still runs well.
restricting my larger nodes/edges dataframes respectively to the "id", "label" and "from", "to" columns (same as example data) but the codes still fails.
I wonder whether the problem comes from the size of the dataframe.
# example data
library(igraph)
links <- cbind.data.frame(from = rep("A", 6),
to = LETTERS[1:6],
weight = rep((1:3), each =2))
nodes <- nodes <- cbind.data.frame(id = LETTERS[1:6],
feature = rep((1:3), each =2))
net <- graph_from_data_frame(d = links, vertices = nodes, directed = T)
V(net)$color <- V(net)$feature
plot(net, vertex.size=30, edge.arrow.size = 0)
This is what I get:
What I want is to cluster the same colored nodes together, something similar as shown in the figure below. How can I do it?
Maybe the option mark.groups in plot could help
plot(net,mark.groups = split(V(net)$name,V(net)$color))
which gives
I'm trying to visualize my network with visNetwork package. But I found myself totally confused about controling node size and edge width. In the first example, I set value=1 in nodes and value=0.1in edges. In the second example, I set value=10 in nodes and width=0.1 in edges. However, in both graphs, size of nodes appear to be the same. Changing edge width seems to work with width not value. I don't know why. I did see people use value in edges for edge width control.
Can anyone clarify me on this issue? Also, what is the range of values for node size and edge width?
nodes1 <- data.frame(id = 1:10,
label = paste("Node", 1:10),# add labels on nodes
value = 1, #**
color = c("darkblue"))
edges1 <- data.frame(from = sample(1:10,8),
to = sample(1:10, 8),
value = 0.1 #**
)
visNetwork::visNetwork(nodes1, edges1, width = "150%", physics=F)
nodes2 <- data.frame(id = 1:10,
label = paste("Node", 1:10),# add labels on nodes
value = 10, #**
color = c("darkblue"))
edges2 <- data.frame(from = sample(1:10,8),
to = sample(1:10, 8),
width = 0.1 #**
)
visNetwork::visNetwork(nodes2, edges2, width = "150%", physics=F)
it looks like size of the nodes works based on comparison . If it is set one value than graph just reflect the same size of nodes on optimal scale, thus it is not changed
if you put value equal to different number you'll see nodes of different size
nodes2 <- data.frame(id = 1:10,
label = paste("Node", 1:10),# add labels on nodes
value = 1:10, #**
color = c("darkblue"))
edges2 <- data.frame(from = sample(1:10,8),
to = sample(1:10, 8),
width = 0.1 #**
)
visNetwork::visNetwork(nodes2, edges2, width = "150%", physics=F)
I am using igraph in R for network analysis. I want to display an edge attribute on each line in the plot. An example is below
df <- data.frame(a = c(0,1,2,3,4),b = c(3,4,5,6,7))
nod <- data.frame(node = c(0:7),wt = c(1:8))
pg <- graph_from_data_frame(d = df, vertices = nod,directed = F)
plot(pg)
I want the value of the "wt" feature to show up between each node on the line, or preferably, in a little gap where the line breaks.
Is it possible to make this happen?
Use the parameter edge.label to assign labels of the edges, I used - probably wrong - nod$wt. Of course, you could assign other labels.
You could use the following code:
# load the package
library(igraph)
# your code
df <- data.frame(a = c(0,1,2,3,4),b = c(3,4,5,6,7))
nod <- data.frame(node = c(0:7),wt = c(1:8))
pg <- graph_from_data_frame(d = df, vertices = nod,directed = F)
# plot function with edge.label added
plot(pg, edge.label = nod$wt)
Please, let me know whether this is what you want.
I found the R riverplot package very handy to make Sankey/Minard charts. The output chart is great, including the position of the nodes and the width of the edges.
But, I have a problem with the colors. I assigned colors through a "col" column in the nodes, but the output colors do not match at all what I indicated. I tried experimentally to remove all colors, assign a single color at a time, then add a second, and so on, but I've been unable to find any logic in the erroneous assignments. It just seems completely random, even adding colors that I are not part of the specified list.
For my ease of handling, I loaded the nodes and edges as two separate files.
Below is my reproducible example:
#######################
R CODE:
#######################
library(riverplot)
ruk_sankey_edges <- read.table("/.../ruk_sankey_edges.csv", header = TRUE, na.strings = "''", sep = ";", dec=".")
ruk_sankey_nodes <- read.table("/.../ruk_sankey_nodes.csv", header = TRUE, na.strings = "''", sep = ";", dec=".")
nodes <- ruk_sankey_nodes
edges <- ruk_sankey_edges
colnames( nodes ) <- c( "ID", "x", "y", "col")
colnames( edges ) <- c( "ID", "N1", "N2", "Value")
river <- makeRiver( nodes, edges, node_labels = NULL, node_xpos = nodes$x, node_ypos = nodes$y)
style <- list(col = nodes$col )
riverplot(river, lty = 0, default_style = style, srt = 0,
node_margin = 0.1, nodewidth = 1, plot_area = 0.8, nsteps = 50,
add_mid_points = NULL, yscale = "auto")
#######################
AND THE DATA FILES:
#######################
ruk_sankey_nodes.csv :
ID;X;Y;col
A1;5;70;gray
A2;10;90;red
A3;10;65;gray
A4;20;85;gray
A5;30;105;green
A6;30;95;cyan
A7;30;85;mangenta
A8;30;75;yellow
A9;20;45;gray
A10;30;60;blue
A11;30;40;black
#######################
ruk_sankey_edges.csv :
ID;ID1;ID2;Value
E1;A1;A3;39159
E2;A1;A2;8200
E3;A4;A8;2942
E4;A4;A7;1608
E5;A4;A6;3039
E6;A4;A5;3897
E7;A3;A9;27673
E8;A3;A4;11486
E9;A9;A11;22235
E10;A9;A10;5438
#######################
Does anyone have a suggestion? Or is able to obtain the indicated colors?
Thank you very much,
Patrick
In your nodes data frame (as in nodes.df below), convert the col variable, which is probably a factor, to character. riverplot() gets confused!
nodes.df$col <- as.character(nodes.df$col)
alternatively use
stringsAsFactors= FALSE
in your 'nodes' data frame. This is proposed in the Reference Manual: see the examples on page 7 for 'makeriver()' styles.