R输出图形中的字体设置及pdf图形中的中文支持


title: "Rfonts"
author: "wintryheart"
date: "2020/7/6"
output:
html_document:
toc: true
toc_depth: 2
number_sections: true


一、grDevices包的windowsFonts()函数

在windows系统中,字体集(the font family)只是一个字符串名字,必须映射到特定的windows字体。

windowsFonts()函数,用于列出已有的字体映射,或定义新的映射。 windowsFont()函数用于创建一个新的映射。

系统自带字体

系统自带三个字体集名:"serif""sans""mono" ,分别映射"TT Times New Roman""TT Arial""TT Courier New"

> windowsFonts()

$serif
[1] "TT Times New Roman"

$sans
[1] "TT Arial"

$mono
[1] "TT Courier New"

这些映射只有在字体风格(font face)是 1 (plain), 2 (bold), 3 (italic), or 4 (bolditalic)时使用。

示例1:自带help文件

windowsFonts(JP1 = windowsFont("MS Mincho"),
             JP2 = windowsFont("MS Gothic"),
             JP3 = windowsFont("Arial Unicode MS"))
plot(1:10)
text(5, 2, "\u{4E10}\u{4E00}\u{4E01}", family = "JP1")
text(7, 2, "\u{4E10}\u{4E00}\u{4E01}", family = "JP1", font = 2)
text(5, 1.5, "\u{4E10}\u{4E00}\u{4E01}", family = "JP2")
text(9, 2, "\u{5100}", family = "JP3")

windowsFonts()支持中文名的字体文件。

windowsFonts( A=windowsFont("华文彩云"),
                         B=windowsFont("华文仿宋"),
                         C=windowsFont("华文行楷")) 
plot(1:10,1:10,type="n")
text(2,10,"华文彩云",family="A")
text(2,8,"华文仿宋",family="B")
text(2,6,"华文行楷",family="C")

二、sysfont包添加新字体

  1. 下载字体解压到windows系统的字体文件夹中(C:/Windows/Fonts)。

  2. 在字体文件夹中找到想要的字体,右键-属性,查看文件名。例如:楷书的名字为“simkai.ttf”

  3. 使用font_add()函数添加字体。只能加载英文名的字体,不支持加载中文名的字体。

> font_add("simkai","simkai.ttf")

> font.families()
[1] "sans"         "serif"        "mono"         "wqy-microhei" "simkai"  

三、showtext包渲染字体

showtext的主要优点是用户可以使用任何受支持的字体文件进行文本渲染,文本符号将被转换为多边形(用于矢量图形)或光栅图像(用于位图和屏幕图形),从而在所有平台上生成与设备无关的输出。如果您想在图形设备中使用非标准字体,此函数将非常有用。

加载和停止字体渲染

#使用showtext渲染字体
showtext _begin()

#关闭showtext字体渲染
showtext_end()

示例:

为了使pdf()更好地显示特定的中文字体,需要调用中文字体文件,比如windows系统自带的simkai.ttf

## 1、打开图形设备
pdf("showtext-ex1.pdf")

## 画图
plot(1, type = "n")

## 打开showtext,并画上中文字符。
showtext_begin()
text(1, 1.2, intToUtf8(c(21315, 31179, 19975, 36733)), cex = 5)

## 使用另一种中文字体
if("simkai.ttf" %in% font_files()) font_add("simkai", "simkai.ttf")
text(1, 0.8, intToUtf8(c(19968, 32479, 27743, 28246)),
     cex = 5, family = "simkai")
     
## 关闭showtext
showtext_end()

## 关闭图形设备
dev.off()

四、Cairo包

Cairo初始化一个新的图形设备,使用Cairo图形库进行渲染。当前能制作高质量的PNG、JPEG、TIFF位图文件、具有嵌入式字体的高分辨率PDF文件、SVG图形和PostScript文件。它还提供了X11和Windows交互式图形设备。不像其他设备,它支持所有的图形功能,包括alpha混合,抗锯齿等。

Cairo(width = 640, height = 480, file="", type="png", pointsize=12, 
      bg = "transparent", canvas = "white", units = "px", dpi = "auto",
      ...)

CairoPNG(filename = "Rplot%03d.png", width = 480, height = 480,
         pointsize = 12, bg = "white",  res = NA, ...)
CairoJPEG(filename = "Rplot%03d.jpeg", width = 480, height = 480,
         pointsize = 12, quality = 75, bg = "white", res = NA, ...)
CairoPDF(file = ifelse(onefile, "Rplots.pdf","Rplot%03d.pdf"),
         width = 6, height = 6, onefile = TRUE, family = "Helvetica",
         title = "R Graphics Output", fonts = NULL, version = "1.1",
         paper = "special", encoding, bg, fg, pointsize, pagecentre)      

CairoX11()、CairoPNG()、CairoPDF()、CairoPS()和CairoSVG()是Cairo的简易的基本类型包装器,它们使用的参数与所替换的设备(如X11()、png()、pdf()等)相同。
但由于Cairo()更灵活,建议使用Cario()函数。

Cairo.capabilities()查看cairo包支持的所有图形格式。

> Cairo.capabilities()
   png   jpeg   tiff    pdf    svg     ps    x11    win raster 
  TRUE  FALSE  FALSE   TRUE   TRUE   TRUE  FALSE   TRUE   TRUE 

示例1:简例

# very simple KDE
Cairo(600, 600, file="plot.png", type="png", bg="white")
plot(rnorm(4000),rnorm(4000),col="#ff000018",pch=19,cex=2) # semi-transparent red
dev.off() # creates a file "plot.png" with the above plot

Cairo(600, 600, file="plot.pdf", type="pdf", dpi=100)  #pdf必须设置合适的dpi,不可过大。
plot(rnorm(4000),rnorm(4000),col="#ff000018",pch=19,cex=2)
dev.off()

注:Cairo()输出pdf图形时,必须设置dpi。没有经验,不好设置。在上例中dpi不能大于100。不如直接使用CairPDF()更为方便,不用设置dpi。

示例2:简单中文支持

library("Cairo")
font_add("yahei","msyh.ttc")  #加载**微软雅黑**字体


CairoPDF()
plot(1:10,1:10,type="n")
text(5,5, "微软雅黑", family="yahei")
dev.off()

示例3:ggplot2输出pdf的中文支持

library("ggplot2")  
library("Cairo")
font_add("yahei","msyh.ttc")  #加载**微软雅黑**字体

CairoPDF("mm.pdf", width=12, height=9)  #自定义宽高。

setwd("c:/users/wintryheart/desktop")
load("enroll1.Rdata")
showtext_begin()
ggplot(data = enroll1, aes(x=year, y=lowest, group=class))+
  geom_line(aes(color=class))+
  geom_point()+
  geom_text(aes(year, lowest,label=lowest),position = position_dodge(0), vjust=-0.5)+
  labs(x="", y="", title="苏州大学历年招生分数线(2015-2019)", caption="数据来源:中国教育在线(https://gkcx.eol.cn/school/118/provinceline)")+
  facet_wrap(.~subject)+
  theme_bw()+
  theme(legend.title=element_blank(), 
    legend.text=element_text(size=10, family="simkai"), 
    legend.position="top", 
    plot.title=element_text(hjust=0.5,family="yahei" ),
    plot.caption=element_text(hjust=0,family="yahei"),
    strip.text=element_text(size=14, family="simkai"))
showtext_end()
dev.off()

注:

  • 如果不加showtext_begin()和showtext_end(),能正常显示中文,但所有字体为系统默认字体。
  • 如果加showtext_begin()和showtext_end(),则能正常显示各部分自定义的中文字体。

五、小结

  • 如果是plot()作图,不需要输出pdf,使用windowsFonts(),即可以提供中文字体(font family)支持。
  • 如果是plot()作图,需要输出pdf,使用showtext和Cairo,都可以提供中文字体支持。
  • 如果是ggplot2作图,需要输出pdf,需要结合showtext和Cairo,共同提供中文字体支持。
  • font_add()添加字体。只能加载英文名的字体,不支持加载中文名的字体。
  • windowsFonts()映射字体,支持中文名的字体。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354