oswaldosantos / ggsn Goto Github PK
View Code? Open in Web Editor NEWR package to add north symbols and scale bars to maps created with ggplot or ggmap
Home Page: http://oswaldosantos.github.io/ggsn/
License: GNU General Public License v2.0
R package to add north symbols and scale bars to maps created with ggplot or ggmap
Home Page: http://oswaldosantos.github.io/ggsn/
License: GNU General Public License v2.0
ggsn only supports one variable faceting. At the moment, when using two variables the scale bar is drawn on multiple facets. For example:
library(rgdal); library(broom); library(dplyr);
dsn <- system.file('extdata', package = 'ggsn')
## Map in geographic coordinates.
map <- readOGR(dsn, 'sp')
map@data$id <- 1:nrow(map@data)
map.df <- merge(tidy(map), map, by = 'id')
map_df <- bind_rows(
map.df %>% mutate(f1 = "a", f2 = "c"),
map.df %>% mutate(f1 = "b", f2 = "c"),
map.df %>% mutate(f1 = "a", f2 = "d"),
map.df %>% mutate(f1 = "b", f2 = "d")
)
ggplot(data = map_df, aes(long, lat, group = group, fill = nots)) +
geom_polygon() +
coord_equal() +
geom_path() +
facet_grid(f1~f2) +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8) +
scalebar(map.df, dist = 5, dd2km = TRUE, model = 'WGS84', facet.var = 'f1', facet.lev = 'a')
Two variable faceting could be specified by supplying a vector of variable names and facet levels.
ggplot(data = map_df, aes(long, lat, group = group, fill = nots)) +
geom_polygon() +
coord_equal() +
geom_path() +
facet_grid(f1~f2) +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8) +
scalebar(map.df, dist = 5, dd2km = TRUE, model = 'WGS84', facet.var = c('f1', 'f2'), facet.lev = c('a', 'b'))
Dear Oswaldo,
just found out about your package. It's very useful, but it could use some more flexibility in my opinion. Have you thought about letting the user modify the scalebar border and fill colors? This would make it more adequate for use on top of e.g. darker satellite images obtained through ggmap (I did run into this you see ...). If you think it is a good idea, I'd be happy to contribute.
Kind regards,
Bart
PS The workaround I use now is adding a transparent white rectangle below the scalebar.
Hi there! i'm noticing some unusual behaviour with the scalebar function and wondered if you had seen this before.
My code is here
# plot ggplot
ggplot() +
geom_polygon(data = study_area_df, aes(x = long, y = lat, group = group),
fill = "white", color = "black") +
geom_path(data = sjer_roads_df, aes(x = long, y = lat,
group = group, size = factor(RTTYP)), colour = "grey") +
scale_size_manual("Road Type", values = c("M" = .3,
"S" = .8,
"Unknown" = .3)) +
geom_point(data = sjer_plots_df, aes(x = coords.x1,
y = coords.x2, shape = factor(plot_type), color = factor(plot_type)), size = 3) +
scale_color_manual("Plot Type", values = c("trees" = "darkgreen",
"grass" = "darkgreen",
"soil" = "brown")) +
scale_shape_manual("Plot Type", values = c("grass" = 18,
"soil" = 15,
"trees" = 8)) +
labs(title = "ggplot() map of roads, plots and study area",
subtitle = "with north arrow and scale bar",
x = "", y = "") + ggsn::blank() +
ggsn::scalebar(sjer_plots_df, dist = 100, dd2km = FALSE, model = 'WGS84', location = "topright",
st.dist = 10, st.size= 10,
anchor = c(x = x_scale_loc, y = y_scale_loc))
and the full tutorial is here:
https://earthdatascience.org/course-materials/earth-analytics/week-4/r-make-maps-with-ggplot-in-R/
this is for my students. am i doing something wrong ? i'm getting characters for the scale bar and no bar. i presume i'm doing something wrong but can't seem to figure out what! my data are in UTM meters.
Thank you for any help.
I am trying to use ggsn::scalebar
in a script that produces maps that could range in area. The default scalebar labels overlap the scalebar.
Is there a way to ensure that this doesn't happen? st.dist
doesn't seem to fit what I am looking for, and it seems like avoiding overlap should be built in by default.
Examples:
ggsn::scalebar(location="bottomleft",
dist = roundup(diff(xlim.set)/10)/1000, #minimum 1/10 of x limits, in km
x.min = xlim.set[1],
x.max = xlim.set[2],
y.min = ylim.set[1],
y.max = ylim.set[2],
dd2km = F,
dist_unit = "km")
ggsn::scalebar(location="bottomleft",
dist = roundup(diff(xlim.set)/10)/1000, #minimum 1/10 of x limits, in km
x.min = xlim.set[1],
x.max = xlim.set[2],
y.min = ylim.set[1],
y.max = ylim.set[2],
dd2km = F,
dist_unit = "km",
st.bottom = F)
Hi Oswaldo,
I was wondering if it's possible to place this scalebar off the face of the map; I'd like to place it more visibly and off the map where it won't interfere with the visual, perhaps below the x axis.
Code for the scalebar is:
scalebar(dist = 50, dd2km = TRUE, model = "WGS84",
st.size = 3, location="bottomleft",
x.min=-71.70774,
x.max=-70.63711,
y.min=41.89158,
y.max=42.7862)
First of all, thank you for this package.
When I have multiple layers to plot, I use to write my ggplot layers as is:
ggplot() +
geom_sf(data = data1) +
geom_sf(data = data2)
In that case, your scalebar continues to work but not the north arrow.
For instance with your example:
dsn <- system.file('extdata', package = 'ggsn')
# Map in geographic coordinates
map <- st_read(dsn, 'sp', quiet = TRUE)
# Map in projected coordinates
map2 <- st_transform(map, 31983)
ggplot() +
geom_sf(data = map2, aes(fill = nots)) +
north(map2, symbol = 16, scale = 0.15) +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8) +
scalebar(map2, dist = 5, dd2km = FALSE)
I do not see where this comes from.
Hello-
I have tried adding a scalebar to a map created in ggplot2, following the code provided in the package documentation, and I have found that the example code no longer works. I've hit the same error when trying to add a scale bar to a map I've created using my own data. Here is the script that I am running, which generates the error. This code is copied and pasted directly from the package documentation file, "ggsn.pdf", page 7:
library(rgdal); library(broom) dsn <- system.file('extdata', package = 'ggsn') map <- readOGR(dsn, 'sp') map@data$id <- 1:nrow(map@data) map.df <- merge(tidy(map), map, by = 'id') ggplot(data = map.df, aes(long, lat, group = group, fill = nots)) + geom_polygon() + coord_equal() + geom_path() + scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8) + scalebar(map.df, dist = 5, dd2km = TRUE, model = 'WGS84')
The error that this generates is as follows:
Error in FUN(left, right) : non-numeric argument to binary operator
For reproducibility, here is my RSessionInfo:
`R version 3.3.3 (2017-03-06)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: macOS Sierra 10.12.3
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] broom_0.4.2 knitr_1.15.1 stringr_1.0.0 readxl_0.1.1 gridExtra_2.2.1
[6] lattice_0.20-34 animation_2.4 dismo_1.0-15 raster_2.5-8 geosphere_1.5-1
[11] wesanderson_0.3.4 scales_0.4.1 maptools_0.9-2 roxygen2_5.0.1 adehabitatHR_0.4.14
[16] adehabitatLT_0.3.20 CircStats_0.2-4 boot_1.3-18 MASS_7.3-45 adehabitatMA_0.3.10
[21] ade4_1.7-4 deldir_0.1-12 rgdal_1.1-10 sp_1.2-4 ggmap_2.6.1
[26] RMySQL_0.10.9 DBI_0.5-1 ggsn_0.4.0 ggplot2_2.2.1 devtools_1.12.0
loaded via a namespace (and not attached):
[1] reshape2_1.4.1 colorspace_1.2-6 foreign_0.8-67 withr_1.0.1 jpeg_0.1-8
[6] plyr_1.8.3 munsell_0.4.3 gtable_0.2.0 RgoogleMaps_1.2.0.7 mapproj_1.2-4
[11] psych_1.7.3.21 memoise_1.0.0 labeling_0.3 parallel_3.3.3 curl_0.9.7
[16] proto_0.3-10 Rcpp_0.12.9 mnormt_1.5-5 rjson_0.2.15 png_0.1-7
[21] digest_0.6.12 stringi_1.1.1 dplyr_0.5.0 RJSONIO_1.3-0 grid_3.3.3
[26] tools_3.3.3 magrittr_1.5 maps_3.1.0 lazyeval_0.2.0 tibble_1.2
[31] tidyr_0.6.0 rsconnect_0.4.3 rstudioapi_0.5 assertthat_0.1 httr_1.1.0
[36] R6_2.2.0 nlme_3.1-131 git2r_0.15.0`
Loading required package: ggsn
Installing package into ‘/gpfs1/homes/uqbababa/.R/library’
(as ‘lib’ is unspecified)
also installing the dependency ‘sf’
downloaded 7.8 MB
downloaded 634 KB
The downloaded source packages are in
‘/gpfs1/scratch/30days/uqbababa/RtmpQeDgXO/downloaded_packages’
Warning messages:
1: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
there is no package called ‘ggsn’
2: In install.packages("ggsn") :
installation of package ‘sf’ had non-zero exit status
3: In install.packages("ggsn") :
installation of package ‘ggsn’ had non-zero exit status
Hello,
I have generated a map in ggplot, but plotted only the area between two sets of coordinates and would like to apply a scalebar. Using the x.min x.max etc. commands, the scale bar does appear, however no text appears.
The warning message "Removed 3 rows containing missing values (geom_text)." appears whenever my code is run.
Below is an example, apologies if it is not suitable. Please let me know if there are any issues with it:
`install.packages('mapdata','maps','maptools')
devtools::install_github("dkahle/ggmap")
library(ggplot2)
library(ggmap)
library(maptools)
library(maps)
library(mapdata)
library(ggsn)
japan <- map_data('japan')
JapanMap <- ggplot() +
geom_polygon(data = japan, aes(x = long, y = lat, group = group)) +
xlim(c(138, 144)) + ylim(c(35, 42)) +
scalebar(x.min = 138, x.max = 144,
y.min = 35, y.max = 42,
dist = 50, dd2km = T, model = 'WGS84', location = 'bottomright',
anchor = c(x = 144, y = 35, st.size = 3))`
Attached is the resultant map with scalebar but missing text
Many thanks,
Aran
library(ggmap)
library(ggplot2)
library(ggsn)
register_google(key = APIKEY)
map_saosebast <- ggmap(get_googlemap("sao sebastiao, sp, brazil",
scale = 2, zoom = 12,
maptype ='terrain',
color = 'color'))
x_lim <- map_saosebast$data[c(1, 4), 1] * c(1, .9998)
y_lim <- map_saosebast$data[c(1, 4), 2] * c(1.003, 1)
map_saosebast + scalebar(x.min = x_lim[1], x.max = x_lim[2],
y.min = y_lim[1], y.max = y_lim[2],
dist = 1, dist_unit = 'km', transform = TRUE, model = 'WGS84')
Warning messages:
1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
3: In min(x) : no non-missing arguments to min; returning Inf
4: In max(x) : no non-missing arguments to max; returning -Inf
5: Removed 3 rows containing missing values (geom_text).
> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 17763)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
attached base packages:
[1] grid stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggsn_0.5.3 ggmap_3.0.0 ggplot2_3.2.1
loaded via a namespace (and not attached):
[1] Rcpp_1.0.2 pillar_1.4.2 compiler_3.6.1 plyr_1.8.4 class_7.3-15 bitops_1.0-6
[7] tools_3.6.1 digest_0.6.20 jsonlite_1.6 tibble_2.1.3 gtable_0.3.0 lattice_0.20-38
[13] pkgconfig_2.0.2 png_0.1-7 rlang_0.4.0 DBI_1.0.0 rstudioapi_0.10 curl_4.0
[19] e1071_1.7-2 withr_2.1.2 dplyr_0.8.3 httr_1.4.1 stringr_1.4.0 RgoogleMaps_1.4.4
[25] classInt_0.4-1 tidyselect_0.2.5 glue_1.3.1 sf_0.7-7 R6_2.4.0 jpeg_0.1-8
[31] foreign_0.8-71 sp_1.3-1 purrr_0.3.2 tidyr_0.8.3 magrittr_1.5 units_0.6-4
[37] scales_1.0.0 maptools_0.9-5 assertthat_0.2.1 colorspace_1.4-1 labeling_0.3 KernSmooth_2.23-15
[43] stringi_1.4.3 lazyeval_0.2.2 munsell_0.5.0 crayon_1.3.4 rjson_0.2.20
Map plots, but no scalebar. Using the values by hand in x.min, etc, produces the same error.
There seems to be a problem in the scalebar()
function when the underlying data are simple features and the plot is faceted.
Reproducible example:
library(ggsn); library(sf)
dsn <- system.file('extdata', package = 'ggsn')
# Map in geographic coordinates
map <- st_read(dsn, 'sp', quiet = TRUE)
(ggm1 <- ggplot(map, aes(fill = nots)) +
geom_sf() +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8))
ggm1 +
blank() +
facet_grid(~ nots) +
north(map) +
scalebar(map, dist = 5, dd2km = TRUE, model = 'WGS84',
facet.var = "nots", facet.lev = "[0,10]")
Throws this error:
Error in sort.list(y) : 'x' must be atomic for 'sort.list'
Have you called 'sort' on a list?
It seems that this line in scalebar()
:
data[, facet.var[i]] <- factor(data[, facet.var[i]])
is the culprit and breaks because data[, facet.var[i]]
returns a simple features data frame containing two variables, nots and geometry. It makes sense to change the right hand side to pull(data, facet.var[i])
but I'm not sure about the best way to change the underlying class to factor on the left hand side. There are also several other spots in the code where factor(data[, facet.var[i]])
should also use pull()
.
I wanted to show scalebar on only one of the facets, but my variable is numeric (years). In that case, selecting a facet adds a new empty facet. I think this maybe due to the transformation to factors in your code. Maybe, you may want to use as.factor(as.character(...))
at some places.
Example:
library(dplyr)
library(ggsn); library(sf)
dsn <- system.file('extdata', package = 'ggsn')
# Map in geographic coordinates
map <- st_read(dsn, 'sp', quiet = TRUE)
map2 <- map %>%
mutate(years = as.numeric(nots) + 2000)
ggplot(map2, aes(fill = nots)) +
geom_sf() +
blank() +
facet_grid(~years) +
north(map2) +
scalebar(map2, dist = 5, dd2km = TRUE, model = 'WGS84',
facet.var = "years", facet.lev = '2001')
Here is an example.
library(ggsn)
library(ggplot2)
levls = c("A", "B", "C")
tmp_data= expand.grid(type = levls,
long = 1:10)
tmp_data$lat = runif(10)
tmp_data$type = factor(tmp_data$type, levels = levls[c(2,1,3)])
g = ggplot(data = tmp_data, aes(x = long, y = lat)) + facet_grid(.~type) + geom_point()
g
g + scalebar(data = tmp_data, location = "topright", facet.var = "type",
facet.lev = "B", dd2km = FALSE,dist = 0.1)
I'd like to be able to conserve a specific order for the levels in the facetting variable. However, using scalebar seems to rearrange them into alphabetical order.
Hi there.
First of all, thanks for the package.
I just wanted to point out an issue with the package gganimate
. While the scale bar works fine for static plots, for some reason it gives problems for animated plots.
Here is a reproducible example inspired from your Readme:
library(ggsn); library(ggplot2); library(sf); library(gganimate)
#> Loading required package: ggplot2
#> Loading required package: grid
#> Linking to GEOS 3.5.1, GDAL 2.1.3, PROJ 4.9.2
data("domestic_violence")
(ggm1 <- ggplot(domestic_violence, aes(fill = Scaled)) +
geom_sf() +
scale_fill_continuous(low = "#fff7ec", high = "#7F0000") +
ggsn::scalebar(domestic_violence, dist = 4, dist_unit = "km",
transform = TRUE, model = "WGS84"))
gganimate::animate(
ggm1 + transition_states(Value),
nframes = 5
)
Created on 2019-04-17 by the reprex package (v0.2.1)
As you can see, the scale bar is not rendered properly in all of the images of the animations. Furthermore, it raises an error when using transition_time()
that I suspect must be due to the same underlying cause.
In ggsn v0.5.0
, the scalebar()
function will fail if the names of the columns containing latitude and longitude data do not start with lat
and long
, respectively:
library(ggmap)
library(ggsn)
coords <-
data.frame(stringsAsFactors = FALSE,
x = c(150.750034, 150.6857303, 150.533333, 150.416667, 150.279,
150.3730633, 150.5625494, 150.65),
y = c(-33.613769, -33.5801886, -33.5, -33.55, -33.514, -33.7094058,
-33.7002999, -33.666667))
head(coords)
#> x y
#> 1 150.7500 -33.61377
#> 2 150.6857 -33.58019
#> 3 150.5333 -33.50000
#> 4 150.4167 -33.55000
#> 5 150.2790 -33.51400
#> 6 150.3731 -33.70941
my_map <- qmplot(x, y, data = coords, geom = "blank",
maptype = "terrain-background", zoom = 11)
my_map +
scalebar(data = coords, dist = 5, dist_unit = "km", model = "WGS84",
transform = TRUE)
#> Warning in min(data$long): no non-missing arguments to min; returning Inf
#> Warning in max(data$long): no non-missing arguments to max; returning -Inf
#> Warning in min(data$lat): no non-missing arguments to min; returning Inf
#> Warning in max(data$lat): no non-missing arguments to max; returning -Inf
#> Warning in sin(lat): NaNs produced
#> Warning in cos(phi): NaNs produced
#> Warning in sin(phi): NaNs produced
#> Warning in sin(phi): NaNs produced
#> Warning in sin(lat): NaNs produced
#> Warning in cos(phi): NaNs produced
#> Warning in sin(phi): NaNs produced
#> Warning in sin(phi): NaNs produced
#> `data` must be uniquely named but has duplicate columns
And no map will be generated. Compare this to the magic names:
names(coords) <- c("long", "lat")
my_map +
scalebar(data = coords, dist = 5, dist_unit = "km", model = "WGS84",
transform = TRUE)
I am ploting a map using the ggplot2 and sf packages and I would like to include a map scale and north arrow to the figure using the ggsn package. Here is the problem. I want to show a figure with two or more facets but I would like to add the scale and north arrow to only one of the figure facets.
I've detailed my question here. . I'm not sure this should be created as an issue
.
I'd like to change border size and colors of the scalebar. I thought it would be possible to add "color", "fill" and "border.size" arguments to the code, unfortunately it s not. Any pointers?
I am trying to reproduce the first example of adding north and scalebar on my macOS,
library(ggsn)
library(sf)
dsn <- system.file('extdata', package = 'ggsn')
# Map in geographic coordinates
map <- st_read(dsn, 'sp', quiet = TRUE)
# Map in projected coordinates
map2 <- st_transform(map, 31983)
(ggm1 <- ggplot(map, aes(fill = nots)) +
geom_sf() +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8))
ggm1 +
blank() +
north(map) +
scalebar(map, dist = 5, dd2km = TRUE, model = 'WGS84')
but it gives following error
Error in grid.Call.graphics(C_setviewport, vp, TRUE) :
non-finite location and/or size for viewport
In addition: There were 21 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In max(data$long) : no non-missing arguments to max; returning -Inf
2: In min(data$long) : no non-missing arguments to min; returning Inf
3: In max(data$lat) : no non-missing arguments to max; returning -Inf
4: In min(data$lat) : no non-missing arguments to min; returning Inf
5: In max(data$long) : no non-missing arguments to max; returning -Inf
6: In max(data$lat) : no non-missing arguments to max; returning -Inf
7: In max(data$long) : no non-missing arguments to max; returning -Inf
8: In min(data$lat) : no non-missing arguments to min; returning Inf
9: In max(data$lat) : no non-missing arguments to max; returning -Inf
10: In min(data$lat) : no non-missing arguments to min; returning Inf
11: In max(data$lat) : no non-missing arguments to max; returning -Inf
12: In min(data$lat) : no non-missing arguments to min; returning Inf
13: In sin(lat) : NaNs produced
14: In cos(phi) : NaNs produced
15: In sin(phi) : NaNs produced
16: In sin(phi) : NaNs produced
17: In sin(lat) : NaNs produced
18: In cos(phi) : NaNs produced
19: In sin(phi) : NaNs produced
20: In sin(phi) : NaNs produced
21: Removed 2 rows containing missing values (geom_text).
My session information is as follows
> sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-apple-darwin16.7.0 (64-bit)
Running under: macOS Sierra 10.12.6
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] sf_0.5-4 ggsn_0.4.0 ggplot2_2.2.1.9000
loaded via a namespace (and not attached):
[1] Rcpp_0.12.12 lattice_0.20-35 png_0.1-7 digest_0.6.12 grid_3.4.1
[6] plyr_1.8.4 DBI_0.7 gtable_0.2.0 magrittr_1.5 units_0.4-6
[11] scales_0.5.0.9000 rlang_0.1.2 lazyeval_0.2.0 sp_1.2-5 RColorBrewer_1.1-2
[16] tools_3.4.1 udunits2_0.13 foreign_0.8-69 munsell_0.4.3 yaml_2.1.14
[21] compiler_3.4.1 colorspace_1.3-2 maptools_0.9-2 tibble_1.3.4
Hi. I often use small ggmaps with high Google API scale value, where 1km scales are definitely too much. Is it possible to use values of scale size lower than 1, like 100m?
Thanks
First off, I am super excited about this package! Thanks for all the work. I have been trying to get a scalebar on my own map and kept on getting various errors. So I ran through your example and got this
Error in FUN(left, right) : non-numeric argument to binary operator
After running
ggm1 + blank() + north(map.df) + scalebar(map.df, dist = 5, dd2km = TRUE, model = 'WGS84')
from your example. the creation of ggm1 worked just fine. This is the same error I get when I try to add a scalebar to my own map. Thoughts? Thanls
When I try to use ggsn on a ggplot-map, I get an error when using coord_map
. I do see that certain map projections might cause an error (where to point to north on a globe for example), but in the default map projection it would not cause an issue (as far as I understand it).
Here is an example:
library(ggsn)
#> Loading required package: ggplot2
# following loosely the example in ?map_data (ggplot2)
## Data Preparation
states <- map_data("state")
arrests <- USArrests
names(arrests) <- tolower(names(arrests))
arrests$region <- tolower(rownames(USArrests))
choro <- merge(states, arrests, sort = FALSE, by = "region")
choro <- choro[order(choro$order), ]
# Map Creation
figure_map <- ggplot(choro, aes(long, lat)) +
geom_polygon(aes(group = group, fill = assault))
## A minimum case
figure_map
figure_map + north(choro, symbol = 16, scale = 0.15)
## Coordinates of a Map
figure_map + coord_map()
figure_map + coord_map() + north(choro, symbol = 16, scale = 0.15)
#> Error: annotation_custom only works with Cartesian coordinates
Any chance to fix this easily?
Hello,
How can I add a scale bar to a ggplot map where the axes have been modified? Here is what I have tried:
Code to generate data frame:
options(scipen = 12)
lib <- c("raster", "rgdal", "ggplot2", "ggsn")
sapply(lib, function(x) require(x, character.only = TRUE))
nz1 <- getData("GADM", country = "NZ", level = 1)
nz1 <- spTransform(nz1, CRS("+init=epsg:2135"))
nz1@data$id <- rownames(nz1@data)
nz1.ff <- fortify(nz1)
nz1.df <- merge(nz1@data, nz1.ff, by = "id", all.y = TRUE)
colnames(nz1.df)[7] <- "Region"
Tried this first, no dice:
mapNZ <- ggplot() +
geom_polygon(data=nz1.df, aes(x=long, y=lat, fill = Region, group=group), size = 0.1) + scale_x_continuous(limits = c(-400000, 650000)) + scale_y_continuous(limits = c(-4500000, 6250000))
theme_bw() + theme(text = element_text(size=50))
x_lim <- mapNZ$nz1.df[c(-400000, 650000), 1] * c(1, .9998)
y_lim <- mapNZ$nz1.df[c(-4500000, 6250000), 2] * c(1.003, 1)
mapNZ + scalebar(x.min = x_lim[1], x.max = x_lim[2],
y.min = y_lim[1], y.max = y_lim[2], dist = 200, st.size = 20)
Then I replaced scale_x_continuous() and scale_y_continuous() with coord_cartesian(), as that seems to be the fix for similar issues, but that didn't work either. It doesn't throw an error, the scale bar just doesn't show up. Can you suggest anything? Thanks!
Is there any way to change the units of a scalebar from km to miles?
Using ggsn 0.5.0
:
When creating a map with ggplot()
and geom_sf()
and using scalebar()
, if your sf
data object has a column named label
, the information in that column is used instead of the proper unit labels specified in scalebar()
. For example:
library(sf)
library(tidyverse)
library(ggsn)
library(maps)
library(ggplot2)
st <- st_as_sf(map("state", plot=FALSE, fill=TRUE)) %>%
filter(ID %in% c("connecticut","massachusetts","new hampshire")) %>%
mutate(label=c("CN","MA","NH"))
ggplot(data=st) +
geom_sf() +
scalebar(data=st, dist_unit="km", dist=100, transform=T)
You can work around this by changing the name of the column in the sf
object to anything else, e.g.
st <- st %>% rename(.label = label)
ggplot(data=st) +
geom_sf() +
scalebar(data=st, dist_unit="km", dist=100, transform=T)
Naming the label column scalebar()
creates to something other than label
and less likely to overlap with sf
column names should solve this. I can write a PR if you want.
Line 236 in 1e20884
In ggsn v0.5.0
, the presence of extra columns will make scalebar()
fail when it is time to pipe it together with a ggplot
object:
library(ggmap)
library(ggsn)
coords <-
data.frame(stringsAsFactors = FALSE,
long = c(150.750034, 150.6857303, 150.533333, 150.416667, 150.279,
150.3730633, 150.5625494, 150.65),
lat = c(-33.613769, -33.5801886, -33.5, -33.55, -33.514,
-33.7094058, -33.7002999, -33.666667),
label = c("WSU", "Grose Vale", "Bilpin", "Mt Tomah", "Bell",
"Katoomba", "Springwood", "Hawkesbury Heights"))
head(coords)
#> long lat label
#> 1 150.7500 -33.61377 WSU
#> 2 150.6857 -33.58019 Grose Vale
#> 3 150.5333 -33.50000 Bilpin
#> 4 150.4167 -33.55000 Mt Tomah
#> 5 150.2790 -33.51400 Bell
#> 6 150.3731 -33.70941 Katoomba
my_map <- qmplot(long, lat, data = coords, geom = "blank",
maptype = "terrain-background", zoom = 11)
my_map +
scalebar(data = coords, dist = 5, dist_unit = "km", model = "WGS84",
transform = TRUE)
#> `data` must be uniquely named but has duplicate columns
And a blank map (white rectangle) is generated. But when the extra column(s) are removed:
my_map +
scalebar(data = coords[c("long", "lat")], dist = 5, dist_unit = "km",
model = "WGS84", transform = TRUE)
Hi Oswaldo,
I'm trying to add a scale bar to a ggplot object that includes several layers. There is an sf object (read from a shapefile using st_read( ) ) that I want to use to produce the scale bar. Here is my code and the error:
ggplot( prediction ) + theme_bw() + geom_raster( aes( Longitude , Latitude , fill = Probability )) + scale_fill_viridis( option = "B" , limits = c( 0, 0.6 )) + geom_sf(data=counties, color="gray5", fill="NA", cex=0.1) + geom_contour( aes( x=Longitude , y=Latitude , z=p) , breaks = c( 0.025 ), color="Blue" , cex=1.2, lty=1) + geom_contour( aes( x=Longitude , y=Latitude , z=p) , breaks = c( 0.975 ), color="Red" , cex=1.2, lty=1) + geom_sf(data=buffer, color="black", fill="NA", cex=2) + scalebar(data=buffer, dist = 25, dd2km = TRUE, x.min=-79.83613, x.max=-78.04790, y.min=35.11765, y.max=36.89916, model = "WGS84")
Here's the error:
Warning messages:
1: In max(data$long) : no non-missing arguments to max; returning -Inf
2: In min(data$lat) : no non-missing arguments to min; returning Inf
3: In max(data$lat) : no non-missing arguments to max; returning -Inf
4: In min(data$lat) : no non-missing arguments to min; returning Inf
5: In max(data$lat) : no non-missing arguments to max; returning -Inf
6: In min(data$lat) : no non-missing arguments to min; returning Inf
north(ggmap(get_googlemap()) produces above error.
:(
Hi!
I'm using coord_map() instead of coord_equal() to select a segment of a map. Do you know any way to use ggsn with it?.
Thank you for your work!
Hi,
I am trying to update the ggsn (0.4.0) package in order to use north( ) and avoid the error "Error: annotation_custom only works with Cartesian coordinates", but every time that I run the github instalation I get this error:
Error: C:/Users/bmped/AppData/Local/Temp/RtmpWmL5pz/devtoolseb448a42356/oswaldosantos-ggsn-f0fd534/man/scalebar.Rd:54: Bad \link text
I wonder, how can I solve it?
Thank you!
Thank you!
Hi Oswaldo, the scalebar function is great, but I was wondering if there is currently a way to change the number of labels (i.e. the number of scales), ideally from 3 to 2 whereby only "0" and the maximum scale is drawn. For example, on the map below only display 0 and 8km. This would be useful because sometimes in small scales the middle label isn't required and gets in the way.
library(ggsn); library(ggplot2); library(sf)
data("domestic_violence")
(ggm1 <- ggplot(domestic_violence, aes(fill = Scaled)) +
geom_sf() +
scale_fill_continuous(low = "#fff7ec", high = "#7F0000"))
ggm1 + north(domestic_violence) + scalebar(domestic_violence, dist = 4, dist_unit = "km", transform = TRUE, model = "WGS84")
The sf
package is the R implementation of Simple Features and starts to be a new standard for working with spatial data in R. More information at https://github.com/edzer/sfr and http://robinlovelace.net/geocompr/spatial-class.html.
Moreover, the development version of ggplot2
package already supports plots with sf
object using a geom_sf()
function - http://ggplot2.tidyverse.org/reference/ggsf.html. I think it could be very useful to have a possibility to add a north arrow and scale bar to maps with sf
objects.
@oswaldosantos do you plan to add a support for sf
objects?
I've installed ggsn 0.4.6 and ggplot2 2.2.1.9000. When I try to run the example code:
library(ggsn); library(sf)
dsn <- system.file('extdata', package = 'ggsn')
# Map in geographic coordinates
map <- st_read(dsn, 'sp', quiet = TRUE)
ggm1 +
blank() +
north(map) +
scalebar(map, dist = 5, dd2km = TRUE, model = 'WGS84')
I get:
Error: GeomCustomAnn was built with an incompatible version of ggproto.
Please reinstall the package that provides this extension.
My session info:
R version 3.4.2 (2017-09-28)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Attached base packages:
[1] grid stats graphics grDevices utils datasets methods base
other attached packages:
[1] sf_0.5-5 ggsn_0.4.6 ggplot2_2.2.1.9000
In ggsn v0.5.0
, the scalebar()
function does not warn the user if the dist
argument is too large for the map. This results in part of the scalebar being cut off (if dist
goes off the edge of the plot area on only one edge) or the entire bar just going missing if dist
is large enough that both sides go outside the plot area:
library(ggmap)
library(ggsn)
coords <-
data.frame(stringsAsFactors = FALSE,
long = c(150.750034, 150.6857303, 150.533333, 150.416667, 150.279,
150.3730633, 150.5625494, 150.65),
lat = c(-33.613769, -33.5801886, -33.5, -33.55, -33.514,
-33.7094058, -33.7002999, -33.666667))
head(coords)
#> long lat
#> 1 150.7500 -33.61377
#> 2 150.6857 -33.58019
#> 3 150.5333 -33.50000
#> 4 150.4167 -33.55000
#> 5 150.2790 -33.51400
#> 6 150.3731 -33.70941
my_map <- qmplot(long, lat, data = coords, geom = "blank",
maptype = "terrain-background", zoom = 11)
my_map +
scalebar(data = coords, dist = 22, dist_unit = "km", model = "WGS84",
transform = TRUE, location = "bottomleft")
This is the extent of this map, about 44 km wide.
my_map +
scalebar(data = coords, dist = 25, dist_unit = "km", model = "WGS84",
transform = TRUE, location = "bottomleft")
#> Warning: Removed 1 rows containing missing values (geom_text).
The right half of the scale bar cannot fit in the plot area.
my_map +
scalebar(data = coords, dist = 25, dist_unit = "km", model = "WGS84",
transform = TRUE, location = "bottomright")
#> Warning: Removed 1 rows containing missing values (geom_text).
The left half cannot fit.
my_map +
scalebar(data = coords, dist = 2500, dist_unit = "km", model = "WGS84",
transform = TRUE, location = "bottomright")
#> Warning in min(x): no non-missing arguments to min; returning Inf
#> Warning in max(x): no non-missing arguments to max; returning -Inf
#> Warning: Removed 2 rows containing missing values (geom_text).
This is what happens when neither half of the scale bar can fit.
my_map +
scalebar(data = coords, dist = 1, dist_unit = "m", model = "WGS84",
transform = TRUE, location = "bottomright")
And the above too-large example looks very much like this too-small example.
Thank your for the great package! I am using it regularly.
I recently created a map with a scale bar of 100m. The labels were 0.05 and 0.1km.
Is there any way to change the label format to meters?
I think this would be a useful option for users.
Any way to adjust the line width on the scale bar? Looks good in plot window, but when exported as a postscript file, the line width is too wide. I see you can adjust text size with st.size, but don't see a way of adjusting line width.
Using the latest sf
:
library(ggsn); library(sf); library(ggplot2)
dsn <- system.file('extdata', package = 'ggsn')
map <- st_read(dsn, 'sp', quiet = TRUE)
map2 <- st_transform(map, 31983)
ggm1 <- ggplot(map, aes(fill = nots)) +
geom_sf() +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8)
ggm1 +
blank() +
north(map)
Returns:
Error in grid.Call.graphics(C_setviewport, vp, TRUE) :
non-finite location and/or size for viewport
Also, ggm1 + scalebar(map, dist = 5, dd2km = TRUE, model = 'WGS84')
does not show any scalebar.
I updated to the latest development version ggsn (0.5.1) and I get this error.
Error in
st_geometry<-.data.frame(
tmp, value = NULL) : inherits(value, "sfc") || is.character(value) is not TRUE
The error is the same as the one described in this stack exchange post. It seems there is some issue with the line st_geometry(legend2) <- NULL.
https://stackoverflow.com/questions/55943227/new-error-when-fitting-a-ggsn-scale-bar-to-ggmap-object
Also, I believe that the sf library should be prefixed to the st_geometry call, so that users don't need to load sf library themselves. e.g. sf:st_geometry(legend2)
. After loading the sf library, I get the above message.
Blz cara... muito obrigado! This is great!
I was wondering... it could be really useful to also allow for a title block. .. expandable to title and author... etc.. that way the scale bar, legend, and title block could all be optionally combined?
If we can do all that and add a border, i think R maps could really compete with any software package!
Can't load this package
my code:
%load_ext rpy2.ipython
%%R
install.packages(c("ggplot2", "devtools", "dplyr", "stringr"))
install.packages(c("maps", "mapdata", "ggmap", "sf", "gssn"))
%%R
library(ggplot2)
library(ggmap)
library(maps)
library(mapdata)
library(gssn)
RInterpreterError: Failed to parse and evaluate line 'library(ggsn)\n'.
R error message: 'Error in library(ggsn) : there is no package called ‘ggsn’'
This happens on colab, and R studio (version 4.0.2 (2020-06-22)). I've allso tried the devtools install and still get the same error.
Hi,
could you clarify which projection are you using to define the scale bar? a standard plate carée?
I couldn't seem to find what I was looking for in the code.
Thanks
Hi Oswaldo - Feature request rather than issue. It would be great to add support for terra raster datasets to be used as the 'data' used for creating the ggplot in ggsn::north and ggsn::scalebar. At the moment I have to manually extract the extents using terra::ext and then set them in using x.min, x.max, y.min, y.max. Hopefully quite an easy one to implement and would remove an annoying step. Thanks!
I'm adding a scale bar (using the ggsn
package) to a map that is faceted. I can't quite figure out how to correctly use the facet.var variable. I currently can successfully add a scalebar
that appears on all facets, but cannot restrict it to a single facet (get the undefined columns selected error). It looks like the examples are for facet_grid
, and I can't quite replicate the result with facet_wrap
. Any help would be appreciated...
An example of my issue:
library(ggmap)
library(ggsn)
Finalmap <- get_map(location = c(lon = -23.17, lat = 15.2), zoom = 11,
maptype = "hybrid", scale = 2)
data <- expand.grid(x = -23.17, y = 15.2, Factor = c("A", "B", "C"))
ggmap(Finalmap) +
geom_point(data = data, aes(x = x, y = y)) +
facet_wrap(~ Factor) +
scalebar(dist = 3, dist_unit = "km",
x.min = -23.2, x.max = -23.1, y.min = 15.1, y.max = 15.3,
anchor = c(x = -23.12, y = 15.12),
height = 0.04, st.dist = 0.1,
st.color = "white",
transform = TRUE, model = "WGS84",
#### THESE TWO LINES ARE THE PROBLEM
facet.var = c("Factor"),
facet.lev = "C")
Hi,
My plotting code that used ggsn::scalebar fine last year stopped working until I made a minor change, replacing dd2km
with transform
. The documentation doesn't explain this.
Thanks for the package - otherwise works great!
Hello,
it seems like the package is not working anymore. If I execute the example-code, I get this error-message
Error in grid.Call.graphics(C_setviewport, vp, TRUE) : non-finite location and/or size for viewport In addition: There were 21 warnings (use warnings() to see them)
Example Code
dsn <- system.file('extdata', package = 'ggsn')
map <- st_read(dsn, 'sp', quiet = TRUE)
map2 <- st_transform(map, 31983)
(ggm1 <- ggplot(map, aes(fill = nots)) +
geom_sf() +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8))
ggm1 +
blank() +
north(map) +
scalebar(map, dist = 5, dd2km = TRUE, model = 'WGS84')```
Here is my session info
```r
sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Matrix products: default
locale:
[1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
[5] LC_TIME=English_Australia.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] sf_0.6-3 ggsn_0.4.0 ggplot2_3.0.0
loaded via a namespace (and not attached):
[1] Rcpp_0.12.18 RColorBrewer_1.1-2 pillar_1.3.0 compiler_3.5.0 plyr_1.8.4
[6] bindr_0.1.1 class_7.3-14 tools_3.5.0 digest_0.6.15 tibble_1.4.2
[11] gtable_0.2.0 lattice_0.20-35 pkgconfig_2.0.1 png_0.1-7 rlang_0.2.1
[16] DBI_1.0.0 rstudioapi_0.7 yaml_2.1.19 bindrcpp_0.2.2 spData_0.2.9.0
[21] e1071_1.6-8 withr_2.1.2 dplyr_0.7.6 classInt_0.2-3 grid_3.5.0
[26] tidyselect_0.2.4 glue_1.3.0 R6_2.2.2 foreign_0.8-70 sp_1.3-1
[31] purrr_0.2.5 magrittr_1.5 scales_0.5.0 maptools_0.9-2 units_0.6-0
[36] assertthat_0.2.0 colorspace_1.3-2 lazyeval_0.2.1 munsell_0.5.0 crayon_1.3.4 `
Hi,
I keep getting the following error message when attempting to install 'ggsn':
##########################
double free or corruption (out)
Aborted (core dumped)
#########################
which seems to suggest "insufficient package version (submitted: 0.5.0, existing: 0.5.0)
I have attached log files and session info.
Many thanks for your help, I look forward to using the package.
Best,
Dylan
Session Info:
R version 4.0.2 (2020-06-22)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.1 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=es_CL.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=es_CL.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=es_CL.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=es_CL.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_4.0.2
Hi,
I use ggsn from time to time to make maps, and I'm pretty sure it should be more famous than it is. As it's very useful.
I stumbled upon the ggplot2-exts repository https://github.com/ggplot2-exts/ggplot2-exts.github.io that makes a searchable gallery for ggplot2 extensions.
Would you consider to make a PR to add ggsn to the list of ggplot2 extensions?
Thanks again for building ggsn!
How can I add a N arrow and scale to maps obtained directly from the web with ggmap
? For example:
library(ggmap)
library(ggsn)
myLocation <- c(lon = 98.883060, lat = 8.167072)
myMap <- get_googlemap(center = myLocation,
zoom = 11,
scale = 2,
maptype = "terrain",
markers = data.frame(t(myLocation)))
close_up <- ggmap(myMap)
I'm not sure what to put in here:
close_up +
blank() +
north(???) +
scalebar(???, dist = 5, dd2km = TRUE, model = 'WGS84')
What do you recommend? It would be great to have an example of this in the docs!
If I want to keep the scalebar on all facets, text appears in a weird way:
library(ggsn); library(sf)
dsn <- system.file('extdata', package = 'ggsn')
# Map in geographic coordinates
map <- st_read(dsn, 'sp', quiet = TRUE)
(ggm1 <- ggplot(map, aes(fill = nots)) +
geom_sf() +
scale_fill_brewer(name = 'Animal abuse\nnotifications', palette = 8))
ggm1 +
blank() +
facet_grid(~nots) +
north(map) +
scalebar(map, dist = 5, dd2km = TRUE, model = 'WGS84')
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.