Visualizing relation between two objects using R and export to HTML - r

I am using R to visualize relation between, say, 5-6 different nodes. Now, a graph is probably the best way to do it. The issue is, the edges are way too many. There can be a hundred edges between two vertexes. That makes the graph look very clumsy. I want the edge name to be displayed. With a hundred edge name being displayed, they overlap over each other and hence not comprehensible.
So, I have two questions-
Is there any other way in which I can represent the data? Some kind of chart probably?
I want to export the final output to HTML, which uses d3.js or any other similar library, keeping the edge name and a few other similar information intact. What will be the best plugin to use in that case?
I am using the igraph library to create the graph in R.
I also tried using the networkD3 library to export it to an HTML and make it interactive.
graph <- graph.data.frame(edges, directed = TRUE, vertices = vertex)
plot(graph, edge.label = E(graph)$name)
wc <- cluster_walktrap(graph)
members <- membership(wc)
graph_d3 <- igraph_to_networkD3(graph, group = members)
graph_forceNetwork <- forceNetwork(Links = graph_d3$links, Nodes = graph_d3$nodes,
Source = 'source',
Target = 'target',
NodeID = 'name',
Group = 'group',
zoom = TRUE,
fontSize = 20)
Right now, it is a graph with only two vertex and about 60-70 edges between them. So, I did not use any particular layout.

Related

plotting the most represented node in my igraph object in R

I have the fblog data set that is about french political party blogs.and is an object of igraph
I just want to plot the most represented party(node) in my the set
I used degree as below,
but now I dont know how to use it to plot it
I want just to show 20 of most important party(nodes) in my graph and plot them.
I hope you can help me
deg_g <-sort(igraph::degree(fblog, mode = "all", normalized = T),decreasing = TRUE)
class(deg_g)
UU<-deg_g[1:20]
In order to get the subgraph, you need to know which nodes have the highest degree, not what their degree is. Once you have that, you can just use induced_subgraph.
library(igraph)
library(sand)
data(fblog)
fblog = upgrade_graph(fblog)
DEG <-order(igraph::degree(fblog, mode = "all", normalized = T),
decreasing = TRUE)
HighDeg = induced_subgraph(fblog, DEG[1:20])
plot(HighDeg)
I am sure that you can layout the graph to make it prettier, but this is the subgraph that you requested.

How to retain the general shape of a network in igraph?

I currently have a network graph in igraph with which I am running simulations to see how the frequency of traits change over time like so:
g <- erdos.renyi.game(1000, 1/1000)
V(g)$nice <- sample(c(0, 1), vcount(g), replace = TRUE, prob = c(0.1, 0.9)
Following this I have a working code that modifies the the network across several "turns". The problem arises when I graph the network. I initially graph the network at t = 0 and once more at t = 20 or so to compare the two and see how they have changed. However, the location of the nodes have changed from the initial to the final. Is there a way that I can retain the location of the nodes in the actual graph? (i.e. so that node 4 will remain at some coordinate (a, b) despite changes in the network)
You can repeat the same layout by using the layout argument to plot. First, you create a layout using one of the many layout_ arguments, then just call plot specifying the layout. If you plot again with the same layout, the nodes will be in the same place.
LO_FR = layout_with_fr(g)
plot(g, layout=LO_FR, vertex.size=4, vertex.label=NA,
main="layout_with_fr")
LO_N = layout_nicely(g)
plot(g, layout=LO_N, vertex.size=4, vertex.label=NA,
main="layout_nicely")
Type help(package=igraph) and then scroll down to the functions whose names start with layout_. Try several and pick one that you like.

R d3 network graph - stop animation

I have plotted a network graph using d3 library but as the number of nodes grow, animation takes a huge performance toll. For analytics, I do not need good UI but something quick
Question: How do I stop the real-time simulation and yet still enable manipulation of the graph?
Working Code Example
require(igraph)
require(networkD3)
# Use igraph to make the graph and find membership
karate <- make_graph("Zachary")
wc <- cluster_walktrap(karate)
members <- membership(wc)
# Convert to object suitable for networkD3
karate_d3 <- igraph_to_networkD3(karate, group = members)
# Create force directed network plot
forceNetwork(Links = karate_d3$links, Nodes = karate_d3$nodes,
Source = 'source', Target = 'target', NodeID = 'name',
Group = 'group')
Visual Output:

Automatically curving an arc when it is overlapping with another one

I am automatically generating graphs whose nodes need to be in fixed positions. For example:
There is actually an arc from node V4 to node V16, but we annot see it because there are also arcs from V4 to V10 and from V10 to V16.
Note that both the nodes and the arcs are generated automatically, and that the positions may vary, so I would need an automated way to curve arcs that are hidden behind other arcs.
Also note that none of these solutions are valid: igraph: Resolving tight overlapping nodes ; Using igraph, how to force curvature when arrows point in opposite directions. The first one simply places de nodes in a certain way, but my nodes need to be fixed. The second one simply deals with pairs of nodes that have two arcs connecting them going in the opposite direction.
UPDATE: The construction of the graph is the result of the learning process of the graph that forms a Bayesian Network using bnlearn library, so I am not very sure how could I produce a reproducible example. The positions of the nodes are fixed because they represent positions. I actually need some magic, some kind of detection of overlapping arcs: If two arcs overlap, curve one of them slightly so that it can be seen. I know from the linked questions that curving an arc is an option, so I thought maybe this kind of magic could be achieved
One solution would be to use the qgraph package. In the example below it automatically curves the bidirectional edges:
library(igraph)
library(qgraph)
# the raster layout
layout <- cbind(1:3, rep(1:3, each = 3))
# fully connected network
adj <- matrix(1, 9, 9)
# plot directed and undirected network
layout(matrix(1:2, 1, 2))
qgraph(adj, layout = layout, directed = FALSE, title = "undirected")
qgraph(adj, layout = layout, directed = TRUE, title = "directed") # automatically curves the bidirectional arrows
To convert an igraph object to something qgraph can use, all you need is an edgelist or adjacency matrix:
g <- make_ring(9)
edgeList <- do.call(rbind, igraph::get.adjedgelist(g))
qgraph(edgeList)
If you also want to include the axes, you can do so using axis() since qgraph uses base graphics. However, you probably have to tinker with par() as well to make it look nice.

(igraph) Grouped layout based on attribute

I'm using the iGraph package in R to layout a network graph, and I would like to group the vertex coordinates based on attribute values.
Similar to the answered question How to make grouped layout in igraph?, my question differs in that the nodes needn't be grouped by a community membership that was derived from a community detection algorithm.
Rather, I want to layout with groups based on attribute values that are known in advance for each vertex.
For example, if each vertex has an attribute "Master.Org", and there are ~10 to ~20 distinct values for Master.Org, then how can I layout the graph such that all vertices within the same Master.Org are grouped ?
Thanks!
Additional Detail
In fact, two separate attributes provide nested levels of grouping.
My goal is to layout a graph object such that the "Master.Org" and "Org.Of" values are grouped together in their XY coordinates on the graph.
For example, each node will belong to an "Org.Of". And there can be multiple "Org.Of" values within the "Master.Org".
Thoughts ?
Thanks!
While this question is rather old, it is a reasonable question and deserves an answer.
No data was provided so I will generate an arbitrary example.
library(igraph)
set.seed(1234)
G = erdos.renyi.game(20, 0.25)
V(G)$Group1 = sample(3,20, replace=TRUE)
plot(G, vertex.color=rainbow(3, alpha=0.4)[V(G)$Group1])
Without doing anything, the Group is ignored.
Now, we need to create a layout that will plot nodes
in the same group close together. We can do this by creating
a graph with the same nodes, but with additional links between
nodes in the same group. The within-group links will be given
a high weight and the original links will be given a small weight.
This will cluster nodes in the same group. We then apply the
layout to plotting the original graph, without the extra links.
They were just to get a good layout.
G_Grouped = G
E(G_Grouped)$weight = 1
## Add edges with high weight between all nodes in the same group
for(i in unique(V(G)$Group1)) {
GroupV = which(V(G)$Group1 == i)
G_Grouped = add_edges(G_Grouped, combn(GroupV, 2), attr=list(weight=5))
}
## Now create a layout based on G_Grouped
set.seed(567)
LO = layout_with_fr(G_Grouped)
## Use the layout to plot the original graph
plot(G, vertex.color=rainbow(3, alpha=0.4)[V(G)$Group1], layout=LO)
If you want to go beyond this to have multiple levels of grouping, just add additional links with appropriate weights to connect the subgroups too.

Resources