You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ggplot保存PDF无法保留全部元素的问题排查与解决求助

问题:ggplot保存PDF时元素缺失,PNG显示正常

问题描述

使用ggplot绘制密度图,保存为PNG格式显示正常,但保存为PDF格式时部分元素缺失。尝试了RStudio面板保存、ggsave()、pdf()+print()+dev.off()三种方法,在Mac预览和Adobe中打开PDF均异常。

运行环境:R 4.3.0,RStudio 2023.09.1+494,macOS 14.0

示例代码:

ggplot(mtcars, aes(x=mpg, group=cyl, fill=as.factor(cyl))) +
  geom_density(adjust=1.5, alpha=.6, col= "black") +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        panel.border = element_blank(),
        text=element_text(family="times", size=20),
        axis.text=element_text(family="times", size=20),
        legend.text=element_text(family="times", size=20),
        strip.text=element_text(family="times", size=20),
        legend.position = "none")+
  scale_x_continuous(expand=c(0,0)) +
  scale_y_continuous(expand=c(0,0))

正常PNG效果:
正常PNG图表

PDF异常效果:
缺失元素的PDF图表

原因分析

核心问题是字体嵌入与PDF渲染的兼容性:

  • macOS 14.0(Sonoma)的系统字体机制更新,导致R默认PDF设备无法正确处理"times"字体的嵌入,尤其是当图形包含半透明(alpha=.6)元素时,字体渲染冲突会导致图形元素缺失。
  • 默认PDF设备对字体和透明度的组合支持有限,无法正确渲染带透明度的填充元素。

解决方案

方法1:使用Cairo PDF设备替代默认设备

Cairo对字体嵌入和透明度的支持更稳定,直接替换保存方式:

# 用cairo_pdf直接保存
cairo_pdf("plot.pdf", width=8, height=6)
print(last_plot())
dev.off()

# 或用ggsave指定device参数
ggsave("plot.pdf", plot=last_plot(), device=cairo_pdf, width=8, height=6)

方法2:修复字体设置

避免使用系统识别模糊的"times"字体名,改用明确的字体名称,比如"Times New Roman":

# 修改主题中的字体设置
ggplot(mtcars, aes(x=mpg, group=cyl, fill=as.factor(cyl))) +
  geom_density(adjust=1.5, alpha=.6, col= "black") +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        panel.border = element_blank(),
        text=element_text(family="Times New Roman", size=20),
        axis.text=element_text(family="Times New Roman", size=20),
        legend.text=element_text(family="Times New Roman", size=20),
        strip.text=element_text(family="Times New Roman", size=20),
        legend.position = "none")+
  scale_x_continuous(expand=c(0,0)) +
  scale_y_continuous(expand=c(0,0))

# 配合cairo_pdf保存
ggsave("plot.pdf", device=cairo_pdf)

方法3:用showtext包统一字体渲染

如果上述方法无效,使用showtext包强制字体嵌入,解决跨设备字体渲染问题:

install.packages("showtext")
library(showtext)

# 加载Times字体(根据系统路径调整)
font_add("times", "Times New Roman.ttf")
showtext_auto() # 自动启用showtext渲染

# 绘制并保存
p <- ggplot(mtcars, aes(x=mpg, group=cyl, fill=as.factor(cyl))) +
  geom_density(adjust=1.5, alpha=.6, col= "black") +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        panel.border = element_blank(),
        text=element_text(family="times", size=20),
        axis.text=element_text(family="times", size=20),
        legend.text=element_text(family="times", size=20),
        strip.text=element_text(family="times", size=20),
        legend.position = "none")+
  scale_x_continuous(expand=c(0,0)) +
  scale_y_continuous(expand=c(0,0))

ggsave("plot.pdf", p, device="pdf")

验证方法

保存PDF后,用Adobe Acrobat打开,检查文档属性中的字体是否已正确嵌入:

  1. 打开PDF → 文件 → 属性 → 字体
  2. 确认目标字体显示为“已嵌入”或“子集嵌入”

内容的提问来源于stack exchange,提问作者grace.cutler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:07:44