ggplot2图表注释字体与其他文本不一致问题求助
解决ggplot2注释文本与图表其他文本样式不一致的问题
我明白你遇到的痛点——好不容易调好了轴标题和图例的字体大小,结果注释文本还是格格不入。让我们一步步解决这个问题:
问题根源
ggplot2里的文本参数单位和继承逻辑容易踩坑:
theme()中element_text()的size参数单位是点(pt),这也是你设置轴标题、图例文本时用的20的单位。- 而
annotate("text")(包括geom_text())的size参数单位是毫米(mm),所以你用20 / .pt是正确的转换逻辑,但光转大小还不够,字体家族的统一也很关键。
另外,你之前的代码里没有统一全局文本样式,各个element_text()可能默认使用了不同的字体(比如系统衬线字体),而你给注释指定了sans,这就导致了视觉上的差异。
解决方案:统一全局文本样式
我们可以先定义一套全局文本样式,让所有元素(轴标题、图例、注释)都继承这套样式,再对特殊位置的元素做微调:
# 定义全局统一的文本样式:大小20pt,无衬线字体,黑色 global_text <- element_text(size = 20, family = "sans", colour = "black") plot <- ggplot(material) + theme_void() + scale_color_hue() + aes(x = strain, y = stress, colour = type, group = type) + geom_xspline(size = 1, spline_shape = 0.5) + labs(x = "Strain (in/in)", y = "Stress (ksi)", color = element_blank()) + theme( legend.position = "bottom", legend.box.background = element_rect(colour = "black", size = 0.5), # 复用全局样式,只调整轴标题的位置属性 axis.title.y = global_text %+replace% list(angle = 90, vjust = -22, hjust = 0.55), axis.title.x = global_text %+replace% list(vjust = 7, hjust = 0.6), axis.text.y = element_blank(), axis.text.x = element_blank(), legend.text = global_text, legend.box.margin = margin(10,10,10,10), legend.spacing.x = unit(0, 'cm'), # 设置全局文本,让所有未单独指定的文本元素都继承这个样式 text = global_text ) + scale_y_continuous(trans = "reverse") + scale_x_continuous(trans = "reverse") + geom_vline(aes(xintercept = 0), size = 0.3) + geom_hline(aes(yintercept = 0), size = 0.3) + geom_segment(aes(x = 0, y = 0, xend = -0.0009226, yend = 0), size = 1) + geom_segment(aes(x = -0.0009226, y = 0, xend = -0.0011707, yend = -0.94), size = 1) + geom_segment(aes(x = 0, y = -4.958, xend = -0.00333, yend = -4.958), size = 0.6, linetype = "dotted", colour = "black") + geom_segment(aes(x = -0.00333, y = 0, xend = -0.00333, yend = -4.958), size = 0.6, linetype = "dotted", colour = "black") + geom_segment(aes(x = -0.0024, y = 0, xend = -0.0024, yend = -4.958), size = 0.6, linetype = "dotted", colour = "black") + geom_segment(aes(x = -3.75E-03, y = 0, xend = -3.75E-03, yend = -4.6011), size = 0.6, linetype = "dotted", colour = "black") + geom_segment(aes(x = -0.0046736, y = 0, xend = -0.0046736, yend = -4.6011), size = 0.6, linetype = "dotted", colour = "black") + # 现在注释可以直接使用转换后的size,和全局字体保持一致 annotate("text", x = 0, y= -0.94, label = "f'", size = 20 / .pt, family = "sans")
更省心的优化:设置geom_text默认样式
如果你经常需要添加注释,可以提前设置geom_text的默认参数,这样后续的annotate就不用重复指定size和family了:
# 给所有text类几何对象设置默认样式 update_geom_defaults("text", list(size = 20 / .pt, family = "sans", colour = "black")) # 之后annotate就可以简化成: annotate("text", x = 0, y= -0.94, label = "f'")
这样所有文本元素就会完全统一,不会再出现样式脱节的情况了。
内容的提问来源于stack exchange,提问作者Maral Dorri
相关产品推荐
相关产品推荐

