I want to make a function which plots directed graphs with vertices aligned and adds some text below each vertex, i.e. something like the example plot below. The plotting function should be able to handle pie graphs as vertices, so I have used igraph
package in R.
adjm <- matrix(c(0,1,0,1,
0,0,1,1,
0,0,0,1,
0,0,0,0), nrow=4, byrow=TRUE)
g1 <- graph.adjacency(adjm, mode="directed")
values <- lapply(1:4, function(x) sample(1:4,4))
windows(width=7, height=3.5)
plot(g1, layout=layout.grid(g1, width=4),
vertex.shape="pie", vertex.pie=values,
vertex.pie.color=list(heat.colors(4)),
edge.curved=TRUE,
vertex.label=LETTERS[1:4], vertex.size=50,
vertex.label.dist=5, vertex.label.degree=pi/2,
edge.label=1:5, rescale=FALSE,
xlim=c(-0.2,3.5), ylim=c(0,0.5))
I have two problems.
Why is it that the longer the vertex label, the longer the distance to the vertex centre as in the following example? Can I force them to appear at the same level without manually finding and defining them the right distance?
windows(width=7, height=3.5)
plot(g1, layout=layout.grid(g1, width=4),
vertex.shape="pie", vertex.pie=values,
vertex.pie.color=list(heat.colors(4)),
edge.curved=TRUE,
vertex.label=c("A", "AA", "AAAA", "AAAAAA"), vertex.size=50,
vertex.label.dist=5, vertex.label.degree=pi/2,
edge.label=1:5, rescale=FALSE,
xlim=c(-0.2,3.5), ylim=c(0,0.5))
How to remove empty space when plotting aligned plots? If I make a horizontal graph it will be placed at the bottom of the window with a lot of empty space. The flatter the image, the smaller the graph, as in the third plot. (It seems that the size of the graph is determined such that the plot would fit in any position, vertical or horizontal.)
plot(g1, layout=layout.grid(g1, width=4),
vertex.shape="pie", vertex.pie=values,
vertex.pie.color=list(heat.colors(4)),
edge.curved=TRUE,
vertex.label=c("A", "AA", "AAAA", "AAAAAA"), vertex.size=20,
vertex.label.dist=2, vertex.label.degree=pi/2, edge.label=1:5)
I can write argument asp=0
to keep the vertices the right size in a flatter window but the automatic curvatures and the positions of the vertex labels change. I can manually tweak negative upper margin, label distances, and edge curvature, but of course this is not a solution for a generic function. The best result so far was the result of rescale=FALSE
as in the code for the first plot, but the edge curvatures are still too small and with larger vertices they get behind the vertices completely. (Also, the problem with varying vertex label distances still remains.) Direct use of autocurve.edges
is not giving me any curvature. Any ideas of what to try next?
To fix this, you might want to tweak the plot.igraph
function a little bit. To do this, you can experiment using trace(plot.igraph,edit=TRUE)
and modify the code of the function.
A few tips to get what you want: For the labels, line 319 of the function is:
y <- layout[, 2] + label.dist * sin(-label.degree) * (vertex.size + 6 * 8 * log10(nchar(labels) + 1))/200
So the y
placement of the labels is proportional to the number of characters of the label, just remove the log10(nchar(labels) + 1)
and the labels will stay at the same level.
For the size issue, if you want to keep rescale
, the y
position of the plot is defined line 55
layout <- layout.norm(layout, -1, 1, -1, 1)
You can change the third number to whatever you want and the plot will be higher (for example, layout <- layout.norm(layout, -1, 1, 0, 1) will center the vertexes on 0). You can also change the margins by changing the
par` settings. You could for example do:
oldMargins<-par("mar")
par(mar=c(10,4,4,4))
and after the plot par(mar=oldMargins)
This is the plot I get using this code after the adjustments:
I left the axes to make it easier to tweak, and removed the pies because no value was given in your post.
oldMargins<-par("mar")
par(mar=c(10,4,4,4))
plot(g1, layout=layout.grid(g1, width=4),
vertex.pie.color=list(heat.colors(4)),
edge.curved=TRUE,
vertex.label=c("A", "AA", "AAAA", "AAAAAA"), vertex.size=20,
vertex.label.dist=1, vertex.label.degree=pi/2, edge.label=1:5,axes=TRUE,
ylim=c(-0.5,0.5),xlim=c(-1,1))
par(mar=oldMargins)
When you restart R, any changes you made to the function will be removed, or you can use untrace
to go back to the original function. You can look at this post for more info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With