如何在R中使用Plotly将3D散点图的坐标轴居中?

3

我用R中的Plotly创建了一个3D散点图,有没有办法将坐标轴移动到中间?我的图表现在看起来类似于我在R中快速制作的这个图:

enter image description here

但我希望移除网格背景,坐标轴刻度,并将坐标轴移动到图表中央,使其看起来与此类似:

enter image description here

我的主要问题是如何将轴移动到中间,同时保持x、y和z标签。我使用轨迹来模拟中心轴,但是当我删除背景网格和轴时,就会出现没有轴标签的问题。如何最好地解决这个问题?
下面是重新创建第一个图的代码:
coords = list("x"=c(), "y"=c(), "z"=c())
for(phi in seq(0, 2*pi, 0.2)) {
  for(theta in seq(0, pi, 0.2)) {
    x = (8 * sin(theta) * cos(phi))
    y = (8 * sin(theta) * sin(phi))
    z = (8 * cos(theta))
    coords$x = append(coords$x, x)
    coords$y = append(coords$y, y)
    coords$z = append(coords$z, z)
  }
}
df = data.frame("x"=coords$x, "y"=coords$y, "z"=coords$z)
fig = plot_ly(df, x=~x, y=~y, z=~z, type="scatter3d",
              mode="markers", marker=list(size=3))
fig = layout(fig, scene=list(xaxis=list(range=c(-12, 12)),
                             yaxis=list(range=c(-12, 12)),
                             zaxis=list(range=c(-12, 12))))
fig

我不确定这个答案是否适用于3D plotly,但是值得一看。https://dev59.com/DmoMtIcB2Jgan1znh10x - IRTFM
1个回答

1

这个怎么样?

enter image description here

如果你想要加粗文本:enter image description here

我认为如果我可以让文本加粗,它会看起来更好。在函数getvals中将创建的对象annots中,当你看到text = "x"(y或z)时,如果你想要加粗,就注释如下text = "<b>x</b>"

我试图使其动态化,以便更容易地重新使用,但我没有测试任何可能的Plotly极端情况。它基于这样一个假设:只有1个跟踪器,并且该跟踪器是scatter3d

我想指出,将线标记为mode = "lines"一直被Plotly推翻,渲染为lines+markers。如果我不将其指定为lines+markers,我也无法控制标记。这就是为什么你看到标记被调用但实际上被隐藏的原因。

getvals <- function(plt) {
  plt <- plotly_build(plt) # ensure data is in object
  if(isTRUE(length(plt$x$data) == 1)) {
    df1 <- data.frame(x = plt$x$data[[1]]$x, # extract data
                      y = plt$x$data[[1]]$y,
                      z = plt$x$data[[1]]$z)
    mx <- max(df1$x); my <- max(df1$y); mz <- max(df1$z) # for segments
    nx <-.25 * mx; ny <- .25 * my; nz <- .25 * mz # for line segment size
    d <- colMeans(df1)
    dx <- d[[1]]; dy <- d[[2]]; dz <- d[[3]]     # line segment center
    hx <- dx + nx; hy <- dy + ny; hz <- dz + nz  # line segment high
    lx <- dx - nx; ly <- dy - ny; lz <- dz - nz  # line segment low
    plt <- plt %>%  # add the traces for the internal axes indic.
      add_trace(x = c(lx, hx), y = c(dy, dy), z = c(dz, dz), # x axis line
                mode = "lines+markers", 
                hoverinfo = "skip", marker = list(size = .01),
                line = list(color = "black", width = 3)) %>% 
      add_trace(x = c(dx, dx), y = c(ly, hy), z = c(dz, dz), # y axis line
                mode = "lines+markers",
                hoverinfo = "skip", marker = list(size = .01),
                line = list(color = "black", width = 3)) %>% 
      add_trace(x = c(dx, dx), y = c(dy, dy), z = c(lz, hz), # z axis line
                mode = "lines+markers", 
                hoverinfo = "skip", marker = list(size = .01),
                line = list(color = "black", width = 3)) %>% 
      add_trace(x = dx, y = dy, z = dz, type = "scattered",  # center ball
                mode = "markers", hoverinfo = "skip", 
                marker = list(size = 8, color = "black"))
    annots <- list(                   # text annotations x, y, z
      list(showarrow = F, x = hx, y = dy, z = dz,
           text = "x", xanchor = "right", xshift = -5,
           font = list(size = 20)),
      list(showarrow = F, x = dx, y = hy, z = dz,
           text = "y", xshift = -5, 
           font = list(size = 20)),
      list(showarrow = F, x = dx, y = dy, z = hz,
           text = "z", xshift = -5,
           font = list(size = 20)))
    assign("annots", annots, envir = .GlobalEnv)
    plt # return plot; send annotations to the global env
  }
}

使用该函数
使用原始图表,但不包括对“layout”的调用。我添加了showlegend = F,因为当添加其他跟踪时,它会创建一个图例。您可以将其导入到图表中,也可以像这样操作。
fig = plot_ly(df, x = ~x, y = ~y, z = ~z, type = "scatter3d",
              mode = "markers", marker = list(size = 3),
              showlegend = F) 

fig %>% getvals() %>% 
  layout(
    scene = list(
      aspectratio = list(x = 1, y = 1, z = 1),
      camera = list(
        center = list(x = 0, y = 0, z = 0),
        eye = list(x = -.5, y = .5, z = .6)),
      up = list(x = 0, y = 0, z = 1),
      xaxis = list(showgrid = FALSE, zeroline = FALSE, range = c(-12, 12),
                   showticklabels = FALSE, title = list(text = "")),
      yaxis = list(showgrid = FALSE, zeroline = FALSE, range = c(-12, 12),
                   showticklabels = FALSE, title = list(text = "")),
      zaxis = list(showgrid = FALSE, zeroline = FALSE, range = c(-12, 12),
                   showticklabels = FALSE, title = list(text = "")),
    dragmode = "turntable",
    annotations = annots
  ), margin = list(t = 30, r = 30, l = 30, b = 30, padding = 2))

这正是我想要做的,并且它非常有效 - 谢谢! - dark-walrus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接