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

如何用rayshader将ggplot2的2D折线图、直方图转为3D图?

解决rayshader转换ggplot2折线图与直方图为3D的问题

一、3D折线图实现方案

plot_gg对geom_line的3D支持有限,因为它主要基于图层的填充区域转换为3D高度,无填充的线条默认仅显示为平面元素。要实现真正的3D折线效果,可结合ggplot2构建基础底图,再用rayshader原生函数添加立体线条:

  1. 将分类x轴转换为数值,方便3D空间定位
  2. 用plot_gg生成基础平面,再通过add_3d_lines添加立体线条

修改后的代码:

library(rayshader)
library(ggplot2)

df2 = data.frame(supp=rep(c("VC", "OJ"), each=3),
                dose=rep(c("D0.5", "D1", "D2"),2),
                len=c(6.8, 15, 33, 4.2, 10, 29.5))
# 把分类dose转为数值格式
df2$dose_num = as.numeric(factor(df2$dose))

# 绘制带点的基础底图
gg_line = ggplot(data=df2, aes(x=dose_num, y=len, color=supp)) +
  geom_point(size=3) +
  scale_x_continuous(breaks=1:3, labels=c("D0.5", "D1", "D2"))

# 转换为3D底图
plot_gg(gg_line, raytrace = TRUE, width = 4, zoom = 0.60, theta = -45, phi = 30, 
        windowsize = c(1400,866), multicore = TRUE)

# 分别添加两组数据的3D线条
vc_data = subset(df2, supp=="VC")
oj_data = subset(df2, supp=="OJ")

add_3d_lines(x = vc_data$dose_num, y = vc_data$len, z = 0.2, # z值控制线条悬浮高度
             color = "blue", linewidth = 3)
add_3d_lines(x = oj_data$dose_num, y = oj_data$len, z = 0.2,
             color = "orange", linewidth = 3)
render_snapshot()

二、3D直方图实现方案

geom_histogram的柱子无法被plot_gg直接拉伸为3D,推荐两种解决思路:

方法1:基于ggplot2 + plot_gg调整

将直方图转换为geom_col的填充柱形,让plot_gg识别柱子高度:

library(rayshader)
library(ggplot2)

df = data.frame(
  sex=factor(rep(c("F", "M"), each=200)),
  weight=round(c(rnorm(200, mean=55, sd=5), rnorm(200, mean=65, sd=5)))
)

# 提前计算直方图的统计数据
hist_data = ggplot_build(ggplot(df, aes(x=weight)) + geom_histogram())$data[[1]]

# 用geom_col绘制可被3D识别的填充柱形
gg_hist = ggplot(hist_data, aes(x=x, y=density)) + 
  geom_col(fill="white", color="black") +
  geom_density(data=df, aes(x=weight, y=..density..), alpha=.2, fill="#FF6666")

# 转换为3D,通过height参数控制柱子高度
plot_gg(gg_hist, raytrace = TRUE, width = 4, zoom = 0.60, theta = -45, phi = 30, 
        windowsize = c(1400,866), height = 0.5, multicore = TRUE)

方法2:直接使用rayshader原生hist3d函数

若不需要ggplot2的样式,用原生函数生成3D直方图更直接:

library(rayshader)
library(ggplot2)

df = data.frame(
  sex=factor(rep(c("F", "M"), each=200)),
  weight=round(c(rnorm(200, mean=55, sd=5), rnorm(200, mean=65, sd=5)))
)

# 分别计算男女体重的直方图密度
female_hist = hist(df$weight[df$sex=="F"], plot=FALSE)
male_hist = hist(df$weight[df$sex=="M"], plot=FALSE)

# 合并为矩阵格式
hist_matrix = matrix(0, nrow=length(female_hist$mids), ncol=2)
hist_matrix[,1] = female_hist$density
hist_matrix[,2] = male_hist$density

# 绘制3D直方图
hist_matrix %>%
  sphere_shade(texture="desert") %>%
  plot_3d(hist_matrix, zscale=0.2, theta=-45, phi=30, 
          xlab="Weight", ylab="Sex", zlab="Density",
          windowsize=c(1400,866))
render_snapshot()

关键提示

  • plot_gg仅能将ggplot中有填充的图层转换为3D高度,线条、点等无填充元素默认是平面的,需额外处理
  • 折线图:通过add_3d_lines手动添加立体线条,z轴参数控制线条的悬浮高度
  • 直方图:优先转为geom_col填充柱形,或直接用rayshader原生函数生成纯3D效果

内容的提问来源于stack exchange,提问作者Ed_Gravy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:10:28