RMarkdown中ggplot图表渲染失败:无法获取PNG资源求助
- 环境:Windows 10(build 19045),R 4.3.1,使用tidyverse、ggplot2、bookdown等包编写RMarkdown文档
- 现象:此前表格、图表均可正常生成,近期插入ggplot图表时出现无法获取PNG资源、连接被拒绝的报错;文档输出至网络驱动器路径,但使用
plotly::ggplotly转换图表可正常渲染 - 系统信息:
R version 4.3.1 (2023-06-16 ucrt) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 19045) ...(剩余系统信息省略)
- RMarkdown代码:
--- title: "Test" author: | | Author: Author Name | Unit: Unit | Email: email address | Github Handle: handle output: bookdown::html_document2: fig_caption: TRUE toc: true toc_depth: 3 toc_float: true number_sections: true knit: (function(inputFile, encoding) { out_dir <- '../Reports/'; rmarkdown::render(inputFile, encoding=encoding, output_file=file.path(dirname(inputFile), out_dir, "GGPLOT_TEST.html")) }) link-citations: true bibliographystyle: apalike --- ```{r setup, include = FALSE} knitr::opts_chunk$set( #echo = FALSE, collapse = TRUE, comment = "#>", root.dir = "f:/Crash Analysis/Vehicle_Design_and_Injury_Severity/" ) .libPaths("C:/Program Files/R/R-4.3.1/library") #library(xfun) library(bookdown) library(tidyverse) #For data wrangling library(ggplot2) library(scales) library(plotly)
test chart below
dat = mtcars #Make chart ################################## #Prepare data p = ggplot( dat, aes(x = mpg, y =wt)) + geom_line(aes(x = mpg, y =wt)) + geom_point(aes(x = mpg, y =wt)) + theme(plot.title = element_text(hjust = 0.5)) + theme(text = element_text(size = 16)) + guides(color=guide_legend(title="Body Type")) print(p)
- 报错信息:
[WARNING] Could not fetch resource http://wpdotfill09/R_VMP3_USERS/tdb069/Crash%20Analysis/Vehicle_Design_and_Injury_Severity/Reports/GGPLOT_TEST_files/figure-html/ggplot-1.png: HttpExceptionRequest Request {
host = "wpdotfill09"
port = 80
secure = False
requestHeaders = []
path = "/R_VMP3_USERS/tdb069/Crash%20Analysis/Vehicle_Design_and_Injury_Severity/Reports/GGPLOT_TEST_files/figure-html/ggplot-1.png"
queryString = ""
method = "GET"
proxy = Nothing
rawBody = False
redirectCount = 10
responseTimeout = ResponseTimeoutDefault
requestVersion = HTTP/1.1
proxySecureMode = ProxySecureWithConnect
}
(ConnectionFailure Network.Socket.connect: <socket: 792>: failed (Connection refused (WSAECONNREFUSED)))
Output created: ../Reports//GGPLOT_TEST.html
# 问题原因分析 核心问题是**knitr将网络驱动器上的图片路径错误解析为HTTP URL**: - 输出到网络驱动器时,knitr把共享路径`\\wpdotfill09\...`转换成了`http://wpdotfill09/...`的HTTP请求格式 - 目标主机`wpdotfill09`未开启HTTP服务(80端口),导致尝试通过HTTP访问图片资源时被拒绝 - `plotly::ggplotly`生成的是内嵌在HTML中的交互式JS元素,不需要读取外部PNG文件,因此不受影响 # 解决办法 ### 方案1:强制使用本地文件路径格式 在setup代码块中添加`base.url`参数,指定图片资源的本地网络路径(`file:///`开头): ```r ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", root.dir = "f:/Crash Analysis/Vehicle_Design_and_Injury_Severity/", # 强制使用本地文件路径访问图片 base.url = "file:///F:/Crash Analysis/Vehicle_Design_and_Injury_Severity/Reports/" ) .libPaths("C:/Program Files/R/R-4.3.1/library") library(bookdown) library(tidyverse) library(ggplot2) library(scales) library(plotly)
### 方案2:先输出到本地目录,再移动至网络驱动器 修改`knit`函数,先将文档输出到本地临时目录,再复制到网络驱动器: ```yaml knit: (function(inputFile, encoding) { # 本地临时输出目录 local_out_dir <- tempdir() # 渲染到本地 local_output <- rmarkdown::render(inputFile, encoding=encoding, output_file=file.path(local_out_dir, "GGPLOT_TEST.html")) # 复制到网络驱动器 file.copy(local_output, file.path(dirname(inputFile), '../Reports/', "GGPLOT_TEST.html"), overwrite = TRUE) # 复制图片文件夹 file.copy(file.path(local_out_dir, "GGPLOT_TEST_files"), file.path(dirname(inputFile), '../Reports/', "GGPLOT_TEST_files"), recursive = TRUE, overwrite = TRUE) })
方案3:禁用knitr的URL自动转换
在setup代码块中设置fig.path为相对路径,并关闭self_contained(避免尝试内嵌图片时出错):
```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", root.dir = "f:/Crash Analysis/Vehicle_Design_and_Injury_Severity/", # 设置图片相对路径 fig.path = "GGPLOT_TEST_files/figure-html/", # 不生成单文件HTML,保留外部资源 self_contained = FALSE ) .libPaths("C:/Program Files/R/R-4.3.1/library") library(bookdown) library(tidyverse) library(ggplot2) library(scales) library(plotly)
### 方案4:使用绝对路径直接指定图片存储位置 在setup代码块中设置`fig.path`为网络驱动器的绝对路径: ```r ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", root.dir = "f:/Crash Analysis/Vehicle_Design_and_Injury_Severity/", # 直接指定图片存储到网络驱动器的绝对路径 fig.path = "F:/Crash Analysis/Vehicle_Design_and_Injury_Severity/Reports/GGPLOT_TEST_files/figure-html/" ) .libPaths("C:/Program Files/R/R-4.3.1/library") library(bookdown) library(tidyverse) library(ggplot2) library(scales) library(plotly)
--- 内容的提问来源于stack exchange,提问作者Josh R.

