如何在ggplot2中将填充图例设为涂抹状而非预定义形状?
自定义ggplot2填充图例为污渍/涂抹状图形
首先是用户提供的数据集:
df <- structure(list(Fruit = c("Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe", "Apple", "Orange", "Graphe"), value1 = c(9L, 27L, 21L, 13L, 30L, 8L, 29L, 24L, 25L, 10L, 20L, 5L, 1L, 28L, 11L, 3L, 4L, 12L, 26L, 14L, 19L, 16L, 6L, 17L, 23L, 7L, 18L, 22L, 15L, 2L), value2 = c(11L, 6L, 1L, 30L, 2L, 12L, 20L, 27L, 3L, 10L, 26L, 4L, 7L, 8L, 15L, 5L, 17L, 21L, 18L, 9L, 19L, 16L, 24L, 14L, 23L, 22L, 29L, 13L, 25L, 28L), Var = c("A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "A", "B", "B", "A", "A", "A", "B", "B", "A", "A", "A", "B", "B", "A", "B", "A", "B", "A", "A", "A")), class = "data.frame", row.names = c(NA, -30L))
用户的原始绘图代码:
library(ggplot2) ggplot(df, aes(value1, value2, fill = Var, shape = Fruit)) + geom_point(color = "black", size = 2.5) + scale_shape_manual(values = 21:23) + guides(fill = guide_legend("Identity", override.aes = list(shape = 21)))
完全可以通过key_glyph参数结合自定义函数实现污渍/涂抹状的填充图例,具体步骤如下:
- 自定义污渍形状的key glyph函数
利用grid包的绘图工具生成不规则的污渍图形,这里通过随机多边形模拟自然的污渍边缘:
library(grid) # 自定义污渍图例生成函数 glyph_stain <- function(data, params, size) { # 生成10个随机角度的边缘点 n_points <- 10 angles <- seq(0, 2*pi, length.out = n_points) # 随机半径,控制污渍的不规则程度 radii <- runif(n_points, min = 0.3, max = 0.5) * size x <- radii * cos(angles) y <- radii * sin(angles) # 创建多边形图形对象 polygonGrob( x = x, y = y, gp = gpar( fill = data$fill, col = data$colour %||% "black", lwd = data$size %||% 0.5 ) ) }
- 在绘图中应用自定义图例
将自定义函数传入guide_legend的key_glyph参数,替换fill图例的默认形状:
ggplot(df, aes(value1, value2, fill = Var, shape = Fruit)) + geom_point(color = "black", size = 2.5) + scale_shape_manual(values = 21:23) + guides( fill = guide_legend( title = "Identity", key_glyph = glyph_stain # 使用自定义污渍图例 ), shape = guide_legend(title = "Fruit") )
额外调整建议
- 若想让污渍更自然,可增加
n_points的数值(比如15),或调整radii的范围(比如min=0.2, max=0.6); - 也可以用
pathGrob结合贝塞尔曲线绘制更流畅的不规则边缘,或者导入外部污渍SVG转为Grob对象使用。
内容的提问来源于stack exchange,提问作者benson23
相关产品推荐
相关产品推荐

