Can the visNetwork (R) output save as vector pdf file? - r

I've tried
nodes <- data.frame(id = 1:3, group = c("B", "A", "B"))
edges <- data.frame(from = c(1,2), to = c(2,3))
visNetwork(nodes, edges) %>% visExport(type = "pdf")
and unfortunately, the pdf generated doesn't contain a vectorial image of my network but a bad quality raster image.
How can I get a high-quality vector pdf file?

Related

R: Display "popup" information when mouse hovers over (graph) visnetwork

I simulated some data and created a graph network in R using visnetwork:
library(igraph)
library(dplyr)
library(visNetwork)
#create file from which to sample from
x5 <- sample(1:100, 1100, replace=T)
#convert to data frame
x5 = as.data.frame(x5)
#create first file (take a random sample from the created file)
a = sample_n(x5, 1000)
#create second file (take a random sample from the created file)
b = sample_n(x5, 1000)
#combine
c = cbind(a,b)
#create dataframe
c = data.frame(c)
#rename column names
colnames(c) <- c("a","b")
#create graph
graph <- graph.data.frame(c, directed=F)
graph <- simplify(graph)
plot(graph)
fc <- fastgreedy.community(graph)
V(graph)$community <- fc$membership
library(visNetwork)
nodes <- data.frame(id = V(graph)$name, title = V(graph)$name, group = V(graph)$community)
nodes <- nodes[order(nodes$id, decreasing = F),]
edges <- get.data.frame(graph, what="edges")[1:2]
#visnet graph
visNetwork(nodes, edges) %>% visIgraphLayout(layout = "layout_with_fr") %>%
visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)
Right now, the graph only displays node information when you click on it. Suppose if each node had observed properties in the "original file". E.g.
#add some information corresponding to the original data
other_damages_in_dollars <- rnorm(1000,104,9)
location <- c("canada","usa")
location <- sample(location, 1000, replace=TRUE, prob=c(0.3, 0.7))
type_of_house <- c("single","townhome", "rental" )
type_of_house<- sample(type_of_house , 1000, replace=TRUE, prob=c(0.5, 0.3, 0.2))
#heres how the original data would have looked like
original_data = data.frame(a,b, other_damages_in_dollars, location, type_of_house)
Is there a way to add this information when you click on each node?
#visnet graph - is it possible to use the '$' operator to add these properties?
visNetwork(nodes, edges) %>% visIgraphLayout(layout = "layout_with_fr") %>%
%>% visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)visEvents(selectEdge = "function(properties) { alert(this.body.data.edges._data[properties.edges[0]].original_data$location); }") %>% visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)visEvents(selectEdge = "function(properties) { alert(this.body.data.edges._data[properties.edges[0]].original_data$type_of_house); }") %>% visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)visEvents(selectEdge = "function(properties) { alert(this.body.data.edges._data[properties.edges[0]].original_data$other_damage_in_dollars); }")
You don't need an event. This is built into many of the vis.js elements.
So, I'll start with designing the content of my tooltip. Of the 1000 rows you made of location, home types, and costs, I created a subset with the same number of rows as there are nodes. This is what will be shown in my tooltip.
newTitle = paste0("Location: ", toupper(location[1:nrow(nodes)]),
"<br>Home Type: ", type_of_house[1:nrow(nodes)],
"<br>Damage Related Costs: ",
sprintf("$%.2f", other_damages_in_dollars[1:nrow(nodes)]))
#check it; looks okay
Now I'm going to make my tooltips the titles of my nodes.
# replace the node titles:
nodes$title = newTitle
Call the network and click anywhere on the graph once to activate it. Now you just have to hover....(note the blue box, that means it's listening). There are a lot of nodes really close together, so there will be a bit of delayed response when you move from node to node.
You can get rid of the need to click to activate with visOptions(clickToUse = F).
visNetwork(nodes, edges) %>% visIgraphLayout(layout = "layout_with_fr")
FYI
I didn't go through all of the code in the original question; there's a lot! I'm going to include what I ran before creating my graph, so you know what was in and what was not. This code is not changed from your question.
library(igraph)
library(dplyr)
library(visNetwork)
#create file from which to sample from
x5 <- sample(1:100, 1100, replace=T)
#convert to data frame
x5 = as.data.frame(x5)
#create first file (take a random sample from the created file)
a = sample_n(x5, 1000)
#create second file (take a random sample from the created file)
b = sample_n(x5, 1000)
#combine
c = cbind(a,b)
#create dataframe
c = data.frame(c)
#rename column names
colnames(c) <- c("a","b")
#create graph
graph <- graph.data.frame(c, directed=F)
graph <- simplify(graph)
fc <- fastgreedy.community(graph)
V(graph)$community <- fc$membership
nodes <- data.frame(id = V(graph)$name, title = V(graph)$name, group = V(graph)$community)
nodes <- nodes[order(nodes$id, decreasing = F),]
edges <- get.data.frame(graph, what="edges")[1:2]
#add some information corresponding to the original data
other_damages_in_dollars <- rnorm(1000,104,9)
location <- c("canada","usa")
location <- sample(location, 1000, replace=TRUE, prob=c(0.3, 0.7))
type_of_house <- c("single","townhome", "rental" )
type_of_house<- sample(type_of_house , 1000, replace=TRUE, prob=c(0.5, 0.3, 0.2))
#heres how the original data would have looked like
original_data = data.frame(a,b, other_damages_in_dollars, location, type_of_house)

R igraph cluster nodes with the same colour (feature)

# 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

Setting subgraph/cluster attributes in Rgraphviz

I want to plot a graph via Rgraphviz but I can't handle the design attributes of the clusters that I set.
There are similar questions already on SO and elsewhere but none has a real minimal working example and none of them is answered. So I want to try to ask a complete question to receive a complete answer. As an introduction to the package, I read the paper "How To Plot A Graph Using Rgraphviz" by Gentry, Gentleman, and Huber.
My example network:
library(Rgraphviz)
set.seed(123)
V <- letters[1:6]
M <- 1:4
g1 <- randomGraph(V, M, 0.2)
If I want to plot it, I can easily give it some attributes via a list:
attributes <- list(node = list(shape = "rectangle", fixedsize = FALSE),
graph = list(layout = "dot", bgcolor = "transparent"))
plot(g1, attrs = attributes )
Plotting it via plot(g1) gives the following result:
Now I want to define two clusters/subgraphs. This can be done this way:
sg1= subGraph(c("a", "e", "f"), g1)
sg2= subGraph(c("b", "c", "d"), g1)
subGList <- vector(mode = "list", length = 2)
subGList[[1]] <- list(graph = sg1, cluster = TRUE)
subGList[[2]] <- list(graph = sg2, cluster = TRUE)
Plotting the graph again now including a subGlist argument:
plot(g1, attrs = attributes , subGList = subGList)
So, obviously, there has been a change in the setting and even though it would be convenient having the clusters a little bit more separated, the result is ok.
Now if I want to define cluster-specific styles or try to have them framed, I start having problems. According to page 4 of the mentioned introductory paper one can simply add an element called attrs to the sublists of subGlist.
To my understanding, it should work this way:
subGList[[1]] <- list(graph = sg1,
cluster = TRUE,
attrs = c(fontcolor = "red"))
plot(g1, attrs = attrs, subGList = subGList)
Unfortunately, it doesn't. As mentioned, I would like to frame my clusters (similar to this SO post) but as I can't even handle the fontcolors of the clusters, I think I make a somehow more fundamental mistake.
My complete code:
library(Rgraphviz)
set.seed(123)
V <- letters[1:6]
M <- 1:4
g1 <- randomGraph(V, M, 0.2)
attributes <- list(node = list(shape = "rectangle", fixedsize = FALSE),
graph = list(layout = "dot", bgcolor = "transparent"))
#plot(g1, attrs = attributes )
sg1= subGraph(c("a", "e", "f"), g1)
sg2= subGraph(c("b", "c", "d"), g1)
subGList <- vector(mode = "list", length = 2)
subGList[[1]] <- list(graph = sg1, cluster = TRUE)
subGList[[2]] <- list(graph = sg2, cluster = TRUE)
#plot(g1, attrs = attributes , subGList = subGList)
subGList[[1]] <- list(graph = sg1,
cluster = TRUE,
attrs = c(fontcolor = "red"))
plot(g1, attrs = attrs, subGList = subGList)
I hope someone can help! Thank you

How to construct bipartite graphs using igraph? [duplicate]

This question already has an answer here:
How to create a bipartite network in R with igraph or tnet
(1 answer)
Closed 5 years ago.
I need to create a bipartite graph for consumer-brand relationships.
This is my example data:
datf <- data.frame(Consumers = c("A", "B", "C", "D", "E"),
Brands = c("Costa", "Starbucks", "Cafe2U", "Costa", "Costa"))
The following code gives me a network. But I am not sure how I can add a node type attribute to label consumers and brands:
library(igraph)
dat=read.csv(file.choose(),header=TRUE)
el=as.matrix(dat)
el[,1]=as.character(el[,1])
el[,2]=as.character(el[,2])
g=graph.edgelist(el,directed=FALSE)
I would like to create a bipartite graph with edges that connect each consumer with the brand they like. Ideally, the nodes will be labeled with text.
Could you show me how to do this using library(igraph)?
This resource at Shizuka Lab is really useful for exploring bipartite networks in R with igraph. In short:
library(igraph)
# Your matrix containing consumer choice by brands
m = matrix(data = sample(0:1, 25, replace = TRUE), nrow = 5, ncol = 5)
colnames(m) = c("A", "B", "C", "D", "E")
rownames(m) = c("Costa", "Starbucks", "Cafe2U", "Petes", "Philz")
# Convert it to a bipartitie network
bg = igraph::graph.incidence(m)
bg
# See the vertex attributes
V(bg)$type
V(bg)$name
# Plot the network
shape = ifelse(V(bg)$type, "circle", "square") # assign shape by node type
col = ifelse(V(bg)$type, "red", "yellow") # assign color by node type
plot(bg, vertex.shape = shape, vertex.color = col)
Gives:

Show edge attributes as label with igraph

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.

Resources