如何在ggplot2中自定义圆矩组合点形状并支持angle参数
实现ggplot2自定义圆形+矩形组合形状(支持角度旋转)
要实现可像geom_point()一样调用的自定义形状,我们可以通过自定义grob组合 + 扩展ggplot2的Geom层来实现,同时支持angle参数的映射。以下是完整实现步骤:
1. 定义生成组合形状的grob函数
用grid包的基础grob组合圆形和矩形,通过rotateGrob实现角度旋转:
library(grid) library(ggplot2) circle_rect_grob <- function(x, y, size = 1, angle = 0, colour = "black", fill = NA, alpha = 1, stroke = 0.5) { # 转换形状尺寸为grid单位 size_unit <- unit(size, "char") # 创建圆形grob circle <- circleGrob( x = x, y = y, r = size_unit / 2, gp = gpar( col = alpha(colour, alpha), fill = alpha(fill, alpha), lwd = stroke ) ) # 创建矩形grob(尺寸为圆形直径的2/3,中心对齐) rect_width <- size_unit * 2/3 rect_height <- size_unit * 1/3 rect <- rectGrob( x = x, y = y, width = rect_width, height = rect_height, gp = gpar( col = alpha(colour, alpha), fill = alpha(fill, alpha), lwd = stroke ) ) # 围绕中心旋转矩形 rotated_rect <- rotateGrob(rect, angle = angle, x = x, y = y) # 组合两个grob gTree(children = gList(circle, rotated_rect)) }
2. 创建自定义Geom层
继承GeomPoint,重写draw_panel方法调用自定义grob,并添加angle到美学映射:
GeomCircleRect <- ggproto( "GeomCircleRect", GeomPoint, # 新增angle到支持的美学参数 aes_params = c(GeomPoint$aes_params, "angle"), draw_panel = function(data, panel_params, coord, na.rm = FALSE) { # 转换坐标系统 coords <- coord$transform(data, panel_params) # 生成组合形状grob circle_rect_grob( x = coords$x, y = coords$y, size = coords$size, angle = coords$angle, colour = coords$colour, fill = coords$fill, alpha = coords$alpha, stroke = coords$stroke ) }, # 设置默认参数 default_aes = aes( shape = 19, colour = "black", size = 2, fill = NA, alpha = 1, stroke = 0.5, angle = 0 ) )
3. 创建便捷调用函数
封装成和geom_point()用法一致的函数:
geom_circle_rect <- function(mapping = NULL, data = NULL, stat = "identity", position = "identity", na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, ...) { layer( geom = GeomCircleRect, mapping = mapping, data = data, stat = stat, position = position, show.legend = show.legend, inherit.aes = inherit.aes, params = list(na.rm = na.rm, ...) ) }
4. 使用示例
现在可以像调用geom_point()一样使用,还能映射angle参数:
# 基础使用 ggplot(mtcars, aes(wt, mpg)) + geom_circle_rect(fill = "red", colour = "black", size = 3, angle = 45) # 映射angle参数到数据变量 ggplot(mtcars, aes(wt, mpg, angle = hp, size = disp, fill = cyl)) + geom_circle_rect(colour = "black") + scale_fill_viridis_c() + theme_minimal()
关键说明
- 形状调整:若要修改矩形与圆形的相对大小/位置,直接调整
circle_rect_grob里的rect_width、rect_height参数即可 - 旋转逻辑:
rotateGrob以形状中心为旋转点,确保旋转时整体形状保持居中 - 参数兼容:完全继承
geom_point()的所有参数,新增angle支持数值或变量映射
内容的提问来源于stack exchange,提问作者Bruno Mioto
相关产品推荐
相关产品推荐

