2012-05-30 4 views
5

Sto tracciando dei dati punto usando plot3d(). Vorrei portare le mie etichette di spunta sull'asse y un po 'più vicino ai segni di graduazione dell'asse y.R rgl distanza tra le tacche degli assi e le etichette delle tacche

Il modo migliore che posso pensare di fare questo è quello di

1) tracciare i dati prima, senza disegnare gli assi

2) invitare axis3d() per disegnare l'asse Y e segni di graduazione, ma sopprimere le etichette dall'essere disegnate.

3) interrogare la posizione corrente di ciascun segno di spunta nello spazio 3D. Memorizza le posizioni in un vettore.

4) Utilizzare mtext3d() per aggiungere etichette alle posizioni sulla base di un adeguamento al vettore

Sto avendo un problema al punto 3. Non so come interrogare la posizione di ogni segno di spunta. par3d() ti permette di interrogare un numero di parametri grafici, c'è qualcosa di simile che posso usare per ottenere la posizione di ogni asse?

Mi sto avvicinando a questo torto? Probabilmente.

Ecco un pezzo esempio di codice, senza testo aggiunto per etichette dell'asse 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)) 

risposta

2

Un modo per fare questo è quello di definire esplicitamente le posizioni tick prima di disegnare l'asse, invece di interrogazione loro dopo aver disegnato l'asse. Quindi è possibile utilizzare l'opzione line= di mtext3d per controllare la distanza delle etichette di graduazione dall'asse come questo:

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

Ho trovato che il modo più semplice per controllare sia la posizione dell'etichetta e spuntare la lunghezza in axis3d è di riscrivere la funzione con un paio di parametri aggiuntivi ticksize e lab_dist aggiunti che possono essere utilizzati per sovrascrivere i valori predefiniti incorporati nella funzione. I valori predefiniti di ticksize = 0.05 e lab_dist = 3 riproducono il comportamento dell'originale axis3d.

Per ottenere tick più piccoli e etichette più vicine, è possibile chiamarlo con es.

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

La nuova funzione è simile al seguente:

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) 
}