2015-06-10 14 views
6

W numerze previous question zapytałem, jak uzyskać lokalizacje linii marginesowej we współrzędnych użytkownika. Otrzymałem doskonałą odpowiedź w postaci funkcji line2user. Jednak nie mogę wymyślić, jak zmodyfikować funkcję do pracy, gdy oś x lub y znajduje się w skali logarytmicznej.Uzyskiwanie lokalizacji linii marginesowej w obszarze dziennika

zrobiłem kilka modyfikacji w celu dostosowania oś dziennika skalowane:

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

Jednak nie mogę dowiedzieć się, jak prawidłowo dopasować xoff i yoff zmienne wyciągnąć odpowiednie linie. Ilustracja:

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

sprężonego linii sensu po rozważeniu następujący przykład:

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) 

Jak mogę uzyskać poprawne x_off i y_off wartości podczas pracy z osią dziennika skalowane ?

Odpowiedz

6

Oto wersja, która działa z osiami skali liniowej i. Sztuką jest wyrażanie położenia linii w współrzędnych npc zamiast współrzędnych user, ponieważ te ostatnie nie są oczywiście liniowe, gdy osie znajdują się na skalach logarytmicznych.

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

A oto kilka przykładów, zastosowane do setup_plot z 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

Powiązane problemy