从 0.5.1 版本开始,igraph 在绘制图形时支持不同的顶点形状。
值
如果 shape
参数为 NULL
,shapes()
返回一个字符向量。它返回一个命名列表,其中包含名为“clip”和“plot”的条目,它们都是 R 函数。
add_shape()
返回 TRUE
,不可见。
shape_noclip()
返回其 coords
参数的相应列。
详细信息
在 igraph 中,顶点形状由两个函数定义:1) 提供有关形状大小的信息,用于剪裁边;2) 如果需要,绘制形状。在本文档页面的其余部分中,这些函数称为“形状函数”。第一个是剪裁函数,第二个是绘图函数。
剪裁函数具有以下参数
- coords
一个四列矩阵,包含
el
参数中提供的边列表的顶点的坐标。- el
一个两列矩阵,一些端点将被剪裁的边。它应具有与
coords
相同的行数。- params
这是一个可以调用的函数对象,用于查询顶点/边/绘图图形参数。该函数的第一个参数是“
vertex
”、“edge
”或“plot
”,以确定参数的类型,第二个参数是给出参数名称的字符串。例如params("vertex", "size")
。- end
字符串,给出将使用哪个端点。可能的值为“
both
”、“from
”和“to
”。如果为“from
”,则该函数应剪裁el
边列表中的第一列,“to
”选择第二列,“both
”选择两列。
剪裁函数应返回一个矩阵,该矩阵具有与 el
参数相同的行数。如果 end
为 both
,则该矩阵必须具有四列,否则为两列。该矩阵包含修改后的坐标,其中应用了剪裁。
绘图函数具有以下参数
- coords
顶点的坐标,一个两列矩阵。
- v
要绘制的顶点的 ID。它应与
coords
参数中的行数匹配。- params
与剪裁函数相同,请参见上文。
不使用绘图函数的返回值。
可以通过调用 shapes()
而不带参数或将 shape
参数设置为 NULL
来列出所有已安装的顶点形状的名称。如果给出了形状名称,则该形状的剪裁和绘图函数将在一个命名列表中返回。
add_shape()
可用于将新的顶点形状添加到 igraph。为此,必须给出新形状的剪裁和绘图函数。还可以列出绘图/顶点/边参数(在 parameters
参数中),剪裁和/或绘图函数可以使用这些参数。一个示例是一个通用的正多边形形状,它可以具有边数的参数。
shape_noclip()
是一个非常简单的剪裁函数,用户可以在其自己的形状定义中使用它。它不进行剪裁,边将绘制到列出的顶点位置坐标为止。
shape_noplot()
是一个非常简单(可能不是很有用)的绘图函数,它不绘制任何内容。
示例
# all vertex shapes, minus "raster", that might not be available
shapes <- setdiff(shapes(), "")
g <- make_ring(length(shapes))
set.seed(42)
plot(g,
vertex.shape = shapes, vertex.label = shapes, vertex.label.dist = 1,
vertex.size = 15, vertex.size2 = 15,
vertex.pie = lapply(shapes, function(x) if (x == "pie") 2:6 else 0),
vertex.pie.color = list(heat.colors(5))
)
# add new vertex shape, plot nothing with no clipping
add_shape("nil")
plot(g, vertex.shape = "nil")
#################################################################
# triangle vertex shape
mytriangle <- function(coords, v = NULL, params) {
vertex.color <- params("vertex", "color")
if (length(vertex.color) != 1 && !is.null(v)) {
vertex.color <- vertex.color[v]
}
vertex.size <- params("vertex", "size")
if (length(vertex.size) != 1 && !is.null(v)) {
vertex.size <- vertex.size[v]
}
symbols(
x = coords[, 1], y = coords[, 2], bg = vertex.color,
stars = cbind(vertex.size, vertex.size, vertex.size),
add = TRUE, inches = FALSE
)
}
# clips as a circle
add_shape("triangle",
clip = shapes("circle")$clip,
plot = mytriangle
)
plot(g,
vertex.shape = "triangle", vertex.color = rainbow(vcount(g)),
vertex.size = seq(10, 20, length.out = vcount(g))
)
#################################################################
# generic star vertex shape, with a parameter for number of rays
mystar <- function(coords, v = NULL, params) {
vertex.color <- params("vertex", "color")
if (length(vertex.color) != 1 && !is.null(v)) {
vertex.color <- vertex.color[v]
}
vertex.size <- params("vertex", "size")
if (length(vertex.size) != 1 && !is.null(v)) {
vertex.size <- vertex.size[v]
}
norays <- params("vertex", "norays")
if (length(norays) != 1 && !is.null(v)) {
norays <- norays[v]
}
mapply(coords[, 1], coords[, 2], vertex.color, vertex.size, norays,
FUN = function(x, y, bg, size, nor) {
symbols(
x = x, y = y, bg = bg,
stars = matrix(c(size, size / 2), nrow = 1, ncol = nor * 2),
add = TRUE, inches = FALSE
)
}
)
}
# no clipping, edges will be below the vertices anyway
add_shape("star",
clip = shape_noclip,
plot = mystar, parameters = list(vertex.norays = 5)
)
plot(g,
vertex.shape = "star", vertex.color = rainbow(vcount(g)),
vertex.size = seq(10, 20, length.out = vcount(g))
)
plot(g,
vertex.shape = "star", vertex.color = rainbow(vcount(g)),
vertex.size = seq(10, 20, length.out = vcount(g)),
vertex.norays = rep(4:8, length.out = vcount(g))
)