2012-05-30 211 views
5

我正在繪製一些使用plot3d()的點數據。 我想讓我的y軸刻度標籤更接近我的y軸刻度標記。R rgl軸刻度和刻度標記之間的距離

我能想到這樣做的最好的方法是

1)第一繪製數據,無圖紙的軸

2)調用上axis3d()來繪製y軸和刻度線,但抑制標籤被繪製。 3)查詢3D空間中每個刻度標記的當前位置。將位置存儲在矢量中。

4)使用mtext3d()以基於調整到矢量

我有在步驟3中的問題,我不知道如何查詢每個刻度的位置位置添加標籤。 par3d()允許你查詢一些圖形參數,有沒有類似的東西可以用來獲得每個y軸的座標?

我接近這個錯誤嗎?大概。

下面是一個例子一段代碼,不添加用於Y軸標籤文本....

require(rgl) 
x <- rnorm(5) 
y <- rnorm(5) 
z <- rnorm(5) 
open3d() 
plot3d(x,y,z,axes=F,xlab="",ylab="",zlab="") 
par3d(ignoreExtent=TRUE) 
par3d(FOV=0) 
par3d(userMatrix=rotationMatrix(0,1,0,0)) 
axis3d('y',nticks=5,labels = FALSE) 
par3d(zoom=1) 
par3d(windowRect=c(580,60,1380,900)) 

回答

2

一種方式做,這是繪製軸線,而不是查詢之前明確地定義蜱位置他們繪製軸後。然後你可以使用的mtext3dline=選項從軸這樣的控制刻度標記的距離:

require(rgl) 
rgl.close() 
x <- rnorm(5) 
y <- rnorm(5) 
z <- rnorm(5) 
open3d() 
plot3d(x,y,z,axes=F,xlab="",ylab="",zlab="") 
par3d(ignoreExtent=TRUE) 
par3d(FOV=0) 
par3d(userMatrix=rotationMatrix(0,1,0,0)) 
par3d(zoom=1) 
par3d(windowRect=c(580,60,1380,900)) 

# and here is the trick: 
my.ticks <- pretty(y, n=5) 
axis3d('y', at=my.ticks, labels=rep("", 5)) 
mtext3d(paste(my.ticks), at=my.ticks, edge='y', line=.6) 
1

我發現,同時控制標籤位置和axis3d蜱長度的最簡單的方法是重寫該函數添加了一些額外的參數ticksizelab_dist,它們可以用來覆蓋函數中嵌入的默認值。默認值ticksize = 0.05lab_dist = 3重現原始axis3d的行爲。

要獲得更小的刻度和更接近的標籤,可以使用例如

axis3('y', nticks=5, labels = FALSE, ticksize = 0.03, lab_dist = 2) 

新功能看起來是這樣的:

axis3 <- function (edge, at = NULL, labels = TRUE, tick = TRUE, line = 0, 
      pos = NULL, nticks = 5, ticksize = 0.05, lab_dist = 3, ...) 
{ 
    save <- par3d(skipRedraw = TRUE, ignoreExtent = TRUE) 
    on.exit(par3d(save)) 
    ranges <- rgl:::.getRanges() 
    edge <- c(strsplit(edge, "")[[1]], "-", "-")[1:3] 
    coord <- match(toupper(edge[1]), c("X", "Y", "Z")) 
    if (coord == 2) 
    edge[1] <- edge[2] 
    else if (coord == 3) 
    edge[1:2] <- edge[2:3] 
    range <- ranges[[coord]] 
    if (is.null(at)) { 
    at <- pretty(range, nticks) 
    at <- at[at >= range[1] & at <= range[2]] 
    } 
    if (is.logical(labels)) { 
    if (labels) 
     labels <- format(at) 
    else labels <- NA 
    } 
    mpos <- matrix(NA, 3, length(at)) 
    if (edge[1] == "+") 
    mpos[1, ] <- ranges$x[2] 
    else mpos[1, ] <- ranges$x[1] 
    if (edge[2] == "+") 
    mpos[2, ] <- ranges$y[2] 
    else mpos[2, ] <- ranges$y[1] 
    if (edge[3] == "+") 
    mpos[3, ] <- ranges$z[2] 
    else mpos[3, ] <- ranges$z[1] 
    ticksize <- ticksize * (mpos[, 1] - c(mean(ranges$x), mean(ranges$y), 
            mean(ranges$z))) 
    ticksize[coord] <- 0 
    if (!is.null(pos)) 
    mpos <- matrix(pos, 3, length(at)) 
    mpos[coord, ] <- at 
    x <- c(mpos[1, 1], mpos[1, length(at)]) 
    y <- c(mpos[2, 1], mpos[2, length(at)]) 
    z <- c(mpos[3, 1], mpos[3, length(at)]) 
    if (tick) { 
    x <- c(x, as.double(rbind(mpos[1, ], mpos[1, ] + ticksize[1]))) 
    y <- c(y, as.double(rbind(mpos[2, ], mpos[2, ] + ticksize[2]))) 
    z <- c(z, as.double(rbind(mpos[3, ], mpos[3, ] + ticksize[3]))) 
    } 
    result <- c(ticks = segments3d(x, y, z, ...)) 
    if (!all(is.na(labels))) 
    result <- c(result, labels = text3d(mpos[1, ] + lab_dist * ticksize[1], 
             mpos[2, ] + lab_dist * ticksize[2], 
             mpos[3, ] + lab_dist * ticksize[3], 
             labels, ...)) 
    lowlevel(result) 
}