如何让ggplot2的geom_text/geom_label自动继承主题规范?兼容ggrepel
哈哈,这个需求太懂了——谁想每次画geom_text都手动抄一遍主题里的字体、颜色参数啊?而且还要兼容ggrepel,确实得找个一劳永逸的办法。下面几个方案亲测好用:
方案1:全局更新geom默认参数(推荐,一劳永逸)
这个方法通过update_geom_defaults()把主题里的样式同步给geom_text和geom_text_repel,之后所有相关图层都会自动继承,不用再重复设置。
步骤很简单:
- 先定义你的主题,设置好
axis.text或者base_family这类样式 - 提取主题里的文本参数
- 更新
geom_text和geom_text_repel的默认值
示例代码:
library(ggplot2) library(ggrepel) # 第一步:自定义主题,设置axis.text的样式 my_custom_theme <- theme_minimal() + theme( axis.text = element_text( family = "Georgia", # 字体 face = "italic", # 字体样式 colour = "#2c3e50", # 颜色 size = 12 # 字号 ) ) # 第二步:提取主题里axis.text的参数 axis_text_settings <- my_custom_theme$axis.text text_defaults <- list( family = axis_text_settings$family, face = axis_text_settings$face, colour = axis_text_settings$colour, size = axis_text_settings$size ) # 第三步:更新geom_text和geom_text_repel的全局默认 update_geom_defaults("text", text_defaults) update_geom_defaults("text_repel", text_defaults)
之后画图就完全不用手动设置文本参数了:
ggplot(mtcars, aes(wt, mpg, label = rownames(mtcars))) + geom_point(color = "#e74c3c") + geom_text() + # 自动继承axis.text的样式 geom_text_repel(data = subset(mtcars, mpg > 25)) + # ggrepel也完美兼容 my_custom_theme
如果想让文本继承主题的base_family(而不是单独的axis.text),只需要把提取的对象换成my_custom_theme$text就行,因为base_family是存在于主题的text元素里的。
方案2:自定义专属geom(灵活可控)
如果你不想全局修改所有geom的默认值,只想在特定图表里用这个样式,可以自定义一个专属的geom函数,每次需要的时候调用就行:
# 自定义继承axis.text样式的geom_text geom_text_axis <- function(...) { # 获取当前主题的axis.text设置 axis_text <- theme_get()$axis.text # 调用原生geom_text并传入主题参数 geom_text( family = axis_text$family, face = axis_text$face, colour = axis_text$colour, size = axis_text$size, ... # 保留原生geom_text的其他参数 ) } # 同理给ggrepel做一个 geom_text_repel_axis <- function(...) { axis_text <- theme_get()$axis.text geom_text_repel( family = axis_text$family, face = axis_text$face, colour = axis_text$colour, size = axis_text$size, ... ) }
使用的时候直接替换成自定义的geom:
ggplot(mtcars, aes(wt, mpg, label = rownames(mtcars))) + geom_point() + geom_text_axis() + # 自动用axis.text的样式 geom_text_repel_axis(data = subset(mtcars, mpg > 25)) + my_custom_theme
方案3:直接在geom里引用主题参数(临时应急)
如果只是临时画一张图,不想改全局也不想写自定义函数,可以直接在geom_text里调用主题的参数:
ggplot(mtcars, aes(wt, mpg, label = rownames(mtcars))) + geom_point() + geom_text( family = my_custom_theme$axis.text$family, face = my_custom_theme$axis.text$face, colour = my_custom_theme$axis.text$colour, size = my_custom_theme$axis.text$size ) + my_custom_theme
这个方法虽然直观,但每次都要写一堆参数,适合临时用用。
内容的提问来源于stack exchange,提问作者chamaoskurumi
相关产品推荐
相关产品推荐

