2015-03-18 9 views
9

Sto tentando di eseguire un'etichettatura di plottaggio non convenzionale e vorrei un modo per convertire il parametro in mtext e axis in coordinate utente.Ottieni posizioni linea di margine (mgp) nelle coordinate utente

In altre parole, mi piacerebbe convertire i valori in par()$mgp in coordinate utente.

Questo illustra il problema:

setup_plot <- function() { 
    par(mar = c(2, 10, 2, 2), oma = rep(2, 4)) 
    plot.new() 
    plot.window(xlim = c(0, 1), ylim = c(0, 1)) 
    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) 
    } 
} 

Ho provato due diversi approcci.

## Try one approach where a line is the string height of "M" 
setup_plot() 
xline = strheight("M", units = "user") 
abline(v = par()$usr[1] - 0:9*xline, 
     xpd = TRUE, lty = "dashed", col = "gray40") 

Lines do not line up with the text

## Try a second approach defining a line using par()$mai & par()$mar 
setup_plot() 
xline = abs(grconvertX(unique(par()$mai/par()$mar), "inches", "user")) 
abline(v = par()$usr[1] - 0:9*xline, 
     xpd = TRUE, lty = "dashed", col = "gray40") 

Only one line is drawn

Come si ottiene la posizione retta in coordinate utente?

NOTA: Le cifre qui sono 4 pollici per 6 pollici. Cambiare la dimensione dell'output cambia il modo in cui vengono disegnate le linee - che per me non ha senso.

+0

Questa non è la risposta che state cercando, ma è qualcosa che si potrebbe usare se tutto il resto fallisce: 'mtext (lato = 2, col = "gray40", text = pasta (rep ("_", 45), collapse = ""), line = c (0: 9)) ' – Jota

+0

Questo è un trucco intelligente, ma in realtà non mi interessa disegnare linee. Stavo solo usando le linee per illustrare che non so come ottenere le posizioni corrette. – dayne

risposta

9

Il seguente dovrebbe fare il trucco:

setup_plot() 
abline(v=par('usr')[1] - (0:9) * 
     diff(grconvertX(0:1, 'inches', 'user')) * 
     par('cin')[2] * par('cex') * par('lheight'), 
     xpd=TRUE, lty=2) 

margin_lines

par('cin')[2] * par('cex') * par('lheight') restituisce l'altezza della linea di corrente in pollici, che convertiamo all'utente le coordinate moltiplicando per diff(grconvertX(0:1, 'inches', 'user')), la lunghezza di un pollice a utente coordinate (orizzontalmente, in questo caso - se interessati all'altezza verticale di una linea in user coords useremmo diff(grconvertY(0:1, 'inches', 'user'))).

Questo può essere avvolto in una funzione per comodità come segue:

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

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

EDIT: Una versione aggiornata della funzione, che lavora con assi registrate, è disponibile here.

+0

Ho chiesto una domanda di follow-up se sei interessato: http://stackoverflow.com/questions/30765866/get-margin-line-locations-in-log-space – dayne

Problemi correlati