Reputation: 2222
I'm using the igraph
package to plot a graph that I've created in yEd. This is a graph that should be overlaid on a geographical map, so one of the first things I want to do is alter the vertex coordinates so that they match up to the longitude/latitude they represent. (simple linear transformation)
I tried to use the GraphML format, but iGraph cannot read GraphML files that were created by yEd, so instead, I've saved the graph as a GML file. The structure of the vertex information looks like this:
node [
id 0
label ""
graphics [
x 2181.0043222386603
y 1463.6747524664843
w 5.2609883750396875
h 5.1510372122625085
type "ellipse"
raisedBorder 0
fill "#FFCC00"
outline "#000000"
]
]
As you can see, the coordinates are saved within the graphics
attribute. This is valid GML syntax (at least AFAIK). However, this attribute is not processed correctly by load_graph
and iGraph doesn't save the coordinates. When I try to extract the vertex attributes, I get this:
> vertex_attr(g) %>% glimpse()
# List of 3
# $ id : num [1:73] 0 1 2 3 4 5 6 7 8 9 ...
# $ label : chr [1:73] "" "" "" "" ...
# $ graphics: chr [1:73] "qÑÜ\020#8" "qÑÜ\020#8" "qÑÜ\020#8" "qÑÜ\020#8" ...
How do I load the graph correctly, including x and y coordinates?
Upvotes: 0
Views: 1108
Reputation: 1115
From the igraph
documentation, it says that one of the limitations of its ability to read GML
is
Only node and edge attributes are used, and only if they have a simple type: integer, real or string. So if an attribute is an array or a record, then it is ignored. This is also true if only some values of the attribute are complex.
Which is probably why it's having trouble with the graphics
attribute. igraph
should be able to read graphml
format as well, but likely encounters the same hurdle.
Luckily, if you need a workaround, GML
is a human-readable format that is relatively easy to parse out. If you just need the x
and y
coordinates of the nodes for example, you can do something like this:
library(igraph)
g <- read_graph("graph.gml", format="gml") #create graph object
z <- readLines("graph.gml") #create character vector from which to grep out attributes
id <- trimws(gsub("\t\tid\t", " ", z[grep("\t\tid\t", z)])) #retrive node ids
totid <- length(id) #retrieve number of nodes
#grep for and extract x and y attributes
xcor <- as.numeric(trimws(gsub("\t\t\tx\t", " ", z[grep("\t\t\tx\t", z)])))[1:totid]
ycor <- as.numeric(trimws(gsub("\t\t\ty\t", " ", z[grep("\t\t\ty\t", z)])))[1:totid]
#edges will also have x and y coordinates, so we need to index by the number of nodes
#add attributes back into graph object
g <- set.vertex.attribute(g, "x", value=xcor)
g <- set.vertex.attribute(g, "y", value=ycor)
Upvotes: 1