如何在 R 中旋转 3D Plotly,更新?
Posted
技术标签:
【中文标题】如何在 R 中旋转 3D Plotly,更新?【英文标题】:How to rotate 3D Plotly in R, update? 【发布时间】:2021-12-31 18:12:00 【问题描述】:我想用 3D 表面制作动画情节
我试图复制这个例子
https://***.com/a/66117098/11555164
但我无法让它工作,没有旋转
library(shiny)
library(plotly)
library(htmlwidgets)
ui <- fluidPage(
plotlyOutput("graph")
)
server <- function(input, output, session)
N <- 100
x <- rnorm(N, mean = 50, sd = 2.3)
y <- runif(N, min = 0, max = 100)
z <- runif(N, min = 4, max = 70)
luci.frame <- data.frame(x, y, z)
output$graph <- renderPlotly(
plot_ly(
type = "scatter3d",
mode = "markers",
data = luci.frame,
x = ~ x,
y = ~ y,
z = ~ z
) %>%
layout(scene = list(camera = list(
eye = list(
x = 1.25,
y = 1.25,
z = 1.25
),
center = list(x = 0,
y = 0,
z = 0)
))) %>%
onRender("
function(el, x)
var id = el.getAttribute('id');
var gd = document.getElementById(id);
Plotly.plot(id).then(attach);
function attach()
var cnt = 0;
function run()
rotate('scene', Math.PI / 180);
requestAnimationFrame(run);
run();
function rotate(id, angle)
var eye0 = gd.layout[id].camera.eye
var rtz = xyz2rtz(eye0);
rtz.t += angle;
var eye1 = rtz2xyz(rtz);
Plotly.relayout(gd, id + '.camera.eye', eye1)
function xyz2rtz(xyz)
return
r: Math.sqrt(xyz.x * xyz.x + xyz.y * xyz.y),
t: Math.atan2(xyz.y, xyz.x),
z: xyz.z
;
function rtz2xyz(rtz)
return
x: rtz.r * Math.cos(rtz.t),
y: rtz.r * Math.sin(rtz.t),
z: rtz.z
;
;
")
)
shinyApp(ui, server)
我在 Rstudio 的控制台中没有收到任何错误
我也尝试隔离代码,并避免使用 Shiny(将其保存为 HTML) 在 Chrome 中,打开调试时出现渲染错误
这是第二个代码(没有闪亮的)
#library(shiny)
library(plotly)
library(htmlwidgets)
N <- 100
x <- rnorm(N, mean = 50, sd = 2.3)
y <- runif(N, min = 0, max = 100)
z <- runif(N, min = 4, max = 70)
luci.frame <- data.frame(x, y, z)
plot_ly(
type = "scatter3d",
mode = "markers",
data = luci.frame,
x = ~ x,
y = ~ y,
z = ~ z
) %>%
layout(scene = list(camera = list(
eye = list(
x = 1.25,
y = 1.25,
z = 1.25
),
center = list(x = 0,
y = 0,
z = 0)
))) %>%
onRender("
function(el, x)
var id = el.getAttribute('id');
var gd = document.getElementById(id);
Plotly.plot(id).then(attach);
function attach()
var cnt = 0;
function run()
rotate('scene', Math.PI / 180);
requestAnimationFrame(run);
run();
function rotate(id, angle)
var eye0 = gd.layout[id].camera.eye
var rtz = xyz2rtz(eye0);
rtz.t += angle;
var eye1 = rtz2xyz(rtz);
Plotly.relayout(gd, id + '.camera.eye', eye1)
function xyz2rtz(xyz)
return
r: Math.sqrt(xyz.x * xyz.x + xyz.y * xyz.y),
t: Math.atan2(xyz.y, xyz.x),
z: xyz.z
;
function rtz2xyz(rtz)
return
x: rtz.r * Math.cos(rtz.t),
y: rtz.r * Math.sin(rtz.t),
z: rtz.z
;
;
")
我在 onRender 上遗漏了什么?
更新:
感谢@ismirsehregal 将Plotly.plot
更改为Plotly.update
您可以检查接受的答案
如果你需要没有Shiny的版本,你可以使用这个代码
library(plotly)
library(htmlwidgets)
N <- 100
x <- rnorm(N, mean = 50, sd = 2.3)
y <- runif(N, min = 0, max = 100)
z <- runif(N, min = 4, max = 70)
luci.frame <- data.frame(x, y, z)
PLT <- plot_ly(
type = "scatter3d",
mode = "markers",
data = luci.frame,
x = ~ x,
y = ~ y,
z = ~ z
) %>%
layout(scene = list(camera = list(
eye = list(
x = 1.25,
y = 1.25,
z = 1.25
),
center = list(x = 0,
y = 0,
z = 0)
))) %>%
onRender("
function(el, x)
var id = el.getAttribute('id');
var gd = document.getElementById(id);
Plotly.update(id).then(attach);
function attach()
var cnt = 0;
function run()
rotate('scene', Math.PI / 1000);
requestAnimationFrame(run);
run();
function rotate(id, angle)
var eye0 = gd.layout[id].camera.eye
var rtz = xyz2rtz(eye0);
rtz.t += angle;
var eye1 = rtz2xyz(rtz);
Plotly.relayout(gd, id + '.camera.eye', eye1)
function xyz2rtz(xyz)
return
r: Math.sqrt(xyz.x * xyz.x + xyz.y * xyz.y),
t: Math.atan2(xyz.y, xyz.x),
z: xyz.z
;
function rtz2xyz(rtz)
return
x: rtz.r * Math.cos(rtz.t),
y: rtz.r * Math.sin(rtz.t),
z: rtz.z
;
;
")
PLT
【问题讨论】:
您的示例在 Shiny 中完美运行。因此,请尝试在您的服务器配置中查找错误 @black_paladin 和 ppriede 你用的是哪个版本的 R? R plotly recently updated 从 v1.57.1 到 v2.5.1 的底层 plotly.js 库。这包括许多重大更改 - 此解决方案可能会受到影响。 是的 - 这里使用的 Plotly.plot() 函数是 dropped。 情节 4.10,闪亮 - 1.7.1 谢谢@ismirsehregal !!! 【参考方案1】:R plotly 4.10.0 recently updated 从 v1.57.1 到 v2.5.1 的底层 plotly.js 库。这包括许多重大更改 - 使用 2.0 版的 plotly.js 函数 Plotly.plot was dropped。
要恢复旧行为Plotly.plot
可以替换为Plotly.update
:
library(shiny)
library(plotly)
library(htmlwidgets)
ui <- fluidPage(
plotlyOutput("graph")
)
server <- function(input, output, session)
N <- 100
x <- rnorm(N, mean = 50, sd = 2.3)
y <- runif(N, min = 0, max = 100)
z <- runif(N, min = 4, max = 70)
luci.frame <- data.frame(x, y, z)
output$graph <- renderPlotly(
plot_ly(
type = "scatter3d",
mode = "markers",
data = luci.frame,
x = ~ x,
y = ~ y,
z = ~ z
) %>%
layout(scene = list(camera = list(
eye = list(
x = 1.25,
y = 1.25,
z = 1.25
),
center = list(x = 0,
y = 0,
z = 0)
))) %>%
onRender("
function(el, x)
var id = el.getAttribute('id');
var gd = document.getElementById(id);
Plotly.update(id).then(attach);
function attach()
var cnt = 0;
function run()
rotate('scene', Math.PI / 180);
requestAnimationFrame(run);
run();
function rotate(id, angle)
var eye0 = gd.layout[id].camera.eye
var rtz = xyz2rtz(eye0);
rtz.t += angle;
var eye1 = rtz2xyz(rtz);
Plotly.relayout(gd, id + '.camera.eye', eye1)
function xyz2rtz(xyz)
return
r: Math.sqrt(xyz.x * xyz.x + xyz.y * xyz.y),
t: Math.atan2(xyz.y, xyz.x),
z: xyz.z
;
function rtz2xyz(rtz)
return
x: rtz.r * Math.cos(rtz.t),
y: rtz.r * Math.sin(rtz.t),
z: rtz.z
;
;
")
)
shinyApp(ui, server)
【讨论】:
以上是关于如何在 R 中旋转 3D Plotly,更新?的主要内容,如果未能解决你的问题,请参考以下文章
如何映射分类变量以在 R Plotly 中为 3D 散点图中的点轮廓着色?
如何更新第二个绘图轴 plotly Scatter3D subplots