[R-sig-Geo] How to draw a map as PDF which shows the exact given view port only and without any border (PDF crop)
Hans-Jörg Bibiko
bibiko at eva.mpg.de
Thu Dec 10 17:13:04 CET 2009
Hi,
I tried to find an answer in the net but up to now without success.
A simple example made with:
R version 2.10.0 (2009-10-26)
x86_64-apple-darwin9.8.0
locale:
[1] C/en_US.UTF-8/C/C/C/C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
My task is to draw a map as PDF of Portugal. My view port is given by the coordinates xlim <- c(-10, -6) and ylim <- c(36.9, 42.5). The width of the viewport has to be 5in (for a publication). Due to the ratio of xlim and ylim the height is 7in. OK.
I tried:
# ________________________________________
library(maptools)
data(wrld_simpl)
# my view port
xlim <- c(-10, -6)
ylim <- c(36.9, 42.5)
pdf(file = "map_1.pdf", width = 5, height = 7, bg = "azure2")
plot(wrld_simpl, xlim = xlim, ylim = ylim, col = "khaki")
# my actual view port as reference
rect(xlim[1], ylim[1], xlim[2], ylim[2], border = "red")
dev.off()
# ________________________________________
and ended up in Figure 1 (see attachment). My view port is shown as a red rectangle. As you can see the PDF contains more as I expected.
After some empirical attempts I came up with a wrapper function "pdfNoBorder". Thus I tried it again with that function:
# ________________________________________
library(maptools)
data(wrld_simpl)
pdfNoBorder <- function(file, width, height, xlim, ylim,
asp = 1, ...) {
if (missing(width) && missing(height)) {
stop("At least width or height must be given")
}
if (missing(xlim) && missing(ylim)) {
stop("xlim and ylim must be given")
}
if (missing(width)) {
width = diff(xlim)/diff(ylim) * height
}
if (missing(height)) {
height = width/(diff(xlim)/diff(ylim))
}
pdf(file = file, width = width, height = height, ...)
par(mai = rep(0, 4))
plot.new()
par(fin = c(width * 1.08, height * 1.08), new = T) ### !!!!!
plot.window(xlim = xlim, ylim = ylim, asp = asp)
}
# my view port
xlim <- c(-10, -6)
ylim <- c(36.9, 42.5)
pdfNoBorder(file = "map_2.pdf", width = 5, xlim = xlim, ylim = ylim,
bg = "azure2")
plot(wrld_simpl, add = TRUE, col = "khaki")
rect(xlim[1], ylim[1], xlim[2], ylim[2], border = "red")
dev.off()
# ________________________________________
and Figure 2 shows the result. So far so good, but if you look at the "pdfNoBorder" function I have to use "an empirical hack" namely the line:
par(fin = c(width * 1.08, height * 1.08), new = T)
The value 1.08 works "quite well" but I think that this value is a function of width, height, and the ratio width/height or similar and - of course - it's not precisely.
My question is now whether somebody could give my an hint how to draw a PDF map which shows ONLY my desired view port and without any border by using a "clean" way without any estimated values.
Many thanks in advance,
--Hans
Figure 1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: map_1.pdf
Type: application/pdf
Size: 4482 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-sig-geo/attachments/20091210/b44d96e4/attachment.pdf>
-------------- next part --------------
Figure 2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: map_2.pdf
Type: application/pdf
Size: 4283 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-sig-geo/attachments/20091210/b44d96e4/attachment-0001.pdf>
-------------- next part --------------
More information about the R-sig-Geo
mailing list