如何用Patchwork合并Plotly与ggplot2图表为分面并导出PDF
合并Plotly与ggplot2图表为PDF的解决方案
我尝试用Patchwork的(Treemap_plotly/barchart_ggplot2)命令将Plotly树形图和ggplot2柱状图合并成分面布局并导出为PDF,但该命令无法生效。相关代码如下:
library(ggplot2) library(plotly) library(dplyr) library(patchwork) ## 1.Plotly dt=data.frame( types= rep("stories",10), kind= c('kind_1','kind_2','kind_3','kind_1','kind_2','kind_3','kind_1','kind_2','kind_3','kind_1'), values=seq(1:10)) Treemap_plotly<-plot_ly(data = dt, type= "treemap", values= ~values, labels= ~kind, parents= ~types, domain= list(column=0), name = " ", textinfo="label+value+percent parent")%>% layout(title="Treemap") ## 2.ggplot2 df1 <- data.frame(dose=c("D0.5", "D1", "D2"), len=c(4.2, 10, 29.5)) barchart_ggplot2<-ggplot(data=df1, aes(x=dose, y=len)) + geom_bar(stat="identity", fill="steelblue")+ geom_text(aes(label=len), vjust=-0.3, size=3.5)+ theme_minimal() # 尝试合并(无效) (Treemap_plotly/barchart_ggplot2)
问题原因
Patchwork仅支持ggplot2对象的组合,而Plotly生成的是htmlwidgets类型对象,两者底层结构不同,无法直接用Patchwork语法合并。
解决方案
方案1:将Plotly转为静态图后用Patchwork合并
先把Plotly图表转为静态图片,再转为ggplot兼容的对象,之后用Patchwork组合并导出PDF:
library(ggplot2) library(plotly) library(dplyr) library(patchwork) library(webshot2) library(png) # 生成两个图表(代码同问题部分,可复用) dt=data.frame( types= rep("stories",10), kind= c('kind_1','kind_2','kind_3','kind_1','kind_2','kind_3','kind_1','kind_2','kind_3','kind_1'), values=seq(1:10)) Treemap_plotly<-plot_ly(data = dt, type= "treemap", values= ~values, labels= ~kind, parents= ~types, domain= list(column=0), name = " ", textinfo="label+value+percent parent")%>% layout(title="Treemap") df1 <- data.frame(dose=c("D0.5", "D1", "D2"), len=c(4.2, 10, 29.5)) barchart_ggplot2<-ggplot(data=df1, aes(x=dose, y=len)) + geom_bar(stat="identity", fill="steelblue")+ geom_text(aes(label=len), vjust=-0.3, size=3.5)+ theme_minimal() # 将Plotly转为静态图片,再转为ggplot对象 tmp_png <- tempfile(fileext = ".png") save_image(Treemap_plotly, tmp_png) treemap_static <- ggplot() + annotation_raster(readPNG(tmp_png), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) + theme_void() # 合并布局并导出PDF combined_plot <- treemap_static / barchart_ggplot2 ggsave("combined_plots.pdf", combined_plot, width=8, height=10)
方案2:用htmltools组合后导出为PDF
将两个图表组合成HTML页面,再转为PDF(若需保留交互性,可直接导出为HTML):
library(ggplot2) library(plotly) library(dplyr) library(htmltools) library(webshot2) # 生成两个图表(代码同问题部分) dt=data.frame( types= rep("stories",10), kind= c('kind_1','kind_2','kind_3','kind_1','kind_2','kind_3','kind_1','kind_2','kind_3','kind_1'), values=seq(1:10)) Treemap_plotly<-plot_ly(data = dt, type= "treemap", values= ~values, labels= ~kind, parents= ~types, domain= list(column=0), name = " ", textinfo="label+value+percent parent")%>% layout(title="Treemap") df1 <- data.frame(dose=c("D0.5", "D1", "D2"), len=c(4.2, 10, 29.5)) barchart_ggplot2<-ggplot(data=df1, aes(x=dose, y=len)) + geom_bar(stat="identity", fill="steelblue")+ geom_text(aes(label=len), vjust=-0.3, size=3.5)+ theme_minimal() # 将ggplot转为htmlwidget,组合成HTML页面 ggplot_html <- ggplotly(barchart_ggplot2) combined_html <- tagList( tags$div(Treemap_plotly, style="width: 100%; height: 400px;"), tags$br(), tags$div(ggplot_html, style="width: 100%; height: 400px;") ) # 保存临时HTML并转为PDF tmp_html <- tempfile(fileext = ".html") save_html(combined_html, tmp_html) webshot(tmp_html, "combined_plots.pdf", vwidth=800, vheight=1000)
注意事项
- 方案1生成的是静态PDF,Plotly的交互性会丢失;方案2导出的PDF也是静态的,若需保留交互性可直接保存为HTML文件。
- 执行前需安装依赖包:
install.packages(c("webshot2", "png", "htmltools"))
内容的提问来源于stack exchange,提问作者silent_hunter
相关产品推荐
相关产品推荐

