如何在RStudio中将3D密度图与2D等高线图合并为一张图?
合并3D密度图与2D等高线图到同一画布(Plotly R实现)
问题描述
我希望在RStudio中将密度图与等高线图合并为一张图,已编写代码生成两个独立的3D密度图和2D等高线图,代码如下:
library(MASS) library(plotly) set.seed(123) lambda1 <- 4 k1 <- 3 theta1 <- 5 k2 <- 1 theta2 <- 5 num_simulations <- 1000 n <- rpois(num_simulations, lambda1) n_truncated <- n[n > 0] num_simulations <- length(n_truncated) generate_gamma_sums <- function(counts, k, theta) { sapply(counts, function(x) sum(rgamma(x, shape = k, scale = theta))) } ssx <- data.frame( sx = generate_gamma_sums(n_truncated, k1, theta1), sy = generate_gamma_sums(n_truncated, k2, theta2) ) colnames(ssx) <- c("X", "Y") density_data <- kde2d(ssx$X, ssx$Y, n = 50) x_vals <- rep(density_data$x, each = length(density_data$y)) y_vals <- rep(density_data$y, length(density_data$x)) z_vals <- as.vector(density_data$z) xlim <- range(density_data$x) ylim <- range(density_data$y) pdf_3d_plot <- plot_ly(x = ~x_vals, y = ~y_vals, z = ~z_vals, type = 'mesh3d', intensity = ~z_vals, showscale = TRUE, colorscale = list(c(0, 1), c("black", "white"))) %>% layout( scene = list( xaxis = list(title = "X-axis", range = xlim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), yaxis = list(title = "Y-axis", range = ylim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), zaxis = list(title = "Density", showgrid = TRUE, zeroline = FALSE), camera = list(eye = list(x = 1.5, y = 1.5, z = 1.2)) ), title = list(text = "3D PDF Surface", x = 0.5) ) contour_2d_plot <- plot_ly(x = density_data$x, y = density_data$y, z = density_data$z, type = "contour", contours = list(coloring = "none", showlabels = TRUE), line = list(color = 'black')) %>% layout( xaxis = list(title = "X-axis", range = xlim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), yaxis = list(title = "Y-axis", range = ylim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), title = list(text = "2D Contour Plot", x = 0.5))
请问如何将生成的pdf_3d_plot与contour_2d_plot合并为一张图?
解决方案
可以使用Plotly的subplot()函数将两个子图组合到同一画布中,支持自定义布局(如上下排列、左右排列),同时可以统一调整整体标题和轴设置。以下是修改后的完整代码:
library(MASS) library(plotly) set.seed(123) lambda1 <- 4 k1 <- 3 theta1 <- 5 k2 <- 1 theta2 <- 5 num_simulations <- 1000 n <- rpois(num_simulations, lambda1) n_truncated <- n[n > 0] num_simulations <- length(n_truncated) generate_gamma_sums <- function(counts, k, theta) { sapply(counts, function(x) sum(rgamma(x, shape = k, scale = theta))) } ssx <- data.frame( sx = generate_gamma_sums(n_truncated, k1, theta1), sy = generate_gamma_sums(n_truncated, k2, theta2) ) colnames(ssx) <- c("X", "Y") density_data <- kde2d(ssx$X, ssx$Y, n = 50) x_vals <- rep(density_data$x, each = length(density_data$y)) y_vals <- rep(density_data$y, length(density_data$x)) z_vals <- as.vector(density_data$z) xlim <- range(density_data$x) ylim <- range(density_data$y) pdf_3d_plot <- plot_ly(x = ~x_vals, y = ~y_vals, z = ~z_vals, type = 'mesh3d', intensity = ~z_vals, showscale = TRUE, colorscale = list(c(0, 1), c("black", "white"))) %>% layout( scene = list( xaxis = list(title = "X-axis", range = xlim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), yaxis = list(title = "Y-axis", range = ylim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), zaxis = list(title = "Density", showgrid = TRUE, zeroline = FALSE), camera = list(eye = list(x = 1.5, y = 1.5, z = 1.2)) ), title = list(text = "3D PDF Surface", x = 0.5) ) contour_2d_plot <- plot_ly(x = density_data$x, y = density_data$y, z = density_data$z, type = "contour", contours = list(coloring = "none", showlabels = TRUE), line = list(color = 'black')) %>% layout( xaxis = list(title = "X-axis", range = xlim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), yaxis = list(title = "Y-axis", range = ylim, showgrid = TRUE, zeroline = FALSE, showline = TRUE), title = list(text = "2D Contour Plot", x = 0.5)) # 合并两个子图,设置为上下排列(rows=2),也可改为cols=2实现左右排列 combined_plot <- subplot(pdf_3d_plot, contour_2d_plot, nrows = 2, shareX = TRUE, shareY = TRUE) %>% layout(title = list(text = "3D密度图与2D等高线图组合", x = 0.5), margin = list(l = 50, r = 50, t = 80, b = 50)) # 显示合并后的图 combined_plot
关键说明
subplot()函数的nrows参数设置为2表示上下排列,若设为cols=2则为左右排列;shareX和shareY设为TRUE可让两个子图共享X/Y轴,保证坐标范围一致;- 通过外层
layout()可以统一设置整体标题和边距,让布局更美观。
内容的提问来源于stack exchange,提问作者miss alhejaili
相关产品推荐
相关产品推荐

