改变 iGraph 中图顶点的 X 和 Y 坐标
Alter X and Y coordinates of graph vertices in iGraph
我正在使用 igraph
包来绘制我在 yEd 中创建的图表。这是一个应该覆盖在地理地图上的图表,所以我要做的第一件事就是改变顶点坐标,使它们与它们所代表的 longitude/latitude 相匹配。 (简单的线性变换)
我尝试使用 GraphML 格式,但 iGraph 无法读取由 yEd 创建的 GraphML 文件,因此,我将图形另存为 GML 文件。顶点信息的结构如下所示:
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"
]
]
如您所见,坐标保存在 graphics
属性中。这是有效的 GML 语法(至少 AFAIK)。但是,load_graph
未正确处理此属性,iGraph 不保存坐标。当我尝试提取顶点属性时,我得到这个:
> 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ÑÜ0#8" "qÑÜ0#8" "qÑÜ0#8" "qÑÜ0#8" ...
如何正确加载图表,包括 x 和 y 坐标?
来自igraph
documentation,它表示其读取GML
能力的限制之一是
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.
这可能就是 graphics
属性出现问题的原因。 igraph
也应该能够读取 graphml
格式,但可能会遇到同样的障碍。
幸运的是,如果您需要解决方法,GML
是一种相对容易解析的人类可读格式。例如,如果您只需要节点的 x
和 y
坐标,您可以这样做:
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)
我正在使用 igraph
包来绘制我在 yEd 中创建的图表。这是一个应该覆盖在地理地图上的图表,所以我要做的第一件事就是改变顶点坐标,使它们与它们所代表的 longitude/latitude 相匹配。 (简单的线性变换)
我尝试使用 GraphML 格式,但 iGraph 无法读取由 yEd 创建的 GraphML 文件,因此,我将图形另存为 GML 文件。顶点信息的结构如下所示:
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"
]
]
如您所见,坐标保存在 graphics
属性中。这是有效的 GML 语法(至少 AFAIK)。但是,load_graph
未正确处理此属性,iGraph 不保存坐标。当我尝试提取顶点属性时,我得到这个:
> 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ÑÜ0#8" "qÑÜ0#8" "qÑÜ0#8" "qÑÜ0#8" ...
如何正确加载图表,包括 x 和 y 坐标?
来自igraph
documentation,它表示其读取GML
能力的限制之一是
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.
这可能就是 graphics
属性出现问题的原因。 igraph
也应该能够读取 graphml
格式,但可能会遇到同样的障碍。
幸运的是,如果您需要解决方法,GML
是一种相对容易解析的人类可读格式。例如,如果您只需要节点的 x
和 y
坐标,您可以这样做:
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)