2015-06-10 4 views
6

In un previous question Ho chiesto come ottenere posizioni delle linee di margine nelle coordinate dell'utente. Ho ricevuto una risposta eccellente sotto forma della funzione line2user. Tuttavia, non riesco a capire come modificare la funzione affinché funzioni quando l'asse x o y si trova su una scala di registro.Ottenere le posizioni della linea di margine nello spazio di registrazione

ho fatto un paio di modifiche per accogliere un asse di log-in scala:

line2user <- function(line, side, log = "") { 
    lh <- par('cin')[2] * par('cex') * par('lheight') 
    x_off <- diff(grconvertX(0:1, 'inches', 'user')) 
    y_off <- diff(grconvertY(0:1, 'inches', 'user')) 
    usr <- par('usr') ## Added by me 
    if (grepl("x", log)) usr[1:2] <- 10^usr[1:2] ## Added by me 
    if (grepl("y", log)) usr[3:4] <- 10^usr[3:4] ## Added by me 
    switch(side, 
     `1` = usr[3] - line * y_off * lh, 
     `2` = usr[1] - line * x_off * lh, 
     `3` = usr[4] + line * y_off * lh, 
     `4` = usr[2] + line * x_off * lh, 
     stop("Side must be 1, 2, 3, or 4", call.=FALSE)) 
} 

Tuttavia, non riesco a capire come regolare correttamente le variabili xoff e yoff per disegnare le linee corrette. Illustrazione:

setup_plot <- function(log = "") { 
    par(mar = c(2, 10, 2, 2), oma = rep(2, 4)) 
    plot.new() 
    plot.window(xlim = c(1, 10), ylim = c(1, 10), log = log) 
    box(which = "plot", lwd = 2, col = "gray40") 
    box(which = "figure", lwd = 2, col = "darkred") 
    box(which = "outer", lwd = 2, col = "darkgreen") 
    text(x = 0.5, y = 0.5, 
     labels = "Plot Region", 
     col = "gray40", font = 2) 
    mtext(side = 3, text = "Figure region", line = 0.5, col = "darkred", font = 2) 
    mtext(side = 3, text = "Device region", line = 2.5, col = "darkgreen", font = 2) 
    for (i in 0:9) { 
    mtext(side = 2, col = "darkred", text = paste0("Line", i), line = i) 
    } 
} 

setup_plot(log = "x") 
abline(v=line2user(line=0:9, side=2, log = "x"), xpd=TRUE, lty=2) 

enter image description here

Le linee compressi ha senso dopo aver considerato il seguente esempio:

plot(10) 
diff(grconvertX(0:1, 'inches', 'user')) 
## [1] 0.08121573 (on my device) 

plot(10, log = "x") 
diff(grconvertX(0:1, 'inches', 'user')) 
## [1] 0.0297354 (on my device) 

Come posso ottenere le corrette x_off e y_off valori quando si lavora con un asse di log-in scala ?

risposta

6

Ecco una versione che funziona con scala di registro e assi scala lineare. Il trucco è di esprimere le posizioni delle linee nelle coordinate npc invece delle coordinate user, poiché queste ultime non sono ovviamente lineari quando gli assi si trovano su scale di registro.

line2user <- function(line, side) { 
    lh <- par('cin')[2] * par('cex') * par('lheight') 
    x_off <- diff(grconvertX(c(0, lh), 'inches', 'npc')) 
    y_off <- diff(grconvertY(c(0, lh), 'inches', 'npc')) 
    switch(side, 
     `1` = grconvertY(-line * y_off, 'npc', 'user'), 
     `2` = grconvertX(-line * x_off, 'npc', 'user'), 
     `3` = grconvertY(1 + line * y_off, 'npc', 'user'), 
     `4` = grconvertX(1 + line * x_off, 'npc', 'user'), 
     stop("Side must be 1, 2, 3, or 4", call.=FALSE)) 
} 

E qui sono un paio di esempi, applicato al tuo setup_plot con mar=c(5, 5, 5, 5):

setup_plot() 
axis(1, line=5) 
axis(2, line=5) 
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE) 
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE) 

enter image description here

setup_plot(log='x') 
axis(1, line=5) 
axis(2, line=5) 
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE) 
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE) 

enter image description here

setup_plot(log='y') 
axis(1, line=5) 
axis(2, line=5) 
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE) 
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE) 

enter image description here

setup_plot(log='xy') 
axis(1, line=5) 
axis(2, line=5) 
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE) 
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE) 
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE) 

enter image description here