[英]How to center the axes in Plotly on a 3d scatter plot in R?
I have a 3d scatter plot that I created with Plotly in R - is there anyway to move the axes to the middle?我有一个 3d 散点图 plot,它是我在 R 中用 Plotly 创建的 - 是否可以将轴移动到中间? My plot right now looks similar to this plot that I made real quick in R:我的 plot 现在看起来与我在 R 中快速制作的 plot 相似:
But I would like to remove the grid background, the axis ticks, and move the axes to the middle of the plot to make it look similar to this:但我想删除网格背景、轴刻度,并将轴移动到 plot 的中间,使其看起来类似于:
My main problem is moving the axes to the middle while maintaining the x, y, and z labels on them.我的主要问题是将轴移动到中间,同时保持轴上的 x、y 和 z 标签。 I have used traces to simulate the central axes, but then I have the issue of no axis labels when I remove the background grid and axes.我已经使用轨迹来模拟中心轴,但是当我删除背景网格和轴时,我遇到了没有轴标签的问题。 What is the best way to go about this?关于这个,go 最好的方法是什么?
The code to recreate the first plot is below as well:重新创建第一个 plot 的代码也在下面:
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
How about this?这个怎么样?
If you make the text bold:如果将文本设为粗体:
I think it would look better if I could make the text bold.我想如果我能把文字加粗会更好看。 In the object annots
that will be made in the function getvals
.在将在 function annots
中生成的 object getvals
。 Where you see text = "x"
(y or z), if you prefer bold, annotate like text = "<b>x</b>"
.在您看到text = "x"
(y 或 z)的地方,如果您喜欢粗体,请注释为text = "<b>x</b>"
。
I tried to make this dynamic so that it could be more readily repurposed, but I didn't test any Plotly possible extremes.我试图使它动态化,以便更容易地重新利用它,但我没有测试任何 Plotly 可能的极端情况。 It is based on the assumption that there is only 1 trace and that that trace is a scatter3d
.它基于只有 1 条轨迹并且该轨迹是scatter3d
的假设。
I want to point out that marking the lines as mode = "lines"
was continuously trumped by Plotly, rendering as lines+markers
.我想指出的是,将线标记为mode = "lines"
一直被 Plotly 打败,呈现为lines+markers
。 If I didn't designate it as lines+markers
, I couldn't control the markers, either.如果我不指定它为lines+markers
,我也无法控制标记。 That's why you see markers called but essentially hidden.这就是为什么您会看到标记被调用但基本上隐藏的原因。
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
}
}
Using that function使用那个 function
Take your original plot, less the call for layout
.拿你原来的 plot,减去layout
电话。 I added showlegend = F
, because when the other traces are added, it would have created a legend.我添加了showlegend = F
,因为当添加其他痕迹时,它会创建一个图例。 You could pipe this to the plot, or do it like this.您可以将 pipe 转为 plot,或者这样做。
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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.