Align vertex size with label size in igraph

I am trying to build small networks using igraph in R. Each vertex in the network has a name that is equivalent to its label. I would like each vertex to have a rectangular symbol that is large enough to match its label.

This is my main inspiration.

Map of hyperboria

What is the best way to do this with igraph?

Edit: additional information

Code here

jsonToNM <- function(jfile, directed=TRUE) { # Requires "rjson" and "igraph" nm.json <- fromJSON(file=jfile) nm.graph <- c() # Initialize the graph with the given nodes g <- graph.empty(n=length(nm.json), directed=directed) # Add their names V(g)$name <- names(nm.json) V(g)$label <- V(g)$name # Now, add the edges for(i in 1:length(nm.json)) { # If the node has a "connected" field, # then we note the connections by looking # the names up. if(length(nm.json[[i]]$connected > 0)) { for(j in 1:length(nm.json[[i]]$connected)) { # Add the entry g <- g + edge(names(nm.json)[i], nm.json[[i]]$connected[j]) } } } plot(g, vertex.label.dist=1.5) } 

And the current output is below.

current output

My goal is to place labels inside the vertex graphical object and expand the width of the vertex to accommodate the label.

+4
source share
2 answers

Here is an example. Among some dirty tricks (i.e., Multiplying the vertex size by 200), the key must use two plot commands so that we can measure the width (and height) of the labels using strwidth() , after the size of the graph is set using the first (empty ) plot.

 library(igraph) camp <- graph.formula(Harry:Steve:Don:Bert - Harry:Steve:Don:Bert, Pam:Brazey:Carol:Pat - Pam:Brazey:Carol:Pat, Holly - Carol:Pat:Pam:Jennie:Bill, Bill - Pauline:Michael:Lee:Holly, Pauline - Bill:Jennie:Ann, Jennie - Holly:Michael:Lee:Ann:Pauline, Michael - Bill:Jennie:Ann:Lee:John, Ann - Michael:Jennie:Pauline, Lee - Michael:Bill:Jennie, Gery - Pat:Steve:Russ:John, Russ - Steve:Bert:Gery:John, John - Gery:Russ:Michael) V(camp)$label <- V(camp)$name set.seed(42) ## to make this reproducable co <- layout.auto(camp) plot(0, type="n", ann=FALSE, axes=FALSE, xlim=extendrange(co[,1]), ylim=extendrange(co[,2])) plot(camp, layout=co, rescale=FALSE, add=TRUE, vertex.shape="rectangle", vertex.size=(strwidth(V(camp)$label) + strwidth("oo")) * 100, vertex.size2=strheight("I") * 2 * 100) 

igraph vertex label width

Btw. this doesn't work very well with SVG graphics, because there is no way to measure the width of text from R, the SVG device only makes guesses.

+7
source

I know that this is not a direct answer to your question, but I would suggest using a different visualization tool. yEd is very good at adjusting the width of the nodes to the size of the label. You can also easily manipulate the visualization and export it to SVG for final polishing. It can be obtained for free from www.yworks.com (Disclaimer: I do not work there).

To export a graph in a well-readable format (yEd does not understand the ig gig format), use graphml:

 write.graph(graph, "test.graphml", format="graphml") 

Open it in yEd. Go to edit-> properties mapper and click on “new configuration (Node)” (green “plus” symbol, upper left). In the middle of the frame, in the "data source" section, find the name of your labels (there should be a "name"). In the middle tab under the name “map” select “label text” and in the right column leave “conversion” “Automatic”.

Now select “Tools” → “Fit” node for marking (the default parameters are suitable for the first attempt), and then select your favorite layout. You can export to various graphic formats, but as far as I know, all of them are implemented using raster-intermediate. This way I usually export SVG and do polishing in inkscape. If anyone knows a more efficient procedure for getting good mock graphs created in igraph, let me know.

0
source

All Articles