这篇帖子是我关于how to draw polar dendrogram in 3D in rgl的问题的延伸.用户2554330的回答解决了这个问题.现在,我想在树状图的顶端进一步添加3D网格.

这构成了树状图:

a <- list()  # initialize empty object
# define merging pattern: 
#    negative numbers are leaves, 
#    positive are merged clusters (defined by row number in $merge)
a$merge <- matrix(c(-1, -2,
                    -3, -4,
                    1,  2), nc=2, byrow=TRUE ) 
a$height <- c(1, 1.5, 3)    # define merge heights
a$order <- 1:4              # order of leaves(trivial if hand-entered)
a$labels <- LETTERS[1:4]    # labels of leaves
class(a) <- "hclust"        # make it an hclust object
plot(a)                     # show it

# Convert to a dendrogram object.
ad <- as.dendrogram(a)

# dend_data contains segment information
library(ggdendro)
dend_data <- dendro_data(ad, type = "rectangle")

来自用户2554330的代码以3D形式绘制了树状图:

nodes <- dend_data$segments

# Set the gap between the ends of the tree
gap <- 0
# Set the offset from the center.  
offset <- 0

radius <- with(nodes, max(c(y, yend)) + offset)
circ <- with(nodes, max(c(x, xend)) + gap)

# Convert to polar coordinates
nodes$theta <- with(nodes, 2*pi*x/circ)
nodes$thetaend <- with(nodes, 2*pi*xend/circ)
nodes$r     <- with(nodes, (radius - y)/radius)
nodes$rend  <- with(nodes, (radius - yend)/radius)

# Extract the horizontal and vertical segments
horiz <- subset(nodes, y == yend)
vert <- subset(nodes, x == xend)

library(rgl)

open3d()
#> glX 
#>   1

# Draw the vertical segments, which are still segments
x     <- with(vert, as.numeric(rbind(r*cos(theta), rend*cos(theta))))
y     <- with(vert, as.numeric(rbind(r*sin(theta), rend*sin(theta))))
segments3d(x, y, z = 0)

# Draw the horizontal segments, which are now arcs.  Zero
# radius arcs are dropped
horiz <- subset(horiz, r > 0)
with(horiz, arc3d(from = cbind(r*cos(theta), r*sin(theta), 0),
                  to = cbind(r*cos(thetaend), r*sin(thetaend), 0),
                  center = c(0, 0, 0)))

# Draw the labels
labels <- dend_data$labels
labels$theta <- with(labels, 2*pi*x/circ)
# Add a bit to the y so the label doesn't overlap the segment
labels$r     <- with(labels, (radius - y)/radius + 0.1)
with(labels, text3d(r*cos(theta), r*sin(theta), 0, label))

现在我在树状图的顶端添加球体:

with(labels, spheres3d(r*cos(theta), r*sin(theta), 0, radius = 0.1, color = c("lightblue", "pink", "lightyellow", "lightgrey")))

当我旋转RGL场景时,所有四个球体与3D树状图一起旋转.我想问有没有一种方法可以在RGL窗口中交互地单独旋转每个球体,这样当我旋转粉色球体时,3D树状图不会旋转,其他3个球体也不会旋转.谢谢.

推荐答案

在做你想做的事情时,真的有3项任务.所有这些都是可能的,但难度各不相同:

  1. 允许某些对象独立于其他对象进行旋转.这相当容易.一种方法是将不同的对象放在不同的"子场景"中.子场景可以共享相同的外观空间体积,但不共享相同的鼠标控制.另一种方法是使用3D精灵,它可以有自己的关联矩阵,以不同于其他对象的方式旋转它们.

  2. 允许 Select 特定对象.你没有说你希望用户如何指定哪个对象应该旋转,或者你将如何控制旋转,但通常的方法是指向一个对象,并用鼠标"抓住"它来旋转它.这在rgl年是可能的(见select3d()),但这有点棘手.一个简单得多的 Select 是需要调用一些函数;该函数将设置一些变量,这些变量将在以后使用.

  3. 指定选定对象如何响应鼠标.您可以在 Select 对象后设置用户鼠标处理程序,但您需要弄清楚该处理程序应该做什么.rgl.setMouseCallbacks()函数给出了一个例子.

R相关问答推荐

在ComplexHeatmap中,如何更改anno_barplot()标题的Angular ?

将模拟变量乘以多个观测结果中的模拟变量

在边界外添加注释或标题

查找具有平局的多个列的最大值并返回列名或平局 destruct 者NA值

寻找图片边缘

如何对数据集进行逆向工程?

R Highcharts与两个位置关联的注释

如何在R中合并两个基准点?

R函数‘paste`正在颠倒其参数的顺序

如何在观测缺失的地方添加零

将文件保存到新文件夹时,切换r设置以不必创建目录

如何通过判断数据框的一列来压缩另一列?

有没有办法使用ggText,<;Sub>;&;<;sup>;将上标和下标添加到同一元素?

有没有办法一次粘贴所有列

在散点图中使用geom_point放置线图例

是否有可能从边界中找到一个点值?

如何移动点以使它们的打印不重叠

如何获取R chromote中的当前URL?

R:如何在数据集中使用Apply

如何修改GT表中组名行的 colored颜色 ?