专注系列化、高质量的R语言教程
*_panel
和*_group
方法在功能上属于同一类方法。如前面推文中使用到的compute_group
(统计变换)和draw_panel
(几何图形),分别存在替代方法compute_panel
和draw_panel
。
上篇定义几何图形函数的代码如下:
library(ggplot2)
GeomStepLine <- ggproto("GeomStepLine", Geom,
required_aes = c("x", "y"),
default_aes = aes(size = 1.5, col = "black"),
draw_key = draw_key_path,
draw_panel = function(data, panel_params, coord, type) {
coords <- coord$transform(data, panel_params)
coords = coords[order(coords$x), ]
coords = data.frame(apply(coords, 2, rep, each =2))
n = dim(coords)[1]
if (type == 1) {coords$x = c(coords$x[2:n], NA)}
if (type == 2) {coords$y = c(coords$y[2:n], NA)}
coords = data.frame(coords[complete.cases(coords),])
print(coords)
grid::linesGrob(
x = coords$x,
y = coords$y,
gp = grid::gpar(lwd = coords$size,
col = coords$colour)
)
}
)
geom_stepline <- function(mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, type = 1, ...) {
layer(geom = GeomStepLine, mapping = mapping, data = data, stat = stat,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, type = type, ...))
}
使用aes(group = z)
语句进行分组绘图,但在这种情况下不会起作用:
## 示例数据
set.seed(0929)
data = data.frame(x = 1:10, y = rpois(10,5),
z = rep(1:2,5))
## 尝试分组绘图
ggplot(data, aes(x, y)) +
geom_stepline(aes(group = z)) +
geom_point()
解决办法是在定义GeomStepLine
对象时使用draw_group
方法替代draw_panel
方法:
GeomStepLine <- ggproto("GeomStepLine", Geom,
required_aes = c("x", "y"),
default_aes = aes(size = 1.5, col = "black"),
draw_key = draw_key_path,
draw_group = function(data, panel_params, coord, type) {
coords <- coord$transform(data, panel_params)
coords = coords[order(coords$x), ]
coords = data.frame(apply(coords, 2, rep, each =2))
n = dim(coords)[1]
if (type == 1) {coords$x = c(coords$x[2:n], NA)}
if (type == 2) {coords$y = c(coords$y[2:n], NA)}
coords = data.frame(coords[complete.cases(coords),])
print(coords)
grid::linesGrob(
x = coords$x,
y = coords$y,
gp = grid::gpar(lwd = coords$size,
col = coords$colour)
)
}
)
## 分组绘图
ggplot(data, aes(x, y)) +
geom_stepline(aes(group = z)) +
geom_point()
如下是输出的绘图数据集coords
(两种情况的coords
数据集基本类似):
## x y group PANEL size colour
## X1 0.04545455 0.61363636 1 1 1.5 black
## X1.1 0.14646465 0.61363636 1 1 1.5 black
## X2 0.14646465 0.72727273 2 1 1.5 black
## X2.1 0.24747475 0.72727273 2 1 1.5 black
## X3 0.24747475 0.38636364 1 1 1.5 black
## X3.1 0.34848485 0.38636364 1 1 1.5 black
## X4 0.34848485 0.72727273 2 1 1.5 black
## X4.1 0.44949495 0.72727273 2 1 1.5 black
## X5 0.44949495 0.04545455 1 1 1.5 black
## X5.1 0.55050505 0.04545455 1 1 1.5 black
## X6 0.55050505 0.84090909 2 1 1.5 black
## X6.1 0.65151515 0.84090909 2 1 1.5 black
## X7 0.65151515 0.95454545 1 1 1.5 black
## X7.1 0.75252525 0.95454545 1 1 1.5 black
## X8 0.75252525 0.38636364 2 1 1.5 black
## X8.1 0.85353535 0.38636364 2 1 1.5 black
## X9 0.85353535 0.72727273 1 1 1.5 black
## X9.1 0.95454545 0.72727273 1 1 1.5 black
## X10 0.95454545 0.50000000 2 1 1.5 black
可以看到,在加入aes(group = z)
语句后,group
和PANEL
变量产生了区别。draw_panel
根据PANEL
变量进行分组,draw_group
方法根据group
变量进行分组,因此只有后者能真正实现分组效果。
加入其他分组参数:
ggplot(data, aes(x, y)) +
geom_stepline(aes(group = z, col = z)) +
geom_point()
如果删去group = z
语句也没有分组效果(暂时不清楚原因):
ggplot(data, aes(x, y)) +
geom_stepline(aes(col = z)) +
geom_point()
再来看看ggplot2
包本身的geom_step()
函数的效果:
library(patchwork)
p1 = ggplot(data, aes(x, y)) +
geom_step(aes(group = z, col = z)) +
geom_point() +
guides(col = F)
p2 = ggplot(data, aes(x, y)) +
geom_step(aes(col = z)) +
geom_point() +
guides(col = F)
p1 + p2