R 中的 3D pipe/tube 图 - 创建树根图
3D pipe/tube plots in R - creating plots of tree roots
我正在尝试在 R 中创建模拟树根的 3D 图。这是一个根系随时间增长的示例:
这本质上是一个 3D 圆柱体网络,其中圆柱体直径(以及可选的颜色)表示根部的大小。可用数据包括:
- 根质心的 x、y、z
- "parent" 根的方向(例如 +x、-x、+y、-y、+z、-z),尽管可以通过几种不同的方式获取此信息,包括通过计算 x , y, z 父级直接在绘图之前。
- 根的大小
示例 3D 数据是 here,但这是我第一次使用 ggplot2::geom_spoke
:
在 2D 中尝试它
dat <- data.frame(x = c(0,1,-1,0,1,-1),
y = c(-1,-1,-1,-2,-2,-2),
biomass = c(3,1.5,1.5,1,1,1),
parent.dir = c("+y","-x","+x","+y","+y","+y"))
dat$parent.dir <- as.numeric(as.character(factor(dat$parent.dir,
levels = c("-x", "+x", "-y", "+y"),
labels = c(pi, 0, pi*3/2, pi/2))))
ggplot(dat, aes(x = x, y = y)) +
geom_point(x = 0, y = 0, size = 20) +
geom_spoke(radius = 1,
aes(angle = parent.dir,
size = biomass)) +
coord_equal()
我更喜欢基于 ggplot2
框架的解决方案,但我意识到 ggplot2
没有大量的 3D 选项。一种有趣的方法可能是通过 ggraph
和 tidygraph
包创造性地利用网络图的概念。据我所知,虽然这些软件包只能在 2D 中运行,但他们的开发人员也有一些 interesting related ideas 也可以应用的 3D。
rgl
中的库似乎是 R 中 3D 绘图的首选,但 rgl
解决方案似乎复杂得多,并且缺乏 [=13= 的其他好处]],比如例子中按年份分面,轻松调整比例等
示例数据在这里:
我不明白你的数据格式,所以我确定这不是你想要的显示方式,但它展示了如何在 rgl
:[=16= 中绘制一堆圆柱体]
root <- read.csv("~/temp/root.csv")
segments <- data.frame(row.names = unique(root$parent.direction),
x = c(-1,0,1,0,0),
y = c(0,1,0,0,-1),
z = c(0,0,0,0.2,0))
library(rgl)
open3d()
for (i in seq_len(nrow(root))) {
rbind(root[i,2:4],
root[i,2:4] - segments[root$parent.direction[i],]) %>%
cylinder3d(radius = root$size[i]^0.3, closed = -2, sides = 20) %>%
shade3d(col = "green")
}
decorate3d()
这给出了以下显示(在原来的可旋转):
如果你想让每个圆柱体看起来更光滑,你可以通过 addNormals
,或者在 cylinder3d
中使用 sides = <some big number>
使它们看起来更圆。
我正在尝试在 R 中创建模拟树根的 3D 图。这是一个根系随时间增长的示例:
这本质上是一个 3D 圆柱体网络,其中圆柱体直径(以及可选的颜色)表示根部的大小。可用数据包括:
- 根质心的 x、y、z
- "parent" 根的方向(例如 +x、-x、+y、-y、+z、-z),尽管可以通过几种不同的方式获取此信息,包括通过计算 x , y, z 父级直接在绘图之前。
- 根的大小
示例 3D 数据是 here,但这是我第一次使用 ggplot2::geom_spoke
:
dat <- data.frame(x = c(0,1,-1,0,1,-1),
y = c(-1,-1,-1,-2,-2,-2),
biomass = c(3,1.5,1.5,1,1,1),
parent.dir = c("+y","-x","+x","+y","+y","+y"))
dat$parent.dir <- as.numeric(as.character(factor(dat$parent.dir,
levels = c("-x", "+x", "-y", "+y"),
labels = c(pi, 0, pi*3/2, pi/2))))
ggplot(dat, aes(x = x, y = y)) +
geom_point(x = 0, y = 0, size = 20) +
geom_spoke(radius = 1,
aes(angle = parent.dir,
size = biomass)) +
coord_equal()
我更喜欢基于 ggplot2
框架的解决方案,但我意识到 ggplot2
没有大量的 3D 选项。一种有趣的方法可能是通过 ggraph
和 tidygraph
包创造性地利用网络图的概念。据我所知,虽然这些软件包只能在 2D 中运行,但他们的开发人员也有一些 interesting related ideas 也可以应用的 3D。
rgl
中的库似乎是 R 中 3D 绘图的首选,但 rgl
解决方案似乎复杂得多,并且缺乏 [=13= 的其他好处]],比如例子中按年份分面,轻松调整比例等
示例数据在这里:
我不明白你的数据格式,所以我确定这不是你想要的显示方式,但它展示了如何在 rgl
:[=16= 中绘制一堆圆柱体]
root <- read.csv("~/temp/root.csv")
segments <- data.frame(row.names = unique(root$parent.direction),
x = c(-1,0,1,0,0),
y = c(0,1,0,0,-1),
z = c(0,0,0,0.2,0))
library(rgl)
open3d()
for (i in seq_len(nrow(root))) {
rbind(root[i,2:4],
root[i,2:4] - segments[root$parent.direction[i],]) %>%
cylinder3d(radius = root$size[i]^0.3, closed = -2, sides = 20) %>%
shade3d(col = "green")
}
decorate3d()
这给出了以下显示(在原来的可旋转):
如果你想让每个圆柱体看起来更光滑,你可以通过 addNormals
,或者在 cylinder3d
中使用 sides = <some big number>
使它们看起来更圆。