如何为shadowtext::element_shadowtext设置背景色与半径参数
可行解决方法
shadowtext包自带的element_shadowtext未开放bg.color、bg.r参数,是因为主题元素的编写逻辑没有把这两个参数透传给底层渲染,有两种成熟方案可以实现需求,不需要依赖不符合要求的其他包:
方案1:扩展原生element_shadowtext补全参数
直接重写element_shadowtext构造函数和对应的grob渲染方法,把缺失的两个参数加进去,用法和原生主题元素完全一致,不需要改动原有绘图逻辑:
# 重写element_shadowtext构造函数,新增bg.color、bg.r入参 element_shadowtext <- function(family = NULL, face = NULL, colour = NULL, size = NULL, hjust = NULL, vjust = NULL, angle = NULL, lineheight = NULL, color = NULL, margin = NULL, debug = NULL, inherit.blank = FALSE, bg.colour = NULL, bg.color = NULL, bg.r = 0.1) { if (!is.null(color)) colour <- color if (!is.null(bg.color)) bg.colour <- bg.color structure( list( family = family, face = face, colour = colour, size = size, hjust = hjust, vjust = vjust, angle = angle, lineheight = lineheight, margin = margin, debug = debug, inherit.blank = inherit.blank, bg.colour = bg.colour, bg.r = bg.r ), class = c("element_shadowtext", "element_text", "element") ) } # 重写对应渲染逻辑,透传背景参数到shadowtextGrob element_grob.element_shadowtext <- function(element, label = "", x = NULL, y = NULL, family = NULL, face = NULL, colour = NULL, size = NULL, hjust = NULL, vjust = NULL, angle = NULL, lineheight = NULL, margin = NULL, margin_x = FALSE, margin_y = FALSE, bg.colour = NULL, bg.r = NULL, ...) { if (is.null(label)) return(ggplot2::zeroGrob()) vj <- ggplot2:::calc_element("vjust", element, vjust) hj <- ggplot2:::calc_element("hjust", element, hjust) angle <- ggplot2:::calc_element("angle", element, angle) bg.colour <- if(is.null(bg.colour)) element$bg.colour else bg.colour bg.r <- if(is.null(bg.r)) element$bg.r else bg.r shadowtext::shadowtextGrob( label, x, y, default.units = "native", hjust = hj, vjust = vj, rot = angle, gp = grid::gpar( col = ggplot2:::calc_element("colour", element, colour), fontsize = ggplot2:::calc_element("size", element, size) * .pt, fontfamily = ggplot2:::calc_element("family", element, family), fontface = ggplot2:::calc_element("face", element, face), lineheight = ggplot2:::calc_element("lineheight", element, lineheight) ), bg.colour = bg.colour, bg.r = bg.r, ... ) }
使用时直接在主题配置里传参即可,和geom_shadowtext的参数逻辑完全一致:
data <- data.frame(ID= c("A", "B", "C"), Value =c(1.5,2,1.75)) library(ggplot2) library(shadowtext) ggplot(data, aes(x=ID, y=Value)) + geom_col() + theme(axis.text.x = element_shadowtext( color="black", bg.color = "white", bg.r = 0.2 ), axis.title.x = element_blank())+ geom_shadowtext(aes(label=Value), y=1, hjust=0.5, bg.color="white", bg.r=0.2, color = "black")
方案2:手动绘制轴标签,零代码侵入
如果不想修改包的原生函数,可以直接隐藏默认坐标轴文本,用geom_shadowtext手动绘制轴标签,所有参数都可以直接复用,不需要额外写自定义函数:
ggplot(data, aes(x=ID, y=Value)) + geom_col() + # 隐藏默认x轴文本,预留底部边距 theme(axis.text.x = element_blank(), axis.title.x = element_blank(), plot.margin = margin(b=15)) + # 柱形上的标注文本 geom_shadowtext(aes(label=Value), y=1, hjust=0.5, bg.color="white", bg.r=0.2, color = "black") + # 手动添加x轴标签,y值设为坐标轴下限以下的位置 geom_shadowtext(aes(label=ID, y=-0.08), bg.color="white", bg.r=0.2, color = "black") + # 关闭裁剪避免标签被截断,调整y轴范围适配 coord_cartesian(ylim = c(0, 2.2), clip = "off")
这个方案的优点是不需要修改任何包内逻辑,所有shadowtext支持的参数都可以直接使用;缺点是需要根据图形尺寸手动调整标签的y轴位置和底部边距。
内容的提问来源于stack exchange,提问作者Beni
相关产品推荐
相关产品推荐

