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

如何在R的Plotly中绘制mesh3d对象?RGL可绘但Plotly无输出

问题:Plotly无法渲染RGL正常显示的三角网格

我尝试在Plotly中绘制一个在RGL里能正常显示的三角网格,因偏好Plotly的数据悬停交互功能,优先选择Plotly方案,也接受RGL的替代方案。

复现数据与依赖库

library(rgl)
library(plotly)
library(SurfaceReconstruction)
library(dplyr)

plot_issue_dat <- structure(c(-2.058, -3.02, 4.437, -3.02, 5.8, 4.985, -0.715, 
4.985, 5.8, -0.715, -2.058, 5.458, 5.061, 12.443, 4.943, 4.471, 
6.809, 6.809, -3.024, -3.024, -116.181, -115.799, -116.153, -115.799, 
-115.493, -107.238, -115.701, -107.238, -115.493, -115.701, -116.181, 
-107.907, -115.557, -105.538, -111.077, -114.791, -114.172, -114.172, 
-114.397, -114.397, 203.556, 203.187, 205.384, 203.187, 205.988, 
192.985, 202.444, 192.985, 205.988, 202.444, 203.556, 193.987, 
207.515, 198.121, 198.177, 210.117, 208.797, 208.797, 201.275, 
201.275), dim = c(20L, 3L), dimnames = list(NULL, c("surf_x", 
"surf_y", "surf_z")))

我通过点云数据,使用Advancing Front Reconstruction算法生成了mesh3d对象:

plot_issue_mesh <- SurfaceReconstruction::AFSreconstruction(plot_issue_dat)

> class(plot_issue_mesh)
[1] "mesh3d"

该对象可在RGL中正常绘制:

mfrow3d(1, 2, sharedMouse = TRUE)
wire3d(plot_issue_mesh) 
axes3d()  
next3d()
points3d(x=plot_issue_dat[,1], 
       y=plot_issue_dat[,2], 
       z=plot_issue_dat[,3])
axes3d()  

但将顶点和面数据转换后传入Plotly时,无任何图形输出:

plot_ly_dat_vert <- plot_issue_mesh$vb |> t()
plot_ly_dat_face <- plot_issue_mesh$it |> t()

plot_ly()|>
  add_trace(
    type="mesh3d",
    x = plot_ly_dat_vert[,1],
    y = plot_ly_dat_vert[,2],
    z = plot_ly_dat_vert[,3],
    i = plot_ly_dat_face[,1],
    j = plot_ly_dat_face[,2],
    k = plot_ly_dat_face[,3]
  )

仅单独绘制顶点时Plotly可正常显示:

plot_ly()|>
  add_trace(
    x = plot_ly_dat_vert[,1],
    y = plot_ly_dat_vert[,2],
    z = plot_ly_dat_vert[,3]
  )

版本信息

## [1] "R version 4.2.2 Patched (2022-11-10 r83330) Innocent and Trusting"

## [1] "RStudio Version 2022.12.0.353 Elsbeth Geranium"

    package     loadedversion
dplyr   dplyr   1.0.10
ggplot2     ggplot2     3.4.0
knitr   knitr   1.41
plotly  plotly  4.10.1
rgl     rgl     0.110.2
SurfaceReconstruction   SurfaceReconstruction   0.1.0

mesh3d对象详情

> plot_issue_mesh$vb
         [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]     [,9]    [,10]    [,11]
[1,]   -0.715   -3.020   -3.024   -2.058    4.437    4.471   12.443    4.985    5.458    5.061    6.809
[2,] -115.701 -115.799 -114.397 -116.181 -116.153 -114.791 -105.538 -107.238 -107.907 -115.557 -114.172
[3,]  202.444  203.187  201.275  203.556  205.384  210.117  198.121  192.985  193.987  207.515  208.797
[4,]    1.000    1.000    1.000    1.000    1.000    1.000    1.000    1.000    1.000    1.000    1.000
        [,12]    [,13]
[1,]    5.800    4.943
[2,] -115.493 -111.077
[3,]  205.988  198.177
[4,]    1.000    1.000

> plot_issue_mesh$it
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18]
[1,]    1    4    2    6    8    8    6   12    7     7     9    12    11     1     8     3     6     4
[2,]    2    1    1    3    7    3    2   11    3     6     7     7     6     3     9     8     4     5
[3,]    3    5    4    2    9    7    4   10    6    11    13    11    10    13    13    13    10    10
     [,19] [,20] [,21] [,22]
[1,]    13    10     5     5
[2,]     7     5    13     1
[3,]    12    12    12    13

> plot_issue_mesh$normals
            [,1]       [,2]        [,3]        [,4]       [,5]       [,6]       [,7]       [,8]       [,9]
[1,]  0.04487982 -0.9289559 -0.89572966 -0.29054707  0.2498839 -0.1312339  0.7863605 -0.2423399  0.3724951
[2,] -0.83876795 -0.3494553  0.08686093 -0.95390713 -0.9588761 -0.1204796  0.5823910  0.3784624 -0.7133183
[3,] -0.54263622  0.1221557 -0.43603158  0.07512296 -0.1345901  0.9840032 -0.2060528 -0.8933295 -0.5936534
[4,]  1.00000000  1.0000000  1.00000000  1.00000000  1.0000000  1.0000000  1.0000000  1.0000000  1.0000000
          [,10]      [,11]      [,12]      [,13]
[1,]  0.2388872  0.7250958  0.6054552  0.3288626
[2,] -0.9349205 -0.1093559 -0.7894580 -0.7705457
[3,]  0.2624054  0.6799098 -0.1008973 -0.5459933
[4,]  1.0000000  1.0000000  1.0000000  1.0000000

> plot_issue_mesh$remvert
 [1] 0 0 0 0 0 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[53] 1 1 1 1 1 1 1 1 1 1 1 1 1 1

> plot_issue_mesh$remface
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

解决方案

Plotly方案:修正顶点索引

Plotly的mesh3d使用0起始索引,但RGL的mesh3d对象中it矩阵存储的是1起始索引,这是导致渲染失败的核心原因。只需将面索引全部减1即可:

plot_ly_dat_vert <- plot_issue_mesh$vb[1:3,] |> t()  # 只取x/y/z坐标,去掉齐次坐标的第4行
plot_ly_dat_face <- plot_issue_mesh$it |> t() - 1    # 索引从1转0

plot_ly()|>
  add_trace(
    type="mesh3d",
    x = plot_ly_dat_vert[,1],
    y = plot_ly_dat_vert[,2],
    z = plot_ly_dat_vert[,3],
    i = plot_ly_dat_face[,1],
    j = plot_ly_dat_face[,2],
    k = plot_ly_dat_face[,3],
    hoverinfo = "x+y+z"  # 开启悬停显示坐标
  )

补充说明

  • 转换顶点时可去掉vb矩阵的第4行(齐次坐标的w值,固定为1),不影响渲染
  • 加上hoverinfo参数可明确指定悬停时显示的内容,满足交互需求

RGL增强交互方案(备选)

如果Plotly方案仍有问题,可在RGL中添加悬停交互,使用rglwidget()将RGL图形转为HTML交互式组件:

library(rglwidget)

mfrow3d(1, 1)
wire3d(plot_issue_mesh)
axes3d()
# 添加顶点悬停提示
plot3d(plot_issue_dat, type="s", size=1, col="red", hover=TRUE)

# 导出为可交互的HTML组件
rglwidget()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:11:32