不使用R Markdown如何获得与其效果一致的ggplot平滑绘图输出
问题描述
我正在尽可能优化ggplot的绘图效果,使用R Markdown绘图时,输出的线条极其平滑:
但使用标准R(仍在RStudio中运行,该环境可能对结果产生影响)生成相同图表时,输出效果如下:
(当前示例中效果差异可能不够明显,但实际使用时抖动的线条往往会非常粗糙,锯齿感明显。)
我已经附上了绘图的最小可复现示例(MWE),不确定是否需要补充R Markdown的相关设置,我的配置非常基础,没有特殊修改。代码如下:
if (!require("pacman")) install.packages("pacman") pacman::p_load(tidyverse, dplyr, ggplot2) x <- 0:10 demand <- function(x) 10 - x supply <- function(x) 1 + x ggplot(data.frame(x = c(0:10)), aes(x)) + scale_x_continuous(limits = c(0, 10.5), expand = c(0, 0), breaks = seq(0, 10, 1)) + scale_y_continuous(limits = c(0, 10.5), expand = c(0, 0), breaks = seq(0, 10, 1)) + labs(x = "Q", y = "P") + stat_function(aes(x), fun = supply, size = 1) + # supply function stat_function(aes(x), fun = demand, size = 1)
由于一些原因,我不想每次生成图表都使用R Markdown,请问是否有方法可以在常规R运行环境下获得同样高质量的平滑绘图输出?
解决方案
- 调整RStudio预览设备的抗锯齿设置
打开RStudio的「工具」→「全局选项」→「常规」→「图形」,将图形后端切换为AGG,抗锯齿级别选择高,重启RStudio后预览面板的绘图就会开启抗锯齿,和R Markdown输出的平滑度接近。 - 导出时选择高画质输出参数
优先选择矢量格式(PDF、SVG、EPS)导出,这类格式是无损的,无论放大多少倍都不会出现锯齿,示例代码如下:
# 先把绘图结果存为变量p p <- ggplot(data.frame(x = c(0:10)), aes(x)) + scale_x_continuous(limits = c(0, 10.5), expand = c(0, 0), breaks = seq(0, 10, 1)) + scale_y_continuous(limits = c(0, 10.5), expand = c(0, 0), breaks = seq(0, 10, 1)) + labs(x = "Q", y = "P") + stat_function(fun = supply, size = 1) + stat_function(fun = demand, size = 1) # 导出为PDF矢量图 ggsave("smooth_plot.pdf", p, device = cairo_pdf, width = 6, height = 6) # 导出为SVG矢量图,需先安装svglite包 ggsave("smooth_plot.svg", p, device = svglite::svglite, width = 6, height = 6)
如果需要导出位图(PNG、JPG),可以使用ragg包的AGG设备,调高DPI并开启抗锯齿,输出画质远高于默认的位图设备:
# 先安装ragg包:install.packages("ragg") ggsave("smooth_plot.png", p, device = ragg::agg_png, dpi = 300, width = 6, height = 6, antialias = "subpixel")
- 增加函数采样点密度
你用到的stat_function默认采样点数量是101,对于非线性函数可以手动调大n参数,增加采样点让线条更顺滑:
stat_function(fun = supply, size = 1, n = 1000)
- 配置全局默认设备(可选)
如果想让所有绘图默认都用高画质输出,可以把以下代码加入你的.Rprofile配置文件,之后无需每次手动指定参数:
options( device = function(...) ragg::agg_png(..., res = 150, antialias = "subpixel"), ggsave.device = function(...) ragg::agg_png(..., dpi = 300, antialias = "subpixel") )
内容的提问来源于stack exchange,提问作者542goweast
相关产品推荐
相关产品推荐

