I have been through a lot of questions and documentation, and since you need to bill to use ggmaps()
(because of google cloud services) I started looking for an alternative. I found maps()
, and I'm trying to adapt this solution:
data %>%
rename(x = longitud, y = latitud) %>%
ggplot() +
geom_polygon(aes(x = long, y = lat), data = map_data("world")) +
geom_point(aes(x = x, y = y))
However, I'm getting into a few problems:
This is the data:
data <- structure(list(latitud = c(-30.6833000183105, -41.4000015258789,
-43.8189010620117, -34.2731018066406, -47.0666999816895, -40.3166999816895,
-43.4491996765137, -35.7543983459473, -47.1413993835449, -36.6260986328125,
-54.0410995483398, -37.2118988037109, -33.3086013793945, -37.2792015075684,
-35.4524993896484, -36.5856018066406, -18.5832996368408, -18.2325000762939,
-36.4668998718262, -44.75, -44.6591987609863, -44.5936012268066,
-28.4647006988525, -28.6996994018555, -28.5118999481201, -28.6718997955322,
-28.7306003570557, -30.5902996063232, -30.6667003631592, -35.1730995178223,
-48.1591987609863, -48.377498626709, -45.4000015258789, -45.7832984924316,
-29.94580078125, -38.8652992248535, -30.4386005401611, -31.6646995544434,
-51.2000007629395, -51.3328018188477, -51.25, -45.5666999816895,
-45.551700592041, -45.8372001647949, -39.0144004821777, -28.9414005279541,
-28.7502994537354, -38.6081008911133, -34.9844017028809, -32.8403015136719,
-29.9953002929688, -18.3999996185303, -35.9000015258789, -35.6169013977051,
-35.9085998535156, -35.8166999816895, -33.7346992492676, -45.38330078125,
-35.4068984985352, -32.7571983337402, -32.8502998352051, -33.5938987731934,
-36.8386001586914, -33.4961013793945, -20.1119003295898, -27.8043994903564,
-37.7332992553711, -30.9986000061035, -30.8006000518799, -21.9368991851807,
-22.3652992248535, -22.273099899292, -22.0277996063232, -21.9755992889404,
-22.289400100708, -22.2791996002197, -38.4303016662598, -38.6866989135742,
-45.4057998657227, -38.7799987792969, -37.5503005981445, -37.6018981933594,
-37.8997001647949, -38.0368995666504, -37.9897003173828, -37.7047004699707,
-37.7963981628418, -37.7092018127441, -31.5835990905762, -27.3635997772217,
-27.3194007873535, -29.8931007385254, -30.9242000579834, -21.4246997833252,
-36.5703010559082, -38.2008018493652, -38.0661010742188, -38.4333000183105,
-31.7422008514404, -31.6881008148193, -31.8117008209229, -31.7714004516602,
-27.86669921875, -27.5160999298096, -27.9747009277344, -30.7047004699707,
-36.8499984741211, -36.6500015258789, -36.86669921875, -35.3736000061035,
-40.5167007446289, -33.4782981872559, -33.198299407959, -36.0499992370605,
-35.9667015075684, -36.2332992553711, -34.4921989440918, -34.6581001281738,
-32.8166999816895, -47.3499984741211, -47.5, -29.9811000823975,
-32.4413986206055, -22.3922004699707, -22.3430995941162, -21.7124996185303,
-22.4582996368408, -22.4419002532959, -22.4468994140625, -22.5060997009277,
-33.7219009399414, -33.6613998413086, -35.5574989318848), longitud = c(-71.0500030517578,
-73.2166976928711, -72.38330078125, -71.371696472168, -72.8000030517578,
-72.9666976928711, -72.1074981689453, -71.0864028930664, -72.7257995605469,
-72.4891967773438, -68.7975006103516, -72.3242034912109, -70.3572006225586,
-71.9847030639648, -71.7332992553711, -71.5255966186523, -69.0466995239258,
-69.331901550293, -72.6911010742188, -72.7166976928711, -71.8082962036133,
-71.5477981567383, -71.1782989501953, -70.5500030517578, -71.0064010620117,
-70.6464004516602, -70.5066986083984, -71.1714019775391, -71.5333023071289,
-71.0911026000977, -73.0888977050781, -72.9589004516602, -72.5999984741211,
-72.61669921875, -70.5327987670898, -71.7335968017578, -71.002197265625,
-71.2546997070312, -72.9332962036133, -73.1091995239258, -72.5167007446289,
-72.0832977294922, -72.0680999755859, -71.7769012451172, -73.0828018188477,
-70.2481002807617, -70.4828033447266, -72.8478012084961, -72.0100021362305,
-71.0255966186523, -70.5867004394531, -70.3000030517578, -71.5167007446289,
-71.7677993774414, -71.2981033325195, -71.8332977294922, -70.3007965087891,
-72.4666976928711, -72.2082977294922, -70.736701965332, -70.5093994140625,
-70.3792037963867, -73.061897277832, -70.8167037963867, -68.8407974243164,
-70.1268997192383, -72.61669921875, -71.0899963378906, -70.9697036743164,
-68.5330963134766, -68.6418991088867, -68.1438980102539, -68.6207962036133,
-68.6074981689453, -68.3447036743164, -68.2427978515625, -72.0105972290039,
-72.502799987793, -72.6231002807617, -72.9468994140625, -72.5903015136719,
-72.2782974243164, -71.6239013671875, -71.4781036376953, -71.5199966430664,
-71.7683029174805, -71.6988983154297, -71.823600769043, -71.4606018066406,
-70.3392028808594, -70.8380966186523, -71.2514038085938, -70.7731018066406,
-70.053596496582, -71.5547027587891, -71.2988967895508, -71.3497009277344,
-71.2332992553711, -71.1492004394531, -71.2658004760742, -70.9302978515625,
-71.0639038085938, -70.0667037963867, -70.2647018432617, -69.997802734375,
-70.9244003295898, -72.38330078125, -72.4499969482422, -72.3332977294922,
-71.8292007446289, -73.2833023071289, -70.7172012329102, -70.8955993652344,
-72.0832977294922, -72.0167007446289, -72, -71.3731002807617,
-71.3019027709961, -71, -72.8499984741211, -72.9749984741211,
-70.8981018066406, -71.3139038085938, -69.5299987792969, -69.5650024414062,
-69.5167007446289, -68.7363967895508, -68.8886032104492, -68.8775024414062,
-68.988899230957, -71.5550003051758, -71.3371963500977, -71.7067031860352
)), row.names = c(1L, 136L, 262L, 395L, 507L, 605L, 701L, 789L,
868L, 996L, 1094L, 1124L, 1172L, 1218L, 61387L, 61546L, 75009L,
87052L, 99246L, 110237L, 115091L, 125346L, 135758L, 135819L,
144524L, 154009L, 172251L, 185024L, 192338L, 210797L, 228781L,
228893L, 238299L, 244626L, 253673L, 274263L, 285367L, 304757L,
316768L, 328069L, 336044L, 346167L, 351691L, 363302L, 375494L,
385229L, 402720L, 422016L, 440373L, 451547L, 462674L, 483188L,
491968L, 496483L, 511332L, 530494L, 546443L, 564800L, 575215L,
586462L, 602135L, 622841L, 642834L, 657640L, 677273L, 688216L,
706550L, 724524L, 731829L, 748442L, 748489L, 754030L, 763570L,
776729L, 785860L, 799355L, 812606L, 832675L, 853030L, 860670L,
878448L, 889066L, 889167L, 889273L, 889372L, 889466L, 889499L,
889524L, 913996L, 929594L, 935459L, 953842L, 963352L, 983829L,
991810L, 1005230L, 1005341L, 1011503L, 1022492L, 1029507L, 1047978L,
1063655L, 1073799L, 1073936L, 1086040L, 1106251L, 1126146L, 1134776L,
1154269L, 1170495L, 1181431L, 1192018L, 1197439L, 1212431L, 1231028L,
1247598L, 1264197L, 1264302L, 1271900L, 1279499L, 1279618L, 1290282L,
1309415L, 1320521L, 1320606L, 1320753L, 1320827L, 1337638L, 1344817L,
1355030L, 1368899L, 1381979L, 1393175L), class = "data.frame")
The following code uses the simple features (sf) library to show a map of Chile overlaid with the provided datapoints. The bounding box is set in the parameters to st_crop
and can be adjusted as needed without distorting the map. The code uses the Admin 0 - Countries shape file, which is in the public domain and free to use.
library(sf)
library(ggplot2)
library(dplyr);
library(magrittr);
# download world shapefile from
# https://www.naturalearthdata.com/downloads/
# 50m-cultural-vectors/50m-admin-0-countries-2/
# and extract zip file
world <- st_read(
# change below line to path of extracted shape file
'c:/path/to/ne_50m_admin_0_countries.shp'
);
world %<>% mutate(active = NAME_EN == 'Chile'); # used to highlight Chile
# convert the dataframe to a sf geometry object
dsf <- data %>%
rowwise %>%
mutate(geometry = list(st_point(c(longitud, latitud)))) %>%
st_as_sf(crs=st_crs(world));
# plot the map
world %>% st_crop(xmin=-90, xmax=-30, ymin=-60, ymax=-10) %>%
ggplot() +
geom_sf(aes(fill=active), show.legend=F) + # world map with Chile highlighted
geom_sf(data=dsf, color='#000000') + # point overlay
scale_fill_manual(values=c('#aaaa66', '#ffffcc')) + # country colors
scale_x_continuous(expand=c(0,0)) +
scale_y_continuous(expand=c(0,0)) +
theme_void() + # remove axis labels and gridlines
theme(panel.background=element_rect(fill='lightblue'))
The output is shown below. Note that the map does not distort regions that are cropped.
The sf
package provides support for simple feature (sf) geometries. Simple features provide tools for working with geometries such as polygons and points. There is a cheat sheet here that provides a good overview.
As of release 3.0, ggplot2
provides native support for visualizing simple feature geometries. This allows for us to write:
world <- st_read(
# change below line to path of extracted shape file
'c:/path/to/ne_50m_admin_0_countries.shp'
);
ggplot(world) + geom_sf()
Simple feature objects are generally stored in data frames that include a column describing the geometry. This allows us to show a map of Chile like so:
ggplot(world %>% filter(NAME_EN == 'Chile')) + geom_sf()
Or a map with Chile highlighted:
# create new geometry of world map
# cropped to (10°S, 60°S) and (90°W, 30°W)
chileregion <- world %>% st_crop(
xmin=-90,
xmax=-30,
ymin=-60,
ymax=-10)
# show region with Chile highlighted
ggplot(chileregion %>%
mutate(is.chile = factor(NAME_EN == 'Chile'))) +
geom_sf(aes(fill=is.chile), show.legend = F) +
scale_fill_manual(values=c('gray', 'red'))
We are given a data frame with two columns, latitude and longitude.
To convert to a simple feature, we first use st_point
to create a new point with the given coordinate values:
dsf <- data %>% #begin with data
rowwise %>% # dplyr::rowwise applies mutation to each row individually
# create a geometry column that provides the point as a geometry
mutate(geometry = list(st_point(c(longitud, latitud))))
At this point, dsf
is simply a data frame with a geometry column; it is not yet a simple feature object. We can use the function st_as_sf
to create a sf object from the data frame. In doing so, we will also need to provide a coordinate reference system (CRS) to allow ggplot
to project the coordinates provided onto the map rendering. Here we can provide ESPG 4326 as the CRS, which maps the x and y coordinates directly to lat/long:
# call st_as_sf to convert data frame to a simple geometry object.
dsf <- st_as_sf(crs=4326);
Since dsf
is now a simple geometry, you can plot as such:
> ggplot(dsf) + geom_sf()
(Note that you could also simply overlay the points on the base map with geom_point(data=data, aes(x=longitud, y=latitud))
without first converting to an sf object. This will work here because the CRS for the base map is also ESPG 4326, which maps x and y directly to longitude and latitude, respectively. Using geom_point
, however, will not work in the general case when a coordinate transformation is applied to the geometry.)
With both points now defined as geometries, you can simply overlay:
ggplot() +
geom_sf(data=chileregion) +
geom_sf(data=dsf)
The final plot in the original answer adds some additional visual aesthetics (e.g., blue background) to produce the final map output.