I think both packages have good reasons to not want to depend on
eachother, as integrating this in one of them would imply. Your solution
seems a reasonable one to me.

On 12/15/2010 02:07 PM, Hadley Wickham wrote:
> I have a student who is interested in working on more spatial features
> for ggplot2 this summer. That work is likely to involve separating out
> all spatial features from ggplot2 into their own package and that
> would be a good place for this.
> 
> Hadley
> 
> On Wednesday, December 15, 2010, Paul Hiemstra <p.hiems...@geo.uu.nl> wrote:
>> Hi people,
>>
>> I posted a similar question to the ggplot2 mailing list and with their help 
>> and a lot of tinkering I got a well working function to add a scalebar to a 
>> ggplot plot. I could add the function to automap, but is there another 
>> package which would be more appropraite, e.g. sp (Roger?)?
>>
>> cheers,
>> Paul
>>
>> ps: new version of code here:
>>
>> makeNiceNumber = function(num, num.pretty = 1) {
>>   # Rounding provided by code from Maarten Plieger
>>   return((round(num/10^(round(log10(num))-1))*(10^(round(log10(num))-1))))
>> }
>>
>> createBoxPolygon = function(llcorner, width, height) {
>>   relativeCoords = data.frame(c(0, 0, width, width, 0), c(0, height, height, 
>> 0, 0))
>>   names(relativeCoords) = names(llcorner)
>>   return(t(apply(relativeCoords, 1, function(x) llcorner + x)))
>> }
>>
>> addScaleBar = function(ggplot_obj, spatial_obj, attribute, addParams = 
>> list()) {
>>   addParamsDefaults = list(noBins = 5, xname = "x", yname = "y", unit = "m", 
>> placement = "bottomright",
>>                            sbLengthPct = 0.3, sbHeightvsWidth = 1/14)
>>   addParams = modifyList(addParamsDefaults, addParams)
>>
>>   range_x = max(spatial_obj[[addParams[["xname"]]]]) - 
>> min(spatial_obj[[addParams[["xname"]]]])
>>   range_y = max(spatial_obj[[addParams[["yname"]]]]) - 
>> min(spatial_obj[[addParams[["yname"]]]])
>>   lengthScalebar = addParams[["sbLengthPct"]] * range_x
>>   ## OPTION: use pretty() instead
>>   widthBin = makeNiceNumber(lengthScalebar / addParams[["noBins"]])
>>   heightBin = lengthScalebar * addParams[["sbHeightvsWidth"]]
>>   lowerLeftCornerScaleBar = c(x = max(spatial_obj[[addParams[["xname"]]]]) - 
>> (widthBin * addParams[["noBins"]]),
>>                               y = min(spatial_obj[[addParams[["yname"]]]]))
>>
>>   scaleBarPolygon = do.call("rbind", lapply(0:(addParams[["noBins"]] - 1), 
>> function(n) {
>>     dum = data.frame(createBoxPolygon(lowerLeftCornerScaleBar + c((n * 
>> widthBin), 0), widthBin, heightBin))
>>     if(!(n + 1) %% 2 == 0) dum$cat = "odd" else dum$cat = "even"
>>     return(dum)
>>   }))
>>   scaleBarPolygon[[attribute]] = min(spatial_obj[[attribute]])
>>   textScaleBar = data.frame(x = 
>> lowerLeftCornerScaleBar[[addParams[["xname"]]]] + 
>> (c(0:(addParams[["noBins"]])) * widthBin),
>>                             y = 
>> lowerLeftCornerScaleBar[[addParams[["yname"]]]],
>>                             label = as.character(0:(addParams[["noBins"]]) * 
>> widthBin))
>>   textScaleBar[[attribute]] = min(spatial_obj[[attribute]])
>>
>>   return(ggplot_obj +
>>     geom_polygon(data = subset(scaleBarPolygon, cat == "odd"), fill = 
>> "black", color = "black", legend = FALSE) +
>>     geom_polygon(data = subset(scaleBarPolygon, cat == "even"), fill = 
>> "white", color = "black", legend = FALSE) +
>>     geom_text(aes(label = label), color = "black", size = 6, data = 
>> textScaleBar, hjust = 0.5, vjust = 1.2, legend = FALSE))
>> }
>>
>> library(ggplot2)
>> library(sp)
>>
>> data(meuse)
>> data(meuse.grid)
>> ggobj = ggplot(aes(x = x, y = y, color = zinc), data = meuse) + geom_point()
>> # Make sure to increase the graphic device a bit
>> addScaleBar(ggobj, meuse, "zinc", addParams = list(noBins = 5))
>>
>>
>> On 11/18/2010 09:12 PM, Paul Hiemstra wrote:
>>
>> Dear list,
>>
>> A common addition to any spatial plot are a north arrow and a scale bar. 
>> I've searched online for a straightforward way to add those to a ggplot 
>> plot. I then decided to give a go myself. A crude first attempt for an 
>> automatic scalebar addition function is listed below. The example works for 
>> the meuse dataset, but a second with a different dataset did yield good 
>> results.
>>
>> My question to you is: is there anyone who has some good tips / example code 
>> to add a north arrow and a scalebar to a ggplot image. Any expansions on the 
>> code below are also welcome.
>>
>> cheers,
>> Paul
>>
>> ps Some info on my system is listed at the very bottom
>>
>> library(sp)
>> library(ggplot2)
>>
>> data(meuse)
>> data(meuse.grid)
>>
>> string.length = function(s) {
>> #  browser()
>>   if(!is.character(s)) s = as.character(s)
>>   length(strsplit(s, "")[[1]])
>> }
>>
>> makeNiceNumber = function(num, num.pretty = 1) {
>>   noNumbers = string.length(as.character(round(num)))
>>   return(round(num / 10^(noNumbers - num.pretty)) * 10^(noNumbers - 
>> num.pretty))
>> }
>>
>> makeScaleBar = function(obj, plotname, xname = "x", yname = "y", unit = "m", 
>> placement = "bottomright") {
>> #     browser()
>>   range_x = max(obj[[xname]]) - min(obj[[xname]])
>>   range_y = max(obj[[yname]]) - min(obj[[yname]])
>>   if(placement == "bottomright") {
>>     xcoor.max = makeNiceNumber(max(obj[[xname]]) - (0.05 *range_x ), 
>> string.length(round(max(obj[[xname]]))) - string.length(round(0.3 * 
>> range_x)))
>>     xcoor.min = makeNiceNumber(max(obj[[xname]]) - (0.5 *range_x ), 
>> string.length(round(max(obj[[xname]]))) - string.length(round(0.3 * 
>> range_x)))
>>     ycoor = min(obj[[yname]]) + (0.05 * range_y)
>>   } else {
>>     xcoor.min = makeNiceNumber(max(obj[[xname]]) - (0.95 *range_x ), 
>> string.length(round(max(obj[[xname]]))) - string.length(round(0.3 * 
>> range_x)))
>>     xcoor.max = makeNiceNumber(max(obj[[xname]]) - (0.5 *range_x ), 
>> string.length(round(max(obj[[xname]]))) - string.length(round(0.3 * 
>> range_x)))
>>     ycoor = min(obj[[yname]]) + (0.95 * range_y)
>>   }
>>   scalebar.data = data.frame(x = c(xcoor.max, xcoor.min), y = ycoor, lbl = 
>> c(paste(xcoor.max - xcoor.min, unit), 0))
>>   scalebar.data[[plotname]] = min(obj[[plotname]])
>>   return(list(geom_path(aes(x = x, y = y), data = scalebar.data, lwd = 2, 
>> color = "black"),
>>           geom_text(aes(x = x, y = y, label = lbl), data = scalebar.data, 
>> vjust = 1.3)))
>> }
>>
>> sb = makeScaleBar(meuse.grid, "dist", placement = "topright")
>> ggplot(aes(x  = x, y = y, fill = dist), data = meuse.grid) + geom_tile() + 
>> sb[[1]] + sb[[2]]
>>
>> R version 2.12.0 (2010-10-15)
>> Platform: i486-pc-linux-gnu (32-bit)
>>
>> locale:
>>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
>>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
>>  [5] LC_MONETARY=C              LC_MESSAGES=en_US.UTF-8
>>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
>>  [9] LC_ADDRESS=C               LC_TELEPHONE=C
>> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
>>
>> attached base packages:
>> [1] grid      stats     graphics  grDevices utils     datasets  methods
>> [8] base
>>
>> other attached packages:
>> [1] ggplot2_0.8.7 digest_0.4.2  reshape_0.8.3 plyr_0.1.9    proto_0.3-8
>> [6] sp_0.9-62
>>
>> loaded via a namespace (and not attached):
>> [1] lattice_0.19-13
>>
>> hiems...@fg-113:~$ uname -a
>> Linux fg-113 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010 
>> i686 GNU/Linux
>>
>>
>>
>>
>> --
>> Paul Hiemstra, MSc
>> Department of Physical Geography
>> Faculty of Geosciences
>> University of Utrecht
>> Heidelberglaan 2
>> P.O. Box 80.115
>> 3508 TC Utrecht
>> Phone:  +3130 253 5773
>> http://intamap.geo.uu.nl/~paul
>> http://nl.linkedin.com/pub/paul-hiemstra/20/30b/770
>>
>> currently @ KNMI
>> paul.hiemstra_AT_knmi.nl
>>
>> _______________________________________________
>> R-sig-Geo mailing list
>> R-sig-Geo@r-project.org
>> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>>
> 

-- 
Edzer Pebesma
Institute for Geoinformatics (ifgi), University of Münster
Weseler Straße 253, 48151 Münster, Germany. Phone: +49 251
8333081, Fax: +49 251 8339763  http://ifgi.uni-muenster.de
http://www.52north.org/geostatistics      e.pebe...@wwu.de

_______________________________________________
R-sig-Geo mailing list
R-sig-Geo@r-project.org
https://stat.ethz.ch/mailman/listinfo/r-sig-geo

Reply via email to