Place labels outside of polygon

112 Views Asked by At

I have created a map in R. my map However, I need the labels to sit just outside of the polygons so that the inside includes only the data points. Another alternative would be to color code each polygon and have a legend titled Statistical Areas (and the colors for 909, 910,911 corresponding). I would also like the y-axis to read as Latitude and the x-axis to read as Longitude. Below is the script I have used for the formatting. Does anyone know what I need to add to the script to make these alterations? Any help will be greatly appreciated!

ggplot(data = stats_shapefile) + geom_sf(fill= 'White')+
  geom_sf(data=samples_sf)+ scale_fill_discrete("Statistical Area")+ geom_sf_text(aes(label = Statistica),size = 8 / .pt, position = "identity")
2

There are 2 best solutions below

0
L Tyrone On BEST ANSWER

I had the exact same struggles you are having when trying to get my head around ggplot2, and how to use aes() in particular. If you want to have something in a particular place for instance, you have to declare it inside aes(). The errors you are getting are because ggplot() and geom_text_repel() haven't been given the minimum aes() information they need.

With that in mind, here's a repex to help you on your way. This involves creating intermediary data - sf_points - so that you can 'feed' ggrepel the aes() information it needs. There are other ways of doing this but I believe this approach is good readability-wise. NOTE: the example cra3 data are at the end of this answer.

library(dplyr)
library(sf)
library(ggplot2)
library(ggrepel)

# Create an sf of cra3 centroids with individual long/lat columns for ggrepel to use
sf_points <- cra3 %>%
  st_centroid() %>%
  mutate(long = st_coordinates(.)[,1],
         lat = st_coordinates(.)[,2])

# Plot with labels only
ggplot() + 
  geom_text_repel(data = sf_points,
                  aes(x = long, y = lat, label = Statistica),
                  nudge_x = .7,
                  max.overlaps = Inf,
                  size = 4,
                  segment.color = "grey50",
                  segment.size = .25) +
  geom_sf(data = cra3,
          fill = "white") +
  xlab("Longitude") +
  ylab("Latitude")

Note that the x, y, and label values for the CRA3 polygons were declared in aes() so now ggrepel() knows what to write and where to put them:

result

As before, to colour the polygons, you need to declare fill = inside aes(). Then, use scale_fill_manual() to assign the colour values. R colour names and hex colour values e.g. #CC79A7 are accepted. This example uses hex values.

# Plot with labels and colour
ggplot(data = cra3) + 
  geom_text_repel(data = sf_points,
                  aes(x = long, y = lat, label = Statistica),
                  nudge_x = .7,
                  max.overlaps = Inf,
                  size = 4,
                  segment.color = "grey50",
                  segment.size = .25) +
  geom_sf(aes(fill = Statistica)) +
  scale_fill_manual(name = "CRA3", 
                    values = c("#CC79A7", "#0072B2", "#E69F00")) +
  xlab("Longitude") +
  ylab("Latitude")

The result:

result2

Data:

cra3 <- structure(list(Statistica = c("909", "910", "911"), geometry = structure(list(
    structure(list(structure(c(178.054690999921, 178.230989000334, 
    178.374999999817, 178.580453999551, 178.597331000511, 178.601092999722, 
    178.616812000022, 178.646281000377, 178.661052000147, 178.688828000126, 
    178.702396000226, 178.728038999609, 178.740205999642, 178.741443000545, 
    178.754426000446, 178.782219000448, 178.795783999425, 178.821443000437, 
    178.833616000337, 178.856734999806, 178.867364999595, 178.88758299992, 
    178.896550999444, 178.913545000206, 178.920786000499, 178.934290000026, 
    178.939746999964, 178.949548000567, 178.952749999821, 178.953199999426, 
    178.959143000553, 178.960483999564, 178.960835000158, 178.960971000334, 
    178.962963000468, 178.963177999698, 178.963177999698, 178.962963000468, 
    178.960971000334, 178.960835000158, 178.960483999564, 178.959143000553, 
    178.953199999426, 178.952749999821, 178.949548000567, 178.939746999964, 
    178.934287000092, 178.920783000565, 178.913545000206, 178.896550999444, 
    178.889907000274, 178.880935000047, 178.86071600014, 178.850081999646, 
    178.826960000243, 178.816290000542, 178.81081400023, 178.809874999502, 
    178.80473899963, 178.791206999927, 178.783947000449, 178.776754999871, 
    178.773478999472, 178.773025999934, 178.769805000305, 178.763808999948, 
    178.763945999706, 178.765948000412, 178.766164999994, 178.766164999994, 
    178.765948000412, 178.763945999706, 178.763808999948, 178.763453000256, 
    178.76209899955, 178.761052000011, 178.333333000508, 178.054690999921, 
    -38.1166669995907, -37.8385699998304, -37.6333330003274, 
    -37.3405019995364, -37.3530660003351, -37.3554349997464, 
    -37.3594780001988, -37.3687170003261, -37.3742190003224, 
    -37.3863110004396, -37.393126999885, -37.4078810000242, -37.4158480003568, 
    -37.4167679997021, -37.421706000203, -37.433797999619, -37.4406079995483, 
    -37.4553610002619, -37.463327999801, -37.4805080003658, -37.4894629998991, 
    -37.5088039995559, -37.5185690001469, -37.5397599997011, 
    -37.5501790003721, -37.5728900004281, -37.5837939997213, 
    -37.6076650003898, -37.6171430002366, -37.6189160002415, 
    -37.6435720001104, -37.6505999999412, -37.653511000358, -37.6550220000926, 
    -37.6800710002872, -37.6843820000314, -37.6872839995532, 
    -37.6915940004214, -37.7166429996792, -37.7181540003066, 
    -37.7210660000461, -37.728095000322, -37.752748999707, -37.7545209997014, 
    -37.7639979996459, -37.787870000128, -37.7987789997016, -37.8214890004098, 
    -37.8319039995435, -37.8530960001873, -37.8605949999305, 
    -37.8703629997438, -37.8897039995664, -37.898662000298, -37.9158420003772, 
    -37.9304219997909, -37.9413419995689, -37.942917999834, -37.9530110004025, 
    -37.9757209996329, -37.9861459995776, -37.9950959997078, 
    -38.0086420001961, -38.0104180003274, -38.0199220004242, 
    -38.0376400004512, -38.0391589995937, -38.0642100003859, 
    -38.0685410002353, -38.0714590001264, -38.0757900003803, 
    -38.1008389999017, -38.1023579996967, -38.1052840004431, 
    -38.1123469997801, -38.1166669995907, -38.1166669995907, 
    -38.1166669995907), dim = c(78L, 2L))), class = c("XY", "POLYGON", 
    "sfg")), structure(list(structure(c(177.68678899961, 178.054690999921, 
    178.333333000508, 178.761052000011, 178.756124999501, 178.755669999611, 
    178.752437999828, 178.750004999892, 178.751317000333, 178.751533999915, 
    178.751533999915, 178.751317000333, 178.749311999693, 178.749174999935, 
    178.748817999473, 178.747794999406, 178.748171000243, 178.751420999629, 
    178.751877999872, 178.757869999525, 178.759233000032, 178.759590000494, 
    178.759727999834, 178.76173699999, 178.761955000342, 178.761955000342, 
    178.76173699999, 178.759727999834, 178.759590000494, 178.759233000032, 
    178.757869999525, 178.751877999872, 178.751420999629, 178.748171000243, 
    178.738287999464, 178.733824999834, 178.734043000187, 178.734043000187, 
    178.733824999834, 178.731812999745, 178.731673999634, 178.731315000008, 
    178.729947999985, 178.723945000178, 178.723487000354, 178.720227000395, 
    178.710328000365, 178.704780000448, 178.691141000327, 178.683806999704, 
    178.677007999984, 178.670996000376, 178.670536000199, 178.667267000438, 
    178.657351999968, 178.651789999963, 178.648888999631, 178.64575899998, 
    178.640194999623, 178.626529999678, 178.619173000354, 178.601975000515, 
    178.592903000508, 178.572444999522, 178.561728000459, 178.538332000351, 
    178.526120999703, 178.508578999908, 178.498855999966, 178.48976300042, 
    178.469280000381, 178.45856300013, 178.435138000264, 178.4229230001, 
    178.404972000195, 178.40460599993, 178.392398000404, 178.366394999436, 
    178.348144000191, 178.324697999599, 178.321124000212, 178.338453999522, 
    178.345884000409, 178.359655000002, 178.365288999611, 178.375283999905, 
    178.380285999954, 178.380751999998, 178.383352999802, 177.883333000524, 
    177.68678899961, -38.8597630001569, -38.1166669995907, -38.1166669995907, 
    -38.1166669995907, -38.1370030000971, -38.1387839999432, 
    -38.1483039998458, -38.1541970001492, -38.1705900001463, 
    -38.1749279998076, -38.1778500001402, -38.1821870002351, 
    -38.207235999548, -38.2087580004482, -38.2116889996594, -38.2173790004242, 
    -38.2182859996967, -38.2278280000095, -38.2296130000188, 
    -38.2542670001598, -38.2613500001105, -38.2642849997148, 
    -38.2658070003135, -38.2908560004161, -38.2952019998555, 
    -38.2981300000778, -38.3024769998065, -38.3275259997285, 
    -38.3290480003563, -38.3319830002044, -38.3390649999642, 
    -38.3637199996616, -38.3655060003541, -38.3750490002219, 
    -38.398920999703, -38.4102910000951, -38.4146439998762, -38.4175759997039, 
    -38.4219290001824, -38.4469789997538, -38.4485040003059, 
    -38.4514450000696, -38.4585399997012, -38.4831950000705, 
    -38.4849810000532, -38.4945349997645, -38.5184069995949, 
    -38.5293840003795, -38.5520939999818, -38.5625429998523, 
    -38.5724540002318, -38.5971089998189, -38.5988990001591, 
    -38.6084669999533, -38.6323389998375, -38.6433250002729, 
    -38.6481469999106, -38.6556810000935, -38.6666670000417, 
    -38.689376999825, -38.6998389996078, -38.7210310002949, -38.730794000188, 
    -38.7501349995849, -38.7590569995789, -38.7762380004636, 
    -38.7841360002775, -38.7941020004194, -38.8060699996746, 
    -38.8158429997428, -38.8351820000334, -38.844094999581, -38.8612769997772, 
    -38.8691669997686, -38.879354999645, -38.8796239996337, -38.887507999639, 
    -38.9022610002253, -38.9130150001424, -38.9301969999723, 
    -38.9336889999534, -38.9548799999061, -38.9653669998531, 
    -38.9880769998582, -38.9991179998301, -39.0229889998822, 
    -39.0376200000304, -39.0394189998973, -39.0499999996346, 
    -39.0499999996346, -38.8597630001569), dim = c(91L, 2L))), class = c("XY", 
    "POLYGON", "sfg")), structure(list(structure(c(178.383352999802, 
    178.38681300051, 178.388206000357, 178.388571999432, 178.388712999895, 
    178.390744000359, 178.390966999809, 178.390966999809, 178.390744000359, 
    178.388712999895, 178.388571999432, 178.388206000357, 178.38681300051, 
    178.380751999998, 178.380285000372, 178.376966999709, 178.366970999832, 
    178.361337000224, 178.34756499986, 178.340135999744, 178.334047999827, 
    178.331804000485, 178.331904999847, 178.332129000067, 178.332129000067, 
    178.331904999847, 178.329869000285, 178.329727000241, 178.329360000395, 
    178.327960999491, 178.32188600008, 178.321417000102, 178.318085000539, 
    178.308065999585, 178.302409999668, 178.28860500003, 178.281150999672, 
    178.263779000097, 178.254610999826, 178.233945000248, 178.223159000327, 
    178.199522999559, 178.187286000275, 178.161057999504, 178.147514000065, 
    178.119101999821, 178.084433999792, 178.070896999802, 178.04247200024, 
    178.027838000228, 177.997675999674, 177.982216999991, 177.950797999767, 
    177.946804000116, 177.934748000017, 177.90256399999, 177.900600000033, 
    177.89342099996, 177.886218999998, 177.853781000411, 177.846579000449, 
    177.839398999607, 177.837434999649, 177.805252000392, 177.793196000294, 
    177.789201999454, 177.757783000418, 177.742320000031, 177.712157999477, 
    177.703829000152, 177.689198000074, 177.660773000512, 177.647240000038, 
    177.620996999598, 177.60874900016, 177.587805999944, 177.402662999678, 
    177.335292000347, 177.68678899961, 177.883333000524, 178.383352999802, 
    -39.0499999996346, -39.064074000213, -39.0712340000483, -39.0742020003834, 
    -39.0757429997171, -39.1007939997922, -39.1051870003467, 
    -39.108146999859, -39.1125409996361, -39.1375900003998, -39.1391300004387, 
    -39.1420979996062, -39.1492569999487, -39.1739130003105, 
    -39.1757169997071, -39.1853499999329, -39.2092209999977, 
    -39.2202600001451, -39.2429699995597, -39.2534530001379, 
    -39.2617920004396, -39.2645350004527, -39.2657780002365, 
    -39.2701819997616, -39.2731499998028, -39.2775539997419, 
    -39.3026039996488, -39.3041469997723, -39.3071219998573, 
    -39.3142970000146, -39.3389520001959, -39.3407579997223, 
    -39.3504079999374, -39.374280000239, -39.3853369996863, -39.4080469999238, 
    -39.4185410003878, -39.4397329997316, -39.4494999999955, 
    -39.4688409997807, -39.4777309997999, -39.4949109998232, 
    -39.5027460002507, -39.5174999999844, -39.5241530000568, 
    -39.5362450001222, -39.5541819999885, -39.5608279997045, 
    -39.5729210000891, -39.5782479996802, -39.5874859998754, 
    -39.5913709999164, -39.5976129996598, -39.598355000018, -39.5999820001496, 
    -39.6031289997821, -39.6033090002192, -39.6037709999488, 
    -39.6039250003942, -39.6039250003942, -39.6037709999488, 
    -39.6033090002192, -39.6031289997821, -39.5999829996117, 
    -39.5983560004233, -39.5976140000759, -39.5913720004234, 
    -39.5874850002315, -39.5782460001238, -39.5754680000328, 
    -39.5701420002437, -39.5580499999112, -39.551405999985, -39.5366530000879, 
    -39.5288139998611, -39.513597000077, -39.0646710002976, -38.9013539998739, 
    -38.8597630001569, -39.0499999996346, -39.0499999996346), dim = c(81L, 
    2L))), class = c("XY", "POLYGON", "sfg"))), class = c("sfc_POLYGON", 
"sfc"), precision = 0, bbox = structure(c(xmin = 177.335292000347, 
ymin = -39.6039250003942, xmax = 178.963177999698, ymax = -37.3405019995364
), class = "bbox"), crs = structure(list(input = "WGS 84", wkt = "GEOGCRS[\"WGS 84\",\n    DATUM[\"World Geodetic System 1984\",\n        ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n            LENGTHUNIT[\"metre\",1]]],\n    PRIMEM[\"Greenwich\",0,\n        ANGLEUNIT[\"degree\",0.0174532925199433]],\n    CS[ellipsoidal,2],\n        AXIS[\"latitude\",north,\n            ORDER[1],\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n        AXIS[\"longitude\",east,\n            ORDER[2],\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n    ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), row.names = c(NA, 
3L), class = c("sf", "data.frame"), sf_column = "geometry", agr = structure(c(Statistica = NA_integer_), levels = c("constant", 
"aggregate", "identity"), class = "factor"))
1
Friede On

Another alternative would be to color code each polygon and have a legend titled Statistical Areas (and the colors for 909, 910,911 corresponding).

The following example is adapted from here, with Statistical Areas ~ States.

library(ozmaps)
library(sf)
#> Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
library(ggplot2)

# Australia 
oz_states = ozmaps::ozmap_states
# Some "non-random" points
oz_capitals <- tibble::tribble( 
  ~city,           ~lat,     ~lon,
  "Sydney",    -33.8688, 151.2093,  
  "Melbourne", -37.8136, 144.9631, 
  "Brisbane",  -27.4698, 153.0251, 
  "Adelaide",  -34.9285, 138.6007, 
  "Perth",     -31.9505, 115.8605, 
  "Hobart",    -42.8821, 147.3272, 
  "Canberra",  -35.2809, 149.1300, 
  "Darwin",    -12.4634, 130.8456, 
)

ggplot() + 
  geom_sf(data = oz_states, mapping = aes(fill = NAME), show.legend = TRUE) +
  geom_point(data = oz_capitals, mapping = aes(x = lon, y = lat), colour = "black") + 
  coord_sf() +
  labs(x = "Longitude", y = "Latitude", fill = "States")

Labels outside polygons - possibly achievable with ggsflabel::geom_label_repel (for-sf).