如何自定义ggplot2绘图系统的函数(4)——*_panel和*_group方法的区别


专注系列化、高质量的R语言教程


*_panel*_group方法在功能上属于同一类方法。如前面推文中使用到的compute_group(统计变换)和draw_panel(几何图形),分别存在替代方法compute_paneldraw_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()
862405afa8da422e26f68b83b8e820e8.png

解决办法是在定义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()
a4bca3d242f60fb9848d9252aa2e5cc4.png

如下是输出的绘图数据集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)语句后,groupPANEL变量产生了区别。draw_panel根据PANEL变量进行分组,draw_group方法根据group变量进行分组,因此只有后者能真正实现分组效果。

加入其他分组参数:

ggplot(data, aes(x, y)) +
  geom_stepline(aes(group = z, col = z)) +
  geom_point()
7ec4425d533068f8a1efa24ab96c43de.png

如果删去group = z语句也没有分组效果(暂时不清楚原因):

ggplot(data, aes(x, y)) +
  geom_stepline(aes(col = z)) +
  geom_point()
1ebdd00624ff0dd04f57704e4a421483.png

再来看看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
6347a927eb08da6a6ae910e61601043d.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值