ggplot,R 中的可视化神器。ggplot 的出图美观漂亮、简约大气,自定义程度极高,图中的所有元素均可以修改,没错,是所有元素。

但是在使用过程中,有个问题一直困扰着我,输出的图分辨率多大合适?字体多大比较合适?还有一点比较疑惑的,ggplot 里面的字体大小不知道用的什么单位,px?pt?或者是其他?好像还存在着某种换算关系,比如设置 size=20,输出 PDF 查看字体大小并不是 20 磅,要大一些。

问题描述

画个图,字体:20,横线宽度:3,点大小:3

1
2
3
4
5
ggplot(women, aes(height,y=weight))+geom_point()+
annotate(label='Font Size=20',geom = 'text',x = 64,y=160, size=20)+
geom_hline(yintercept = 140, size=3)+annotate(label='size=3',geom = 'text',x = 60,y=142)+
annotate(geom = 'point', x=60, y=150, size=3)
ggsave('1.pdf')

用 Ai 打开看字体大小和线条粗细

字体:57pt,线条描边:6.4pt,点:7.11pt + 0.71pt/2 = 7.465pt(总大小),跟设置值好像毫无关联啊……

image-20220617140424633

再看官网element_blank() element_rect() element_line() element_text()size 参数的描述

size

Line/border size in mm; text size in pts.

线/描边单位是毫米,文本是点

试一下看看,把坐标轴文本大小设置为 20

1
2
3
4
5
ggplot(women, aes(height,y=weight))+geom_point()+
annotate(label='Font Size=20',geom = 'text',x = 64,y=160, size=20)+
geom_hline(yintercept = 140, size=3)+annotate(label='size=3',geom = 'text',x = 60,y=142)+
annotate(geom = 'point', x=60, y=150, size=3)+
theme(axis.title = element_text(size = 20))

Ai 里面显示文本确实是 20pt,看来在 ggplot 中单位并不都是 pt,不使用 element_xxx() 类型设置的元素存在一个换算关系。

image-20220617141503261

解决方法

文本和线宽

简书上有一个帖子的方法挺有用的,简单来说就是不用 element_xxx() 设置元素时,size 参数都要除以某个比例才能转换成熟悉的 pt。

1
2
3
4
5
6
ggplot2::.pt
# [1] 2.845276
f.pt <- .pt
l.pt <- .pt*72.27/96
l.pt
# [1] 2.141959

文本的 size 参数要 ÷ f.pt,线的 size 参数要 ÷ l.pt,就可以把各种大小都换算成 pt 单位了。

1
2
3
ggplot(women, aes(height,y=weight))+geom_point()+
annotate(label='Font Size=20',geom = 'text',x = 64,y=160, size=20/f.pt)+
geom_hline(yintercept = 140, size=3/l.pt)+annotate(label='size=3',geom = 'text',x = 60,y=142)

非常完美!

image-20220617143109076

关于点的大小,比较复杂,因为点有不同的形状,通过 shape 参数控制。

ggplot 中不同点的形状

形状 21-24 含有描边,这时候点的大小由两个参数控制, size 参数控制填充大小,stroke 参数控制描边大小,单位均为毫米

描边和填充大小

输出 PDF 大小

具体还是要根据期刊的要求来,毕业论文里面我的设置是图 10cm×8cm 左右,文字大小 9pt 左右,线宽 0.75pt 左右,打印出来清晰美观,比较合适。

代码如下:

1
2
3
4
5
6
7
8
mytheme <- theme(axis.title = element_text(size = 9),
axis.text = element_text(size = 8, colour = 'black'),
axis.ticks = element_line(colour = 'black', size = 0.75/l.pt),
axis.line = element_line(lineend = "square", size = 0.75/l.pt),
panel.grid = element_blank(),
panel.background = element_blank(),
)
ggsave('1.pdf', width = 10, height = 8, units = 'cm')

绘图的时候直接 +mytheme 就可以了。

最后贴一张效果图

效果图

参考

Aesthetic specifications • ggplot2 (tidyverse.org)

R语言学习笔记 – ggplot2 绘图指定字体大小与线宽 - 简书 (jianshu.com)

5.3 Using Different Point Shapes | R Graphics Cookbook, 2nd edition (r-graphics.org)