-
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathlayout.qmd
More file actions
582 lines (503 loc) · 27.9 KB
/
layout.qmd
File metadata and controls
582 lines (503 loc) · 27.9 KB
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
```{r}
#| echo: false
source("code/before_script.R")
```
# Map layout {#sec-map-layout}
<!-- https://github.com/geocompx/tmap/issues/20#issuecomment-3209507327 -->
\index{map layout}
Map layout relates to all of the visual aspects of the created plot except the visual variables (@sec-visual-variables and @sec-scales), legends (@sec-legends-and-titles), map components (@sec-map-components), and their positions (@sec-positions).
It includes the map background, frame, typography, scale, aspect ratio, margins, and more.
We can customize the map layout using the `tm_layout()` function.
In this chapter, we cover the most often used arguments of this function using a map of Slovenia's regions as an example (@fig-layout-example).
<!-- ??mention that is has tons of arguments -- we do not going to explain them all, but suggest to look at the help file, when needed -->
<!-- maybe highlight that many layout arguments are valid for the plot mode only -->
```{r}
#| label: fig-layout-example
#| message: false
#| fig-cap: "A map of Slovenia with a default layout."
library(sf)
library(tmap)
slo_borders = read_sf("data/slovenia/slo_border.gpkg")
slo_regions = read_sf("data/slovenia/slo_regions.gpkg")
slo_cities = read_sf("data/slovenia/slo_cities.gpkg")
tm = tm_shape(slo_borders) +
tm_polygons() +
tm_shape(slo_regions) +
tm_polygons(fill = "region_group") +
tm_text(text = "region_name", size = "population") +
tm_credits("Data source: GISCO Eurostat database", fontface = "bold") +
tm_title("Slovenia")
tm
```
## Colors {#sec-lcolors}
\index{map layout!colors}
The most basic map layout customization is the color of the map background.
Actually, there are a few separate zones on the map that can be colored -- it includes, among others, the map background, the outer space background, and the map legend background (@fig-layout-colors).
They can be customized with the `bg.color`, `outer.bg.color`, and `legend.bg.color` arguments of the `tm_layout()` function.
```{r}
#| label: fig-layout-colors
#| fig-cap: "Customized map layout colors: background, outer space, and legend background."
tm +
tm_layout(bg.color = "lightgreen",
outer.bg.color = "forestgreen",
legend.bg.color = "lightblue")
```
The `tm_layout()` function also has tools to modify the complete map color style with arguments such as `color.saturation`, `color.sepia_intensity`, and `color_vision_deficiency_sim.`
The first one represents the saturation of all colors on the map, including the backgrounds, as well as visual variables such as the fill or color of polygons and lines.
The `color.saturation` parameter accepts a value between `0` and `1`, where `0` means no color saturation (i.e., the map is black and white), and `1` means full-color saturation (i.e., the map is colorful, default) (@fig-layout-saturation).
The value of `0` may be useful when we want to create a black-and-white map, for example, to print it on a black-and-white printer, while the values in between `0` and `1` can be used to create a more muted, stylized map.
```{r}
#| label: fig-layout-saturation
#| warning: false
#| layout-nrow: 3
#| fig-cap: "Impact of the `color.saturation` argument on the map layout."
#| fig-subcap:
#| - "value: `0`"
#| - "value: `0.4`"
#| - "value: `0.7`"
tm +
tm_layout(color.saturation = 0)
tm +
tm_layout(color.saturation = 0.4)
tm +
tm_layout(color.saturation = 0.7)
```
The `color.sepia_intensity` argument allows to apply a sepia filter to the map.
<!-- explain? -->
Its value can be set between `0` and `1`, where `0` means no sepia filter (i.e., the map is colorful, default), and `1` means full sepia filter (i.e., the map is brownish) (@fig-layout-sepia).
The sepia filter is a popular effect that gives the map a vintage look.
```{r}
#| label: fig-layout-sepia
#| warning: false
#| layout-nrow: 3
#| fig-cap: "Impact of the `color.sepia_intensity` argument on the map layout."
#| fig-subcap:
#| - "value: `0.4`"
#| - "value: `0.7`"
#| - "value: `1`"
tm +
tm_layout(color.sepia_intensity = 0.4)
tm +
tm_layout(color.sepia_intensity = 0.7)
tm +
tm_layout(color.sepia_intensity = 1)
```
\index{color perception}
\index{color blindness}
\index{color vision deficiency simulation}
Both of the above options aim to change the overall map's look and feel.
The `color_vision_deficiency_sim` has a different purpose: it enables us to visualize how the map would appear to people with different color vision deficiencies.
This could help us to understand how our map is perceived by people with color vision deficiencies, and to make it more accessible.
Three main types of color vision deficiencies are: *protanopia* (red-green color blindness, `"protan"`), *deuteranopia* (red-green color blindness, `"deutan"`), and *tritanopia* (blue-yellow color blindness, `"tritan"`).
```{r}
#| label: fig-layout-color-vision
#| warning: false
#| layout-nrow: 3
#| fig-cap: "Impact of the `color_vision_deficiency_sim` argument on the map layout."
#| fig-subcap:
#| - "value: `\"protan\"`"
#| - "value: `\"deutan\"`"
#| - "value: `\"tritan\"`"
tm +
tm_layout(color_vision_deficiency_sim = "protan")
tm +
tm_layout(color_vision_deficiency_sim = "deutan")
tm +
tm_layout(color_vision_deficiency_sim = "tritan")
```
<!-- ? earth_boundary.color, -->
<!-- ? space.color, -->
## Frame {#sec-lframe}
\index{map layout!frame}
Another possibility to change the map look is to customize the frame around the map content.
Its style depends on several arguments of the `tm_layout()` function.
For example, `frame.color`, `frame.alpha`, and `frame.lwd` change the frame color, transparency (0-1), and line width, respectively (@fig-layout-frame-1).
```{r}
#| label: frame1
#| eval: false
tm +
tm_layout(frame.color = "black",
frame.alpha = 0.6,
frame.lwd = 8)
```
Other arguments that can be used to customize the frame are `frame.r` and `frame.double_line` (@fig-layout-frame-2).
The first one makes the corners of the frame rounded -- the value of `0` means no rounding, while `30` means that the corners are rounded with a radius of 30.^[The `tm_layout()` also has an `r` argument, which is used to round the corners of the all the map elements, including the map frame, but also legend's frame, etc.]
<!-- -- units? ranges of values? -->
<!-- from 0 to 180? try 180 as a footnote? -->
The second one allows to add a second frame line around the frame.
```{r}
#| label: frame2
#| eval: false
tm +
tm_layout(frame.r = 30,
frame.double_line = TRUE)
```
Finally, we can remove the frame completely by setting the `frame` argument to `FALSE` (@fig-layout-frame-3).
```{r}
#| label: frame3
#| eval: false
tm +
tm_layout(frame = FALSE)
```
```{r}
#| label: fig-layout-frame
#| echo: false
#| message: false
#| layout-nrow: 3
#| fig-cap: "Impact of the frame arguments on the map layout."
#| fig-subcap:
#| - "custom color, alpha, and width"
#| - "rounded double line"
#| - "no frame"
<<frame1>>
<<frame2>>
<<frame3>>
```
## Typography {#sec-ltypography}
\index{map layout!typography}
\index{text}
\index{fonts}
<!-- Font faces and font families -->
The decision about the fonts used is often neglected when creating programmable plots and maps.
Most often, the default fonts are used in these kinds of graphs.
This, however, could be a missed opportunity.
A lot of map information is expressed by text, including text labels (@sec-text), legend labels, text in map components (@sec-map-components), or the map title (@sec-titles).
The used fonts impact the tone of the map [@guidero_typography_2017], and their customization allows for a map to stand out from maps using default options.
<!-- role of font faces and font families: -->
<!-- - highlight different levels/importance -->
As we mentioned above, many different map elements can be expressed or can use fonts.
In theory, we are able to set different fonts to each of them.
However, this could result in a confusing visual mix that would hinder our map information.
Therefore, the decision on the used fonts should be taken after considering the main map message, expected map audience, other related graph styles, etc.
In the following three sections, we explain font families and font faces, and give some overall tips on font selection, show how to define used fonts, and how to customize fonts on maps.
### Font families and faces {#sec-fonts}
```{r}
#| echo: false
library(tmap)
data("World")
bf = c("plain", "italic", "bold", "bold.italic")
tm_bf = tm_shape(World) +
tm_borders(col_alpha = 0) +
tm_credits("plain",
fontface = "plain", position = c("center", "center"),
size = 3.5
) +
tm_credits("italic",
fontface = "italic", position = c("center", "center"),
size = 3.5
) +
tm_credits("bold",
fontface = "bold", position = c("center", "center"),
size = 3.5
) +
tm_credits("bold.italic",
fontface = "bold.italic", position = c("center", "center"),
size = 3.5
) +
tm_layout(frame = FALSE, outer.margins = FALSE)
```
```{r}
#| echo: false
library(tmap)
data("World")
# ff = c("Times", "Helvetica", "Courier")
ff = c("serif", "sans", "monospace")
tm_ff = tm_shape(World) +
tm_borders(col_alpha = 0) +
tm_credits("serif",
fontfamily = "serif", position = c("center", "center"),
size = 3.5
) +
tm_credits("sans",
fontfamily = "sans", position = c("center", "center"),
size = 3.5
) +
tm_credits("monospace",
fontfamily = "monospace", position = c("center", "center"),
size = 3.5
) +
tm_layout(frame = FALSE)
```
```{r}
#| label: fig-fonts
#| message: false
#| echo: false
#| layout-ncol: 2
#| fig-cap: Basic font families, and font faces implemented in the tmap package.
#| fig-subcap:
#| - font families
#| - font faces
tm_ff
tm_bf
```
In **tmap**, fonts are represented by a font family (@fig-fonts-1) and a font face (@fig-fonts-2).
A font family is a collection of closely related lettering designs.
Examples of font families include *Times*, *Helvetica*, *Courier*, *Palatino*, etc.
On the other hand, font faces, such as *italic* or *bold*, influence the orientation or width of the fonts.
A *font* is, thus, a combination of a selected font family and font face.
There are a few general font families, such as serifs, sans serifs, and monospaced fonts.
Fonts from the serif family have small lines (known as *a serif*) attached to the end of some letters.
Notice, for example, short horizontal lines on the bottom of letters *r*, *i*, and *f* or vertical lines at the ends of the letter *s* in the top row of @fig-fonts-1.
The fonts in this family are often viewed as more formal.
On the other hand, the sans serif family does not have serifs and is considered more informal and modern.
The last font family, monospaced fonts, is often used in computer programming (IDEs, software text editors), but less often on maps.
A distinguishing feature of the monospaced fonts is that each letter or character in this family has the same width.
Therefore, letters, such as *i* and *a* occupy the same space in the monospaced fonts.
Mixing the use of serif and sans serif fonts often works well for maps.
However, a rule of thumb is not to mix more than two font families on one map.
A sans serif font can be used to label cultural objects, while serif fonts to label physical features.
Then, italics, for example, can be used to distinguish water areas.
The role of bold font faces, together with increased font size, is to highlight the hierarchy of labels -- larger, bold fonts indicate more prominent map features.
Additionally, customizing the fonts' colors can be helpful to distinguish different groups of map objects^[Some additional tips on using font families and faces can be found in the Axis Maps guide at <https://www.axismaps.com/guide/labeling>.].
The decision on which fonts to use should also relate to the expected map look and feel.
Each font family has a distinct personality (creates a "semantic effect"), which can affect how the map is perceived (@Typography-2017; <https://doi.org/10.22224/gistbok/2017.3.2>)
Some fonts are more formal, some are less.
Some fonts have a modern look, while others look more traditional.
Another important concern is personal taste or map branding.
We should filter the decision about the used fonts based on our preferences or even our sense of beauty, as it could create more personal and unique maps.
We just need to remember about the readability of the fonts -- they should not be too elaborate, as it can hinder the main map message.
<!-- suggested fonts or references??? -->
### Fonts available in **tmap** {#sec-fonts-tmap}
Before we discuss how to set a font family and its face, it is important to highlight that a different set of fonts could exist for each operating system (and even each computer).
Additionally, which fonts are available and how they are supported depends on the used *graphic device*.
A graphic device is a place where a plot or map is rendered.
Most commonly, it is some kind of screen device, where we can see our plot or map directly after running the R code.
Other graphic devices allow for saving plots or maps as files in various formats (e.g., `.png`, `.jpg`, `.pdf`).
Therefore, it is possible to get different fonts on your map on the screen, and a (slightly) different one when saved to a file.
Visit `?Devices` or read the Graphic Devices chapter of @peng2016exploratory to learn more about graphic devices.
The **tmap** package has two mechanisms to select a font family.
The first one is by specifying one of three general font families: `"serif"`, `"sans"`, or `"monospace"`.
It tries to match the selected general font family with a font family existing on the operating system^[See <https://github.com/r-lib/systemfonts#system-defaults> for more details.].
For example, `"serif"` could be the `"Times"` font family, `"sans"` -- `"Helvetica"` or `"Arial"`, and `"monospace"` -- `"Courier"` (@fig-fonts-1).
The second mechanism allows to select a font family based on its name (e.g., `"Times"` or `"Palatino"`).
Next, a member of the selected font families can be selected with one of the font faces: `"plain"`, `"italic"`, `"bold"`, and `"bold.italic"` (@fig-fonts-2).
<!-- build-in fonts only -->
As mentioned before, available fonts depend on the computer setup (including operating system) and the used graphics device.
Fonts available on the operating system can be checked with the `system_fonts()` function of the **systemfonts** package [@R-systemfonts] (result not shown).
```{r}
#| eval: false
library(systemfonts)
system_fonts()
```
Information on installing and debugging custom fonts can be found in [a blog post](https://yjunechoe.github.io/posts/2021-06-24-setting-up-and-debugging-custom-fonts/) by June Choe and in the **showtext** package [@R-showtext] documentation.
The next step is to either view or save the map.
This also means that we need to carry over our fonts to the output window/file, which largely depends on the selected graphic device.
In general, screen device or graphical raster output formats, such as PNG, JPEG, or TIFF, works well with custom fonts as they rasterize them during saving.
In case of any problems with graphical raster outputs, it is possible to try alternative graphics devices, for example, implemented in the **ragg** package [@R-ragg].^[See @sec-raster-graphic-formats for an example on how to save a map using a different graphics device.]
On the other hand, graphical vector formats, such as PDF or SVG, could have some problems with saving maps containing custom fonts^[You can get the `invalid font type` error when saving the file.].
The PDF device in R, by default, adds metadata about the used fonts, but does not store them.
When the PDF reader shows the document, it tries to locate the font on your computer, and to use other fonts when the expected one does not exist.
An alternative approach is called embedding, which adds a copy of each necessary font to the PDF file itself.
Gladly, the creation of a PDF with proper fonts can be achieved in a few ways.
Firstly, it could be worth trying some alternative graphic devices such as `cairo_pdf` or `svglite::svglite`.
The second option is to use the **showtext** package [@R-showtext], which converts text into color-filled polygonal outlines for graphical vector formats.
Thirdly, the **extrafont** [@R-extrafont] package allows embedding the fonts in the PDF file, which makes PDFs properly displayed on computers that do not have the given font.
For a longer discussion on typography and R, we recommend to read the **systemfonts** package documentation at <https://systemfonts.r-lib.org/articles/fonts_basics.html>.
### Fonts on maps {#sec-fonts-on-maps}
By default, **tmap** uses the `"sans"` font family with the `"plain"` font face (@fig-fonts).
There are, however, three ways to customize the fonts used.
The first one is to change all of the fonts and font faces for the whole map at once (@fig-mfonts-1).
This can be done with the `text.fontfamily` and `text.fontface` arguments of `tm_layout()`.
```{r}
#| label: font1
#| eval: false
tm +
tm_layout(
text.fontface = "italic",
text.fontfamily = "serif"
)
```
The second way is to specify just some text elements independently (@fig-mfonts-2).
Many **tmap** functions, such as `tm_text()` or `tm_credits()`, have their own `fontfamily` and `fontface` arguments that can be adjusted.
Additionally, `tm_layout()` allows to customize fonts for other map elements using prefixed arguments, such as, `title.fontface` or `legend.title.fontfamily`.
```{r}
#| label: font2
#| eval: false
tm +
tm_layout(
title.fontface = "bold.italic",
legend.title.fontfamily = "monospace"
)
```
```{r}
#| label: fig-mfonts
#| echo: false
#| layout-nrow: 2
#| fig-cap: "Examples of one font (font family and font face) used for all of the map elements (title, text labels, legend, and text annotation), and different fonts used for different map elements."
#| fig-subcap:
#| - one font for all elements
#| - different fonts for different elements
<<font1>>
<<font2>>
```
<!-- The third way is to use a different *tmap style* - see section \@ref() for more details. -->
```{r}
#| eval: false
#| echo: false
# saving tests
tmap_save(tmt2, "tmt2.png")
tmap_save(tmt2, "tmt2.pdf")
```
## Scale {#sec-scale}
\index{map layout!scale}
The **tmap** package has a set of default sizes and widths for various map elements, such as the frame, text, borders, symbol sizes, and more.
In the previous parts of this book, we modified some of these values for selected elements, such as the frame width or text size.
At the same time, we can also change the size of all of the map elements at once -- this is a role of the `scale` argument of the `tm_layout()` function.
It accepts a numeric value, where `1` means the default sizes and widths, `0.5` means that all of the map elements are half as large as the default ones, and `1.5` means that all of the map elements are 1.5 times larger than the default ones.
<!-- Martijn, is the above statement correct? -->
```{r}
#| label: fig-layout-scale
#| warning: false
#| echo: false
#| layout-nrow: 2
#| fig-cap: "Impact of the scale argument on the map layout."
#| fig-subcap:
#| - "`scale = 0.5`"
#| - "`scale = 1.5`"
tm +
tm_layout(scale = 0.5)
tm +
tm_layout(scale = 1.5)
```
Scaling the map elements can be useful when we want to create a more compact map or when we want to make the map more readable by increasing the size of the map elements.
The `scale` argument also exists in the `tmap_save()` function, which allows us to change the size of the map elements when saving the map to a file (@sec-save).
## Design mode {#sec-design-mode}
\index{design mode}
Maps consist of various components, including the map content (with its frame), additional map components (e.g., credits or a title), and the legend, which are often located in different places.
They also have numerous margins -- spaces between data and the frame, spaces between the frame and the plotting, spaces between the icons and the labels, etc.
Many of these properties can be customized, however, it may be challenging to understand the effect of the changes.
To make it easier, **tmap** has a design mode that can be turned on by setting the `tmap_design_mode()` function to `TRUE`.
When the design mode is on, the map is displayed in a special way: it shows all of the created map content, but also adds various lines and colored areas to the map.
Additionally, it returns a small table in the R console with sizes and an aspect ratio of the device, plot, facets, and map areas.
```{r}
#| label: fig-design-mode
#| fig-cap: "A map of Slovenia in the design mode."
tmap_design_mode(TRUE)
tm
```
We may see an example of a map in the design mode in @fig-design-mode.
Its colors relate to the map and the margins around the map content.
For example, the map area is colored yellow, the outside cells (used, for instance, for legends and titles) are in light green, and the outer margins are in light blue.
A complete list of the color codings is shown in @tbl-color-codings.
```{r}
#| label: tbl-color-codings
#| tbl-cap: "Color codings of the design mode."
#| echo: false
color_codings_df = tibble::tribble(
~Name, ~Color, ~Element,
"Light blue", "", "Outer margins",
"Dark blue", "", "Buffers around outside cells",
"Light green", "", "Outside cells",
"Dark green", "", "X and Y labels",
"Pink", "", "Panels",
"Red", "", "Margins for outside grid labels",
"Orange", "", "Margins around maps for grid labels",
"Yellow", "", "Map area"
)
tinytable::tt(color_codings_df[, 2:3]) |>
tinytable::style_tt(i = 1, j = 1, background = "#A6CEE3") |>
tinytable::style_tt(i = 2, j = 1, background = "#1F78B4") |>
tinytable::style_tt(i = 3, j = 1, background = "#B2DF8A") |>
tinytable::style_tt(i = 4, j = 1, background = "#33A02C") |>
tinytable::style_tt(i = 5, j = 1, background = "#FB9A99") |>
tinytable::style_tt(i = 6, j = 1, background = "#E31A1C") |>
tinytable::style_tt(i = 7, j = 1, background = "#FDBF6F") |>
tinytable::style_tt(i = 8, j = 1, background = "#FFFF99")
```
<!-- cols4all::c4a("brewer.paired") -->
The design mode is useful to understand how the map is constructed and how the various arguments of the `tm_layout()` function impact the map layout.
This mode is in place until the `tmap_design_mode()` function is set to `FALSE`.
In the next few sections, we show how the design mode can help us to understand the impact of various arguments of the `tm_layout()` function on the aspect ratio and margins of the map.
## Aspect ratio {#sec-aspect}
\index{map layout!aspect ratio}
The aspect ratio specifies the relation between the width and height of the map area of the plot.
In statistical plots, the aspect ratio typically adapts to the available plotting space.
For example, a histogram expands to fill the entire area, whether the plotting space is wider than it is tall, or taller than it is wide.
Thus, customization of an aspect ratio in statistical plots is usually not needed.
For maps, this is not the case -- we should not change the relation between the width and height of the data in a map as it has a specific projection that determines the spatial relation between the map features.
By default, the aspect ratio of the *tmap* is set to `NA`, which means that it is adjusted to the used shapes (@fig-layout-example).
<!--Martijn, please check the following statements. Also, I still do not fully understand the difference between 0 and NA-->
@fig-layout-asp shows how the aspect ratio can be customized with the `asp` argument of the `tm_layout()` function.
When set to `0`, the aspect ratio is adjusted to the size of the device divided by the number of columns and rows.
The value of `0.5` means that the map area is half as wide as it is tall, while `2` means that the map area is twice as wide as it is tall.
The value of `1` means that the map area is square, i.e., the width and height are equal.
```{r}
#| label: fig-layout-asp
#| warning: false
#| echo: false
#| layout-ncol: 2
#| layout-nrow: 2
#| fig-cap: "Impact of the aspect ratio on the map layout."
#| fig-subcap:
#| - "`asp = 0`"
#| - "`asp = 0.5`"
#| - "`asp = 1`"
#| - "`asp = 2`"
tm +
tm_layout(asp = 0)
tm +
tm_layout(asp = 0.5)
tm +
tm_layout(asp = 1)
tm +
tm_layout(asp = 2)
```
## Margins {#sec-lmargins}
\index{map layout!margins}
\index{margins}
Margins are spaces around the map content, which can be used to separate the map from other elements, such as the legend or the title or separate the map from the extent of the plotting area.
They may serve various purposes, such as to make the map more readable, to avoid overlapping the map content with other elements, and to create space for additional elements.
On the other hand, making margins smaller can help to increase the map area or make the map more condensed.
There are several arguments in `tm_layout()` related to margins.
All of the margin arguments can be customized either with a single value (which is then applied to all sides) or with a vector of four values, which represent the bottom, left, top, and right margins.
<!-- units? -->
<!-- The unit is the device height (for bottom and top) or width (for left and right). -->
The most important margin arguments are `inner.margins` and `outer.margins`.
<!-- scheme figure showing the order of values? -->
The inner margins are spaces between the map content (e.g., symbols, lines, polygons, raster) and the frame of the map (@fig-inner-margins).
By default, the inner margins are set to `c(0.02, 0.02, 0.02, 0.02)`, which means that there is a 2% margin on each side of the map content (@fig-layout-example).
An exception to this rule is raster maps, where the inner margins are set to `c(0, 0, 0, 0)` -- meaning that there are no margins around the raster map content -- by default.
Increasing the inner margins can help to avoid overlapping of the map content with other elements, such as the legend or the title -- for example, we could add some margin on the right side of the map and then place the legend there.
<!-- inner.margins.extra -- ???? -->
```{r}
#| label: fig-inner-margins
#| warning: false
#| echo: false
#| layout-ncol: 2
#| fig-cap: "Impact of the `inner.margins` argument on the map layout."
#| fig-subcap:
#| - "no margins"
#| - "`c(0.8, 0.4, 0.2, 0)`"
tm +
tm_layout(inner.margins = 0)
tm +
tm_layout(inner.margins = c(0.8, 0.4, 0.2, 0))
```
Outer margins are spaces between the map frame and the plotting area (@fig-outer-margins).
By default, they are always set to `c(0.02, 0.02, 0.02, 0.02)`, which means that there is a 2% margin outside of the map frame -- giving a small "breathing space" around the map (@fig-layout-example).
We can increase it on a specific side, for example, to create more space for the legend or other map elements or we can remove it completely to, for example, arrange the map in a grid with other maps (@sec-arranging-maps) (@fig-outer-margins).
```{r}
#| label: fig-outer-margins
#| warning: false
#| echo: false
#| layout-ncol: 2
#| fig-cap: "Impact of the `outer.margins` argument on the map layout."
#| fig-subcap:
#| - "no margins"
#| - "`c(0.08, 0.04, 0.02, 0)`"
tm +
tm_layout(outer.margins = 0)
tm +
tm_layout(outer.margins = c(0.08, 0.04, 0.02, 0))
```
<!-- interplay between margins and plotting device dimensions/asp -->
<!-- meta.margins -- ???? -->
<!-- they are mentioned in the arrangements chapter -- maybe mention + ref -->
<!-- meta.auto_margins -- ???? -->
<!-- Besides inner and outer margins, there is another type of margins: the meta margins. This space dedicated for map components that are outside the map (see [vignette about component positions](https://r-tmap.github.io/tmap/articles/adv_positions#cell-h-and-cell-v). For single maps this is calculated automatically, using the other margins and the map component sizes. If there are no outside map components, `meta.margins` is set to `c(0, 0, 0, 0)`. For complex maps (e.g. facetted maps) it is set to 0.4 for each side in which map components are placed. -->
<!-- between_margin, -->
<!-- panel.margin, -->
Now, as we have seen how the design mode can help us to understand the impact of various arguments of the `tm_layout()` function, we can turn it off.
```{r}
tmap_design_mode(FALSE)
```