我已经使用PLOTLY包在R中创建了一系列3D散点图,其中每个图根据我数据集中的不同变量进行着色.我已经设法使用plotly中的subploy()函数或ManipulateWidget包中的combineWidget()函数将它们组合成一个"主"图.有关使用mtars数据集的代表性示例,请参见下面的代码:

#Packages
library(dplyr)
library(plotly)
library("manipulateWidget")

#Dataset
library(datasets)
data(mtcars)

#Four different 3d scatter plots
fig_1 <- plot_ly(mtcars, type = "scatter3d", x = ~mpg, y = ~cyl, z = ~ wt, color = ~as.factor(vs), 
                 colors = c("black", "grey"), scene = "scene",
                 mode = "markers", marker = list(size = 5, symbol = "circle"))

fig_2 <- plot_ly(mtcars, type = "scatter3d", x = ~mpg, y = ~cyl, z = ~ wt, color = ~as.factor(am),
                 colors = c("red", "blue"), scene = "scene2",
                 mode = "markers", marker = list(size = 5, symbol = "circle"))

fig_3 <- plot_ly(mtcars, type = "scatter3d", x = ~mpg, y = ~cyl, z = ~ wt, color = ~as.factor(gear),
                 colors = c("yellow", "brown", "orange"), scene = "scene3",
                 mode = "markers", marker = list(size = 5, symbol = "circle"))

fig_4 <- plot_ly(mtcars, type = "scatter3d", x = ~mpg, y = ~cyl, z = ~ wt, color = ~as.factor(carb),
                 colors = c("green", "pink", "cyan", "purple"), scene = "scene4",
                 mode = "markers", marker = list(size = 5, symbol = "circle"))

#Can be combined as subplots:
main_plot <- subplot(fig_1, fig_2, fig_3, fig_4, nrows = 2, margin = 0.06) %>% 
  layout(title = "Main Plot", 
         scene= list(domain = list(x=c(0,0.5), y=c(0.5,1)), aspectmode="cube"), 
         scene2 = list(domain = list(x=c(0.5,1), y=c(0.5,1)), aspectmode="cube"),
         scene3 = list(domain = list(x=c(0,0.5), y=c(0,0.5)), aspectmode="cube"),
         scene4 = list(domain = list(x=c(0.5,1), y=c(0,0.5)), aspectmode="cube")
         )

main_plot


#OR alternatively they can be combined as widgets:
combineWidgets(fig_1, fig_2, fig_3, fig_4) 

到目前为止还不错,但我曾希望合并后的3D绘图能以某种方式同步,这样当我拖动/zoom /旋转一个绘图时,其他3个绘图也会效仿并适应新的"视图".有没有人知道在R中是否有可能将组合的3D图形作为子图形或组合的窗口小部件来实现?

类似的问题也被问到了与通过Python(https://community.plotly.com/t/synchronize-camera-across-3d-subplots/22236)密谋的有关,尽管我还不能发现在R中是否已经或可以做一些类似的事情.

如果能得到任何帮助或建议,我将不胜感激.提前谢谢!

  • 赞恩

推荐答案

该功能并未实现,但稍加修改即可实现该功能:

main_plot <- subplot(fig_1, fig_2, fig_3, fig_4, nrows = 2, margin = 0.06) %>% 
  layout(title = "Main Plot", 
         scene  = list(domain = list(x = c(0, 0.5), y = c(0.5, 1)), aspectmode = "cube"), 
         scene2 = list(domain = list(x = c(0.5, 1), y = c(0.5, 1)), aspectmode = "cube"),
         scene3 = list(domain = list(x = c(0, 0.5), y = c(0, 0.5)), aspectmode = "cube"),
         scene4 = list(domain = list(x = c(0.5, 1), y = c(0, 0.5)), aspectmode = "cube")
  )

main_plot %>% 
  htmlwidgets::onRender(
    "function(x, el) {
      x.on('plotly_relayout', function(d) {
        const camera = Object.keys(d).filter((key) => /\\.camera$/.test(key));
        if (camera.length) {
          const scenes = Object.keys(x.layout).filter((key) => /^scene\\d*/.test(key));
          const new_layout = {};
          scenes.forEach(key => {
            new_layout[key] = {...x.layout[key], camera: {...d[camera]}};
          });
          Plotly.relayout(x, new_layout);
        }
      });
    }")

解释

无论何时进行zoom /旋转,都会触发一个plotly_relayout事件,您可以对其做出react .该事件包含一个对象,该对象保存我们可以使用的新布局数据(d).

如果在这个对象中有一个camera槽(即,我们做了一些改变视角/变焦的操作),我们首先获得原始场景(以保留特定于域的原始设置),并用新的相机槽覆盖所有场景的相机槽,有效地同步所有散布情节.

我们使用htmlwidgets::onRender来添加定制的JavaScript代码.

R相关问答推荐

导入到固定列宽的R中时出现问题

R中的子集文件—读取文件名索引为4位数字序列,例如0001到4000,而不是1到4000)

通过使用str_detect对具有相似字符串的组进行分组

如何将移除事件分配给动态创建的按钮?

将嵌套列表子集化为嵌套列表

如何得到R中唯一的组合群?

为什么当用osmdata映射R时会得到相邻状态?

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

使用较长的查询提取具有部分匹配的列表中的较短目标,

使用带有OR条件的grepl过滤字符串

在保留列表元素属性的同时替换列表元素

是否有新方法来更改Facet_WRAP(Ggplot2)中条文本的文本 colored颜色 ?

自动STAT_SUMMARY统计与手动标准误差之间的差异

我是否可以使用多个变异项来构建顺序列(标记多个问题)

如何在R中创建条形图,使条形图在y轴上围绕0.5而不是0构建条形图?

主题(Legend.key=Element_RECT(Fill=&Quot;White&Quot;))不起作用

为什么不能使用lApply在包装函数中调用子集

如何使用ggplot2根据绘图中生成的斜率对小平面进行排序?

如何合并不同列表中的数据文件,包括基于名称的部分匹配,而不是一对一等价

将字符变量出现次数不相等的字符框整形为pivot_wider,而不删除重复名称或嵌套字符变量