I'm plotting a directed network from an edge list, and have so far created a tree-like plot (see here).
It looks good, however all of the nodes are too close together. I would like to keep the shape of it while spreading out the nodes more. Here's the code that got me the image above:
library(igraph)
ref <- read.csv("my-ref.csv", as.is=T)
el <- graph.data.frame(ref, directed=T)
lay.kk <- layout.kamada.kawai(el, niter=1000, kkconst=50)
plot.igraph(el, lay=lay.kk, vertex.label=NA, vertex.size=2, vertex.color="black")
I've tried messing around with kkconst, but that doesn't seem to change anything. Any tips are greatly appreciated!
The Kamada-Kawai layout does not really work well for disconnected graphs because the disconnected components tend to "drift away" from each other. Since igraph scales the entire plot to fit within the canvas, the farther the components are from each other, the closer the nodes will be within the components. Try the Fruchterman-Reingold layout instead.
As Tamás suggested, you might get better results with layout.fruchterman.reingold(). You can fine tune this function with the following parameters:
require(igraph)
g <- erdoss.renyi.game(n = 100, p.or.m = 0.04)
lo <- layout.fruchterman.reingold(g, repulserad = vcount(g)^2.8,
area = vcount(g)^2.3, niter = 1000)
plot(g, layout = lo, vertex.size = 3, vertex.frame.color = NULL,
vertex.label.dist = 0.5, vertex.label.cex = 0.7, edge.width = 0.5)
These values resulted a low overlap, clear but compact layout for me. Try to change them a bit, to see their effect on the layout. Those parameters I set for plot() also help to make the visualization more clear.
There is a similar question here to which I have posted the following answer
Option 1: make the vertices smaller
node.size= c(10,10,10)
plot(net, vertex.size=node.size*0.25)
Option 2 (in case the distances between the vertices are not important to you):
# Use the tkplot option to edit your graph in GUI
tkplot (net)
tkplot GUI will allow you to interactively change the layout types.
Note: tkplot outputs the graph as eps. If you want to edit it further or export it to pdf I suggest using inkscape (I use it for all my graph editing - just save the graph as pdf in RStudio and edit it in inkscape).
For the case of eps if you are on a windows machine you will need to tweak inkscape to open this format. A very short and simple process which is detailed here:
Related
I want to produce a circular cladogram in R. I was trying out the ape package and could produce something like this:
plot(tree,'f', use.edge.length=F)
Now I am not really happy with how the edges look like here. I tried out the evolview webserver, which got me something like this, which looks much nicer, especially regarding the edges.
Can anyone suggest other R packages or a different approach with the ape package, to get similar results to the evolview tree?
The two main differences that stand out to me are the size of the labels and the relative lengths of the edges.
Label size can be controlled using the cex graphical parameter (using par(), or as a parameter to plot()).
Uniform edge length can be added to the tree by replacing the $edge.length property with a vector of 1s:
par(cex = 0.8) # Shrink text
tree$edge.length <- rep_along(1, tree$edge.length)
plot(tree, 'f', use.edge.length = TRUE)
i'm now using lesmis.gml to do network analysis homework.
I can't adjust graph node's distance: there's more than 70 nodes and the nodes are too close.
graph is variable g and g2.
graph looks weird like this.(image)
here's my code using R.
I tried to use Gephi, but my laptop doesn't run it well. It shuts off.
install.packages('igraph')
install.packages('statnet')
library('igraph')
library('statnet')
g<-read.graph("lesmis.gml", format=c("gml"))
g
graph.density(g)
igraph::degree(g,mode="out")
plot(g)
vcount(g)
centralization.degree(g)
V(g)$size<-igraph::degree(g)*5
plot(g)
clo<-igraph::closeness(g)
clo
clo.score<-round((clo-min(clo))*length(clo)/max(clo))+1
clo.colors<-rev(heat.colors(max(clo.score)))
V(g)$color<-clo.colors[clo.score]
plot(g)
btw<-igraph::betweenness(g)
btw
btw.score<-round(btw)+1
btw.score
btw.colors<-rev(heat.colors(max(btw.score)))
V(g)$color<-btw.colors[btw.score]
plot(g)
clusters(g)
clusters(g)$csize
cliques(g)
sapply(cliques(g), length)
largest_cliques(g)
cliques(g)
sapply(cliques(g),length)
a<-largest_cliques(g)
a
clique1<-a[[1]]
g2<-induced.subgraph(graph=g,vids=clique1)
plot(g2)
vcol<-rep("grey80",vcount(g))
vcol[unlist(largest_cliques(g))]<-"gold"
plot(as.undirected(g),vertex.lavel=V(g)$name, vertex.color=vcol)
windows()
I have two suggestions. Before presenting them, I will set up the basics so that what I do is (mostly) repeatable. This is just a streamlined version of what you had in your code, with a change to the vertex size as you had it.
library(igraph)
g<-read.graph("temp/lesmis.gml", format=c("gml"))
V(g)$size<-igraph::degree(g)/2
btw<-igraph::betweenness(g)
btw.score<-round(btw)+1
btw.colors<-rev(heat.colors(max(btw.score)))
V(g)$color<-btw.colors[btw.score]
I think that this is what #nhl was suggesting. There are quite a few layout functions in igraph. Just try a bunch of them and see what looks good. I kind of liked the large graph layout.
set.seed(1234)
LO_LGL = layout_with_lgl(g)
plot(as.undirected(g), layout=LO_LGL, margin=c(-0.25,-0.25))
Once you get something that is pretty close, you might try using tkplot which will allow you to select nodes and move them around to make the graph more readable.
tkplot(as.undirected(g), layout=LO_LGL)
I used the previous layout as a starting place and adjusted the vertices by hand to make the graph clearer. It is not perfect, but you can see some of the communities.
I am using R igraph package to display gene networks. The plot on Rstudio is like this (I can't post image because I am new user and don't have enough reputation, sorry about that):
R igraph on preview
Now I want to draw this on file to clearly see the changes and there is always an issue on vertices near margin side like this:
part of output pdf file
My code is as follows`
pdf("graph.pdf",width = 20, height = 10)
par(mar = c(9,9,9,9))
plot(finalnet, edge.arrow.size=0.1, edge.curved=FALSE,vertex.size= 3, margin = -0.5)
dev.off()
Update: I have tried square layout and the problem persists, here is my plotting object and square plot.
square plot
rda file for my igraph object
Can anyone give me an suggestion how to solve this issue? To whole net is about 170 vertices but I don't know why it cannot be displayed on output file well. I have tried different plot options in mai, mar but this seems to fail.
The reason you are getting this behavior is because you are specifying margin in your plot call. margin=-0.5 is telling R to extend the plot 0.5 units past the graphics device dimensions, below are three examples:
Your original plotting call, notice the clipping
pdf("withMargin.pdf")
par(mar=c(9,9,9,9))
plot(g, margin=-0.5)
dev.off()
Without the call to par, problem still presists but now youuse the entire dimension of the graphics device.
png("withoutPar_Margin.png")
#par(mar=c(9,9,9,9))
plot(g, margin=-0.5)
dev.off()
Lastly, removing the margin in plot
png("withoutplotMargin.png")
par(mar=c(9,9,9,9))
plot(g)
dev.off()
You're specifying a rectangular size for what looks like a square object. Try a square size, as in
pdf("graph.pdf")
This will use the defaults, which are square.
But, it's hard to know for sure since you haven't given us the object to troubleshoot for you.
I have the following sample data (total of 700 observations), code and resulting graph in R. How can I modify the code to make the graph more readable?
The data can be read as "V1 is a follower of V2", on down.
g <- graph.data.frame(graph_subset, directed=TRUE)
plot(g, edge.width=E(g)$weight)
I agree with #MrFlick's comment and #zx8754. You could also try modifying the layout:
plot(g, mode = "circle", edge.width=E(g)$weight)
There are several modes to modify the layout: circle, eigen, random, spring, kamadakawi and so on. Kamadakawi is my best option.
Hope it helps!
Try:
plot(g, layout=layout_in_circle, edge.width=E(g)$weight)
this must change the layout, you can also modify the size of vertex with vertex.cex=1.5 and hide the labels with displaylabels=F. There are more commands, find them in the tutorial that #zx8754 mentioned, section 4.2.
I am trying to build graphs using tree-like data, where nodes typically split into >2 edges. I have tried various layouts, and I see that the layout.reingold.tilford parameter will generate tree-like graphs with non-bifurcating data. However the outputs are not particularly attractive. I would rather use something like the layout.lgl or layout.kamada.kawai since these produce more radial structures. I cannot see how to change the parameters in R such that these trees have no overlapping edges though. Is this possible?
I imported a simple data file in Pajek format, with 355 nodes and 354 edges. I'm currently printing it using:
plot.igraph(g,vertex.size=3,vertex.label=NA,layout=layout.lgl)
This gives me an output like this, which is nice, but still has overlapping edges. I have read that you can manually fix this using tkplot, or another program like cytoscape, however I have quite a few of these to build, and the size of them makes manual correction a hassle.
Many thanks.
Just want to add a comment but my rep is too low. The method that #bdemarest posted does not work on igraph version > 0.7. The newer version does not support the area parameter, so I cannot get the same effect. And getting the old version to build took me a while, so I though I'd share some insights. You can manually install igraph 0.7 from source if you download it from igraph nightly builds. On my machine (Mac OS 10.10), I encountered some problems building it, due to gfortran, so I found this link that solved the problem. Hope that helps anyone who wants to create similar graphs in R.
You may want to try layout.fruchterman.reingold(). It seems to do a good job keeping the edges from crossing. I've tested it with a 355 node version of the barabasi graph suggested by #Tamás.
library(igraph)
g = barabasi.game(355, directed=FALSE)
png("plot1.png", height=6, width=12, units="in", res=200)
par(mfrow=c(1, 2))
plot.igraph(g,vertex.size=3,vertex.label=NA,
layout=layout.fruchterman.reingold(g, niter=10000))
mtext("layout.fruchterman.reingold, area = vcount^2", side=1)
plot.igraph(g,vertex.size=3,vertex.label=NA,
layout=layout.fruchterman.reingold(g, niter=10000, area=30*vcount(g)^2))
mtext("layout.fruchterman.reingold, area = 30 * vcount^2", side=1)
dev.off()
layout.reingold.tilford has a parameter called circular. Setting this to TRUE will convert the final layout into a radial one by treating the X coordinate as the angle (after appropriate rescaling) and the Y coordinate as the radius. Ironically enough, this does not guarantee that there will be no edge crossings in the end, but it works nicely if your subtrees are not exceedingly wide compared to the rest of the graph:
> g <- barabasi.game(100, directed=F)
> layout <- layout.reingold.tilford(g, circular=T)
> plot(g, layout=layout)