-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path06-pointLocations.Rmd
705 lines (545 loc) · 30.2 KB
/
06-pointLocations.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
# Linked Micromap Plots for Point Locations {#Ch6}
\chapterauthor{Martin Holdrege, J{\"u}rgen Symanzik}
A few stand-alone attempts have been made in the past to create linked micromap plots
for point locations such as climate stations and cities, rather than for areal locations
(i.e., polygons).
This requires that the point location is extended to a small (circular or quadratic)
area that can be color-coded in a linked micromap plot. This chapter provides an
overview of necessary steps to produce linked micromap plots for point locations
to create areas of suitable sizes and to avoid overplotting of nearby point locations.
## Introduction: The challenge of displaying point data using micromaps
One obstacle to creating micromaps for point locations is that the user
must create polygons to represent the
point locations. The more standard use of micromaps, displays information associated
with geographic areas for which the associated spatial data
likely already exists. In the case of point locations,
points need to be displayed on the
map as circles (or other shape). The coordinates of a given point location become the center of the circle.
Once the polygons are created, maps and accompanying data can be visualized
using the **micromap**\index{R Packages!micromap} [@PaOl2015] package,
which requires that each entity for which data
is displayed is a polygon on the map.
When creating the polygons (circles) for display on a
micromap, they
need to be appropriately sized and should not overlap too much with each other.
The locations of points that are very close to each other may need to be adjusted so they can be distinguished on the micromap.
Lastly, to create more useful micromaps, the polygons representing the point
locations also need to be
integrated into a base map that shows relevant geographic boundaries.
As with more traditional micromaps, values from multiple variables can be shown
for each location. Additionally, as with other micromaps, there is a space constraint,
and generally, it is challenging to effectively display more than roughly
50 point locations in one micromap..
It is also important to first consider whether a micromap of point locations is
the appropriate visualization for the data that you're trying to display.
You should consider whether the points represent a broader geographic area, which could be represented by larger polygons,
as is done in more traditional micromaps presented in the previous chapters. For example, in
section \@ref(Ch6-Utah) we provide an example where we plot data associated with County Seats in
the state of Utah. In that case there is one point location (city) per county, so it would
also be possible to make an effective micromap where instead of showing the point locations,
the corresponding counties are shown, which would potentially require fewer steps to
create.
## Outline of steps to create micromaps of point locations
Broadly, the following steps need to be taken to display point locations
on micromaps.
1. Obtain coordinates of the point locations of interest along with
the corresponding data to display.
1. Obtain geographic data for the underlying base map. Strictly speaking, the micromaps of point locations could be shown without a base map
but in most cases we think that would make a less useful visualization because there would be no geographic context.
1. Create a simple plot of the point locations. The locations of points that are close to each other may need to be adjusted.
If points are very close together they may overlap on the final map,
making them hard or impossible to distinguish from each other. The trade off here is that adjusting point locations does lead to some geographic
distortion.
We provide examples of both manual and semi-automated approaches to adjusting point locations.
1. Polygons need to be created around points. This step
is necessary because the **micromap**\index{R Packages!micromap} package was designed to show polygons,
not points, on maps. Thus, each point becomes a small polygon
that is then visible in the resulting micromaps.
Multiple R packages offer ways to create buffers (polygons) around points,
and the `points2circles()` function (described below) provides a convenient wrapper to do this.
1. The base map and polygons representing point locations need to be
combined into single object. This step may require re-projecting one or both datasets
into a common projection. The resulting object contains polygons
that will have data associated with them (i.e., the polygons showing the point locations),
as well as polygon(s) that form the background of the map.
1. As described in section \@ref(Ch2-Linking), the `micromap::mmplot()` function, which creates the figure, requires a specially formatted dataframe as input.
Therefore, the object created in the previous step (which may, for example, be
an object from the **sf**\index{R Packages!sf} package [@Pebesma2018])
needs to be converted into such a dataframe.
1. Create an initial simple micromap. To make troubleshooting easier, we recommend that you initially do not add all visualization elements (e.g., error bars, labels, multiple variables).
1. Iterate until the size of the circles representing point locations
and their level of overlap is acceptable (see step 3).
1. As necessary, add additional visualization elements including labels, and adjust dimensions
of the figure until you're satisfied with the final product.
We walk through these steps, and provide additional details using three separate
examples.
In Section \@ref(Ch6-Example1), we create a micromap showing
the populations of large cities across Asia. Section \@ref(Ch6-Utah) provides
a more complex example where point locations are manually adjusted to limit overlap, and section
\@ref(Ch6-Example3) provides an example where point locations are repelled
from each other using the `point_repel()` function.
## Plot large cities in Asia {#Ch6-Example1}
In this example, we create a relatively simple micromap that shows the locations of the 10 largest cities
in Asia, and their associated populations.
To begin, the necessary packages need to be loaded.
```{r Ch6-libraries, message = FALSE, warning = FALSE}
library(micromap)
library(sf)
library(dplyr)
source("R/Ch6_functions.R") # provides custom functions
```
### Load point location data
Next we load the point location data, which is in the form of a dataframe, that contains four
columns that we will use: `city`, `population`, `lat`, and `long`.
```{r Ch6-LoadCities}
cities <- readRDS("data/Ch6-data/asian_cities.RDS")
```
We convert the population column to be in units of millions of people,
so that the numbers are more readable in the final
micromap.
```{r Ch6-LoadPopulation}
cities$population <- cities$population/10^6
```
Before moving on to create the micromap it can be helpful to create a preliminary figure
of the point locations. In examining the locations of the cities in this dataset (Figure \@ref(fig:Ch6-AsiaScatterPlot)), we can see that none of
the cities are very close together. Therefore, when we draw circles around the point
locations we won't need to be worried about undo overlap in the final figure.
```{r Ch6-AsiaScatterPlot, fig.cap='Latitude and longitude of 10 large cities in Asia. Note, in this example the point locations are far apart, and therefore the final map will not have overplotting issues.'}
plot(cities$long, cities$lat, xlab = "Longitude", ylab = 'Latitude')
```
### Generate polygons around points
Our next task is to draw circles around the points. However, first the
point location data needs to be properly formatted. We first convert the `cities` dataframe to a
simple features (`sf`) object from the **sf**\index{R Packages!sf} package [@Pebesma2018].
Usually metadata or other descriptions of the data will provide the coordinate
reference systems ("crs"). In this example we happen to know that the crs is `EPSG:4326`
and we can specify that using the `crs` argument. Correctly specifying the crs is
important for section \@ref(Ch6-Example2Combine) where we combine this object
with a basemap.
In this step we also use the `sf::st_transform()` function to transform the data
to a projection that is more suitable for mapping locations in Asia.
This transformation has the added benefit of making `sf::st_crop()` work smoothly in a later cropping step (the data are now projected onto a plane unlike the original un-projected latitude and longitude coordinates).
```{r Ch6-cities_sf}
cities_sf <- st_as_sf(cities, coords = c("long", "lat"), crs = 4326) %>%
st_transform(crs = 'EPSG:8859')
names(cities_sf)
```
The `cities_sf` object contains the same columns as the original dataset,
except that the `long` and `lat` columns have been replaced by a `geometry` column.
The `geometry` column contains spatial data that defines the point locations of
each city (row) in the dataset. `sf` objects
are special kinds of dataframes, that can represent a wide variety
of spatial data (in the `geometry` column) and also contain additional spatial
metadata (see https://r.geocompx.org/ for more details).
Next we create circles around the point locations, which we do with the `points2circles()` function.
This function can be supplied
a dataframe with columns that give the x and y coordinates, or an `sf` object.
By default the radius of the circles is 5% of the range of the x variable
(i.e., 5% of the width of the map).
A different value can be passed to the radius argument to adjust the size of the circles,
The resulting output of `points2circles()` is an object of class `sf`.
```{r Ch6-CreateCircles-Asia}
circles_sf <- points2circles(cities_sf,
radius = 5)
names(circles_sf)
```
The default method of the `micromap::mmplot()` function requires a dataframe as input, which can be created
using `micromap::create_map_table()` (see section \@ref(Ch2-Steps)). The`sf` object first needs to be converted to a `Spatial` object,
before it can be be passed to `create_map_table()`(this is accomplished with
`sf::as_Spatial()`).
```{r Ch6-CreateMapTableAsia}
circles_df <- create_map_table(
tmp.map = as_Spatial(circles_sf),
IDcolumn = "city"
)
```
### Create micromap
Figure \@ref(fig:Ch6-micromap1) shows a rudimentary micromap with the locations of the cities shown as circles.
```{r Ch6-micromap1, fig.cap = 'Micromap showing the 10 largest cities in asia. Note that locations of cities are shown, but there are no country polygons to indicate the location of cities', fig.width = 4, fig.height = 3}
mmplot(stat.data=cities,
map.data=circles_df,
panel.types=c("labels", "dot", "map"),
panel.data=list("city","population", NA),
ord.by="population", grouping=5,
map.link=c("city","ID"))
```
### Combine point locations and background map {#Ch6-Example2Combine}
To make a better micromap, the circles showing the city locations need to be combined
with a basemap. Some data wrangling may be needed to acquire the necessary basemap (see section \@ref(Ch4)
for more details on preparing shapefiles for use in micromaps).
For this example were using a dataset of country polygons for the whole world.
This dataset can be downloaded using the **rnaturalearth**\index{R Packages!rnaturalearth} package [@Massicotte2023].
```{r eval = FALSE}
wrld <- rnaturalearth::ne_download(scale = 'small', type = "countries",
returnclass = 'sf', category = 'cultural', load = TRUE)
```
For convenience we provide a copy of this dataset (containing a subset of the columns).
```{r Ch6-wrld}
wrld <- readRDS("data/Ch6-data/world_countries.RDS")
```
We first transform the `wrld` object so that it has the
same coordinate reference system as the `circles_sf` object.
```{r Ch6-CheckWrldCRS}
wrld <- st_transform(wrld, crs = st_crs(circles_sf))
```
Next we use the `sf::st_crop()` function so that only the region we're interested in will be shown.
We then crop the map based on the extent of the `circles_sf` object we previously created.
Note that we are using the `sf::st_bbox()` function to get the bounding box of the `circles_sf` object, and then cropping to the extent
of that bounding box.
```{r Ch6-crop, warning = FALSE, message = FALSE}
asia <- st_crop(wrld, st_bbox(circles_sf))
```
Prior to combining the `asia` and `circles_sf` objects, a new column needs
to be added to the `asia` object. When creating micromaps the input includes an 'ID' column
that contains names that uniquely identify the polygons for which data will be shown (see section \@ref(#Ch2-Example1)).
Polygons that are shown on the map but for which no data is shown (i.e., which form the map in the background)
have `NA` values in the 'ID' column.
The 'ID' column in the `circles_sf` object is `city`, and so here we add an empty
column of that name to `asia`, before binding the datasets together.
```{r Ch6-ExtendAsia}
asia$city <- NA
comb_sf <- rbind(circles_sf['city'], asia['city'])
```
```{r Ch6-CombColumns}
names(comb_sf)
```
The resulting `comb_sf` object contains two columns. Note that when selecting a specific column of an `sf` object using `object['columnName']`, an `sf` object is returned with the desired column as well as the `geometry` column. In other words, the `geometry` column is 'sticky' and comes along when selecting columns in this way, so that the associated spatial information is not lost.
Next we need convert the object into a regular dataframe using `micromap::create_map_table()` so that it can be used
in the `micromap::mmplot()` function.
```{r Ch6-CreateMapTableCities}
comb_df <- create_map_table(
tmp.map = as_Spatial(comb_sf),
IDcolumn = "city"
)
head(comb_df, 3)
```
Note that in the `comb_df` dataframe the `ID` column is `NA` for all polygons associated
with the base map, and is filled with the city name for all polygons (circles)
that represent cities.
### Micromap showing base map {#Ch6-Example1Micromap2}
Now we can create the micromap with the base map displayed. To properly
display the base map the `map.all` argument for the map panel needs to be set to `TRUE`
(in this case the maps are shown in the third panel). That way polygons that have no data
(i.e., polygons where the `ID` column is `NA`) also appear.
Additionally, the `nodata.border.color` argument needs to be passed a color
(here we use "black"), to define the color of the base map lines. The width
of those lines is set with the `nodata.border.size` argument.
The `micromap::mmplot` ducumentation (`?mmplot`), provides information on additional arguments.
```{r Ch6-micromap2, fig.cap = 'Micromap showing the 10 largest cities in asia', fig.width = 5, fig.height = 3}
mmplot(stat.data=cities,
map.data=comb_df,
panel.types=c("labels", "dot", "map"),
panel.data=list("city","population", NA),
ord.by="population", grouping=5,
map.link=c("city","ID"),
panel.att = list(
list(2, panel.width = 0.5),
list(2, panel.width = 0.75),
list(3,
map.all = TRUE,
active.border.color = 'black',
active.border.size = 0.3,
inactive.border.color = "gray",
inactive.border.size = 0.3,
panel.width = 1,
outer.hull = FALSE,
nodata.border.color = "black",
nodata.border.size = 0.5))
)
```
## County seats in Utah {#Ch6-Utah}
Here we provide an example of a micromap that shows data for the 29 towns or cities in Utah, USA
that are the County seats of the 29 counties in the
state. In this example we also adjust the locations of some of the points to reduce over-plotting
in the final figure.
### Load point locations and base map data
First we load the point locations, this is an `sf` object,
which provides the name of the county seat, as well as its elevation, population,
coordinates (in the `geometry` column), and the name of the county.
```{r Ch6-ReadRDS}
seats1 <- readRDS("data/Ch6-data/utah_counties.RDS")
class(seats1)
names(seats1)
```
Next we want to load a spatial dataset from the **tigris**\index{R Packages!tigris} package [@Walker2024] that contains
polygons of counties
in Utah, which we can use as a basemap.
```{r Ch6-UTCounites, cache = TRUE, message = FALSE, results='hide'}
county_polygon <- tigris::counties("Utah", cb = TRUE,
year = 2020)
```
Before moving on we need to check whether the base map
and point locations have the same coordinate reference system
```{r Ch6-CheckCountiesCRS}
st_crs(county_polygon) == st_crs(seats1)
```
Since they are different, one of the objects needs to be re-projected.
Here we're re-projecting the `seats1` object, so that it has the same coordinate
reference systems as the `county_polygon` object.
```{r Ch6-TransformCountiesCRS}
seats2 <- st_transform(seats1, crs = st_crs(county_polygon))
```
### Adjust point locations
Figure \@ref(fig:Ch6-CountyMap) shows that some county seats are quite close
to each other, especially in the north-central portion of the state.
In many cases (such as the one shown in section \@ref(Ch6-Example1)),
no adjustment of point locations is needed because the points are naturally well spaced.
However, in this cased we may want adjust the locations of some of these
points so that they are more easily visible in the final micromap. The user needs to
consider how they want to balance being able to see all points
in the micromap (i.e., so there is limited overlap), while not moving points
so far as to create a misleading visualization. We think it is also
important that figure captions disclose when point locations have been adjusted.
```{r Ch6-CountyMap, fig.cap="Locations of counties and county seats (points), in Utah."}
plot(county_polygon$geometry)
plot(seats2$geometry, add = TRUE, pch = 19, col = 'blue ')
```
There are multiple ways that point locations could be adjusted. A tedious, but effective,
method could be to manually choose new coordinates. In this case, another viable option is to replace the coordinates of
of some county seats with the centroid of their respective county. That way we can avoid
excessive over-plotting of the points on the micromap while still having
the points appear in the correct county.
Here, there are several county seats have locations we may want to adjust.
To do this we first create a vector of names of counties who's county seats we want to move.
Then we calculate the centroids of those counties using the `sf::st_centroid()` function.
```{r Ch6-CountiesCentroids, warning = FALSE}
county_names <- c("Weber", "Morgan", "Davis", "Salt Lake", "Summit", "Wasatch",
"Box Elder")
centroids <- county_polygon %>%
filter(NAME %in% county_names) %>%
st_centroid()
```
Next we replace the coordinates of the county seats with the centroids of the county they are located in.
Note here we are first arranging the columns that contain county names into alphabetical order in both the
`seats2` and `centroids` objects so that
that the row ordering matches and correct coordinates are replaced.
```{r Ch6-CountiesReplacement}
seats_adjust1 <- arrange(seats2, county)
centroids <- arrange(centroids, NAME)
seats_adjust1$geometry[seats_adjust1$county %in% county_names] <-
centroids$geometry
```
Figure \@ref(fig:Ch6-CountyMap2) shows the effect of adjusting these points.
```{r Ch6-CountyMap2, fig.cap="Original locations of county seats in blue, and adjusted locations (county centroids) in red."}
plot(county_polygon$geometry)
plot(seats2$geometry[seats2$county %in% county_names], add = TRUE,
pch = 19, col = 'blue')
plot(seats_adjust1$geometry[seats_adjust1$county %in% county_names],
add = TRUE, pch = 19, col = 'red')
```
We leave it as an exercise to the reader to adjust the locations of other
county seats to further improve the final map.
### Prepare points and basemap for `mmplot()`
Now that we have adjusted the point locations, we need to create circles around the points, that will be displayed on the micromap.
```{r Ch6-PlotCircles, fig.cap="Circles drawn around thelocations of county seats. No that overlap between individual circles is fairly limited, because some locations have been adjusted."}
seats_circles <- points2circles(seats_adjust1, radius = 8)
plot(seats_circles$geometry)
```
Next the `seats_circles` needs to be combined
with `county_polygons`.
To be able to bind the two objects, the `county_polygon` object needs to
have an empty county_seats column (as described in section \@ref(#Ch6-Example2Combine))
```{r Ch6-ExtendCounties}
county_polygon$county_seat <- NA
seat_map <- rbind(county_polygon['county_seat'],
seats_circles['county_seat'])
```
The `seat_map` object is a `sf` object that needs to be converted
to a `Spatial` object before it can be flattened into a regular data frame using the
`micromap::create_map_table` function.
```{r Ch6-CreateMapTableCounties}
seat_map_df <- create_map_table(
tmp.map = as(seat_map, 'Spatial'),
IDcolumn = "county_seat"
)
```
### Create micromap
We now have the necessary data to create the micromap using the `mmplot` function.
Note that the stat.data argument in the `micromap::mmplot` function must be passed a dataframe, and the class of
`seats1` is `sf`. Therefore, we use the `sf::st_drop_geometry` function to drop the geometry
column (i.e., which contains the spatial data) and convert the object to a regular dataframe.
```{r Ch6-dropGeometry}
seats_df <- st_drop_geometry(seats1)
```
Note that, as described in section \@ref(#Ch6-Example1Micromap2), the `map.all`,
`nodata.border.color`, and `nodata.border.size` arguments are specified for the
third panel so that the polygons that make up the basemap are plotted.
```{r Ch6-MicromapSeat, fig.cap = "Micromap showing the elevations of county seats in Utah. Some locations have been adjusted to decrease overplotting", fig.width = 5, fig.height = 7}
mmplot(stat.data = seats_df,
map.data = seat_map_df,
panel.types = c("labels", "dot", "map"),
panel.data = list("county_seat","elevation", NA),
ord.by = "elevation",
grouping=5,
map.link=c('county_seat', "ID"),
panel.att = list(
list(1, header = "County Seat",
panel.width = 1),
list(2, header = "Elevation",
xaxis.title = "feet",
panel.width = 1.8),
list(3, header = "Light Gray Means\nHighlighted Above",
map.all = TRUE,
active.border.color = 'black',
active.border.size = 0.3,
inactive.border.color = "gray",
inactive.border.size = 0.3,
panel.width = 1,
outer.hull = FALSE,
nodata.border.color = "black",
nodata.border.size = 0.5,
outer.hull.size = 0.5))
)
```
## Premier league football stadiums {#Ch6-Example3}
For this example we will be using locations of premier league football
stadiums. A challenge with this data set is being able to properly visualize multiple
locations that are very close together, such as the several stadiums located
in London. This is likely to be a common issue that a
user will run into, where locations are clustered in, for example, urban areas.
Here we show a micromap with the actual stadium locations plots, and then create a second version of the micromap where we use a more automated approach to repel locations of stadiums that are too close together.
### Obtain point locations
The data set contains the name of the stadium, the team that plays there,
the capacity of the stadium, number of total spectators over the 2018 season,
the average number of spectators at a match, and the
coordinates (`geometry` column).
```{r Ch6-ReadStadiums}
stadiums <- readRDS("data/Ch6-data/stadiums.RDS")
names(stadiums)
```
Next we "draw" circles around the points.
```{r Ch6-CreateCirclesStadiums}
stadium_circles <- points2circles(stadiums, radius = 8)
```
### Acquire the underlying map
We can extract a basemap of the UK, and then crop it to the extent we are
interested (here we are only keeping the `geometry` information because we're not
interested in any of the associated country information).
```{r Ch6-ExtractUKBasemap}
uk_map <- wrld[wrld$NAME == "United Kingdom", ]
uk_map<- st_crop(uk_map['geometry'],
c(xmin = -5, ymin = 50, xmax = 0, ymax = 56))
```
Now add the empty "ID" column.
```{r Ch6-TransformUKBasemap}
uk_map$stadium <- NA
```
### Combine with points
Compare CRS
```{r Ch6-CheckCRSStadiums}
st_crs(uk_map) == st_crs(stadium_circles)
```
```{r}
uk_map <- st_transform(uk_map, st_crs(stadium_circles))
```
Next we bind the the base map and the point locations together.
```{r Ch6-CreateMapTableExtendedStadiums}
stadiums_map1 <- rbind(uk_map['stadium'], stadium_circles['stadium'])
stadiums_map_df <- create_map_table(
tmp.map = as(stadiums_map1, 'Spatial'),
IDcolumn = "stadium"
)
```
### Create initial micromap
Here we create a micromap showing stadium locations that are not adjusted
(i.e., still overlapping).
```{r Ch6-micromap4, fig.cap = 'Micromap showing stadium locations, note that these maps aren not very readable due to the overlap in locations', fig.width = 5, fig.height = 7}
mmplot(stat.data=st_drop_geometry(stadiums),
map.data=stadiums_map_df,
panel.types=c("labels", "dot", "map"),
panel.data=list("stadium","capacity", NA),
ord.by="capacity", grouping=5,
map.link=c('stadium', "ID"),
panel.att = list(
list(1, panel.width = 1.8),
list(3,
map.all = TRUE,
active.border.color = 'black',
active.border.size = 0.3,
inactive.border.color = "gray",
inactive.border.size = 0.3,
panel.width = 1,
outer.hull = FALSE, # shows outside of map
# this is required to see all map borders:
nodata.border.color = "black",
nodata.border.size = 0.5,
outer.hull.size = 0.5))
)
```
### Micromap with adjusted stadium locations
The the `point_repel()` function can be used to repel points that are too
close together, so that in this case the cluster of stadiums in London
don't all over-plot each other. Here some of the default arguments in `point_repel()`
were changed (`rep.fact` & `adj.max`) to increase the distance between points.
The default arguments may need to be adjustment to obtain satisfactory repulsion
between points (see function documentation for details).
Note that points that are already far apart are not moved.
```{r Ch6-RepelPointsStadium}
stadiums_repel <- point_repel(stadiums, rep.fact = 50, adj.max = 1)
par(mfrow = c(1, 2))
plot(stadiums$geometry, main = 'Original point locations')
plot(stadiums_repel$geometry, main = 'Repelled points')
```
Now circles need to be drawn around the points.
```{r Ch6-CreateCirclesAndMapTableStadiums}
stadium_circles_repel <- points2circles(stadiums_repel, radius = 8)
stadiums_map_repel <- rbind(uk_map['stadium'],
stadium_circles_repel['stadium'])
stadiums_map_repel_df <- create_map_table(
tmp.map = as(stadiums_map_repel, 'Spatial'),
IDcolumn = "stadium"
)
```
```{r Ch6-micromap5, fig.cap = 'Micromap showing stadium locations. Here the stadium locations have been moved slightly so that complete overlap of points does not occur. Micromaps can contain two label columns, as seen here where both the stadium name and team name are provided.', fig.width = 7.5, fig.height = 7}
mmplot(stat.data = st_drop_geometry(stadiums),
map.data = stadiums_map_repel_df,
panel.types = c("labels", "dot", "map", "labels"),
panel.data = list("stadium","capacity", NA, "team"),
ord.by = "capacity", grouping=5,
map.link = c('stadium', "ID"),
panel.att = list(
list(1, header = "Stadium",
panel.width = 1.8),
list(2, header = "Stadium\nCapacity"),
list(3,header = "Light Gray Means\nHighlighted Above",
map.all = TRUE,
active.border.color = 'black',
active.border.size = 0.3,
inactive.border.color = "gray",
inactive.border.size = 0.3,
panel.width = 1,
outer.hull = FALSE,
nodata.border.color = "black",
nodata.border.size = 0.5,
outer.hull.size = 0.5),
list(4, header = 'Team', panel.width = 1.8, align = 'left'))
)
```
## Summary and Further Reading {#Ch6-SummaryFurtherReading}
In this chapter, we have outlined the essential steps to create linked micromap
plots for point locations. The point location data requires some pre-processing
before the **micromap**\index{R Packages!micromap} R package can be used to create the figure.
The process begins with obtaining coordinates and and data of interest for the
point locations. Next, geographic data for the underlying base map is obtained
and prepared. A preliminary plot of the point locations is created, and if
necessary adjustments are made to the point locations to limit overplotting.
Polygons (circles or other shape) are then generated to represent the point
locations. These polygons are integrated with the base map.
The combined object is then converted into a dataframe suitable for use with the
`micromap::mmplot()` function. An initial simple micromap is created, and the
visualization is refined iteratively, adjusting the size and overlap of
polygons, adding labels, and enhancing other visualization elements.
To become proficient in creating linked micromaps for point locations we recommend you also
read Chapter \@ref(Ch1) for a better foundational understanding of the rationale behind
micromaps. Additionally, see Chapter \@ref(Ch2) for a more
thorough coverage of the **micromap**\index{R Packages!micromap} R package and its functionality. Note also
that there are many potential applications for micromaps of point locations that we
did not explore here, such as environmental data collected at fixed sites (see Chapter \@ref(Ch11) for
more on environmental data).
Previously, linked micromap plots for point locations have been used for time series plots
of climate data from weather station locations, accessible through the Utah Climate Center web page
at Utah State University [@Thapliyal2009;@Yarra2010].
Lastly, the types of micromaps we presented in this
chapter could also be presented in different and creative ways such as via web applications
(see Chapter \@ref(Ch7)).
\printbibliography[segment=\therefsegment,heading=subbibliography]