3D труба / труба в R - создание участков из корней деревьев
Я пытаюсь создать трехмерные графики моделируемых корней деревьев в R. Вот пример роста корневой системы с течением времени:
По сути, это трехмерная сеть цилиндров, где диаметр цилиндра (и, необязательно, цвет) представляет размер корня. Доступные данные включают в себя:
- x, y, z корневого центроида
- направление "родительского" корня (например, +x, -x, +y, -y, +z, -z), хотя эту информацию можно получить несколькими различными способами, в том числе путем вычисления x, y, z родительского элемента непосредственно перед заговором.
- размер корня
Пример 3D-данных приведен здесь, но вот моя первая попытка использовать только 2D-данные. 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
рамки, но я понимаю, что не существует тонны 3D-вариантов для ggplot2
, Одним из интересных подходов может быть творческое использование концепции сетевых графов через ggraph
а также tidygraph
пакеты. Хотя эти пакеты работают только в 2D, насколько мне известно, у их разработчика также есть несколько интересных связанных идей в 3D, которые также могут быть применены.
rgl
библиотека в, кажется, лучше для 3D-графики в R, но rgl
Решение кажется гораздо более сложным и лишено других преимуществ ggplot2
например, огранка по году, как в примере, легко настраиваемая шкала и т. д.
Пример данных здесь:
1 ответ
Я не понимаю формат ваших данных, поэтому я уверен, что это не тот экран, который вам нужен, но он показывает, как нарисовать кучу цилиндров в rgl
:
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
если вы хотите, чтобы он выглядел гладко, или используйте sides = <some big number>
в cylinder3d
чтобы они выглядели круглее.