-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path06-map.Rmd
2345 lines (1783 loc) · 106 KB
/
06-map.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
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Map {#map}
---
```{r pressure, echo=FALSE, fig.align='center', fig.cap="Connection Map", out.width = '75%'}
knitr::include_graphics("https://www.r-graph-gallery.com/how-to-draw-connecting-routes-on-map-with-r-and-great-circles_files/figure-html/thecode6-1.png")
```
## Basic Map
This section is a very basic introduction to the leaflet R package. It shows how to display a background map using default parameters, with reproducible code provided.
### Background map in R
This is the [background map](https://www.data-to-viz.com/graph/map.html) section of the gallery. It explains how to build static and interactive maps based on different input data, but does not explain how to plot data on it. See other sections for that: [Choropleth](https://www.r-graph-gallery.com/choropleth.html), [bubble map](https://www.r-graph-gallery.com/bubble-map.html), [connection map](https://www.r-graph-gallery.com/connection-map.html) or [cartogram](https://www.r-graph-gallery.com/cartogram.html).
#### Input Format and Package Overview
R is an great tool for geospatial data analysis. Heaps of dedicated packages exist. Building a map follows those 2 steps:
<u>Find data, load it in R</u>: region boundaries can be stored in [shapefiles](https://www.r-graph-gallery.com/168-load-a-shape-file-into-r.html) or [geoJSON files](https://www.r-graph-gallery.com/325-background-map-from-geojson-format-in-r.html). Some [R libraries](https://www.r-graph-gallery.com/278-the-maps-library.html) also provide the data for the most common places. It is also possible to use google map style backgrounds.
<u>Manipulate and plot it</u>: once geo data are loaded in R you get a geospatial object that has specific features. You can manipulate it and plot it with packages like sp or ggplot2
<center>
![](https://www.r-graph-gallery.com/img/other/backgroundMapExplanation.png){width=100%}
</center>
### Most Basic Background Map with R and Leaflet
This post is a very basic introduction to the `leaflet` R package. It shows how to display a [background map](https://www.r-graph-gallery.com/map.html) using default parameters, with reproducible code provided.
First initiate the map with the `leaflet()` function. Then add tiles with `addTiles()`. Note the use of the `%>%` operator to "pipe" functions. Here you can see how to get the same result using or not this operator.
By default, you get the map beside. See next charts to learn how to [zoom on a zone](https://www.r-graph-gallery.com/179-2-select-a-zone-in-leaflet-map.html), change [background style](https://www.r-graph-gallery.com/180-change-background-in-leaflet-map.html).
```r
# Load the library
library(leaflet)
# Note: if you do not already installed it, install it with:
# install.packages("leaflet")
# Initialize the leaflet map with the leaflet() function
m <- leaflet()
# Then we Add default OpenStreetMap map tiles
m <- addTiles(m)
m
# Same stuff but using the %>% operator
m <- leaflet() %>%
addTiles()
m
# save the widget in a html file if needed.
# library(htmlwidgets)
# saveWidget(m, file=paste0( getwd(), "/HtmlWidget/backgroundMapBasic.html"))
```
<center>
```{r background-map-basic-html, echo=FALSE}
htmltools::tags$iframe(title = "My embedded document", src = "mapHtml/backgroundMapBasic.html", height="400px", width = "100%")
```
</center>
### Change Background Tile with `leaflet` and R
This section shows how to change the background tile used by the leaflet R package. It provides an overview of the most common options with their associated code.
#### Loading a tile
This post follows the previous posts on `leaflet`: most [basic map](https://www.r-graph-gallery.com/179-show-a-map-with-leaflet-r.html), and zooming on a [specific area](https://www.r-graph-gallery.com/179-2-select-a-zone-in-leaflet-map.html).
`Leaflet` offers several tiles to customize the background used on a map.
A tile can be loaded thanks to the `addProviderTiles()` function.
```r
# Load the library
library(leaflet)
# Note: if you do not already installed it, install it with:
# install.packages("leaflet")
# Background 1: NASA
x <- leaflet() %>%
addTiles() %>%
setView( lng = 2.34, lat = 48.85, zoom = 5 ) %>%
addProviderTiles("NASAGIBS.ViirsEarthAtNight2012")
x
# save the widget in a html file if needed.
#library(htmlwidgets)
#saveWidget(x, file=paste0( getwd(), "/NASAGIBS.html"))
```
<center>
```{r nasa-tile-map-html, echo=FALSE, fig.align='center'}
htmltools::tags$iframe(title = "My embedded document", src = "mapHtml/NASAGIBS.html" , height="400px", width = "100%")
```
</center>
#### List of Tiles
Many tiles are made available. A complete list can be found [here](http://leaflet-extras.github.io/leaflet-providers/preview/index.html). Most famous are probably:
Nasa: `NASAGIBS.ViirsEarthAtNight2012`
Google map: `Esri.WorldImagery`
Gray: `Esri.WorldGrayCanvas`
Terrain: `Esri.WorldTerrain`
Topo Map: `Esri.WorldTopoMap`
```r
# Background 2: World Imagery
m <- leaflet() %>%
addTiles() %>%
setView( lng = 2.34, lat = 48.85, zoom = 3 ) %>%
addProviderTiles("Esri.WorldImagery")
m
# save the widget in a html file if needed.
#library(htmlwidgets)
#saveWidget(m, file=paste0( getwd(), "/Esri.html"))
```
<center>
```{r esri-tile-map-html, echo=FALSE, fig.align='center'}
htmltools::tags$iframe(title = "My embedded document", src = "mapHtml/esri.html" , height="400px", width = "100%")
```
</center>
### The `ggmap` Package for Static Maps with Background Titles
The [ggmap](https://github.com/dkahle/ggmap) library makes it easy to retrieve raster map tiles from popular online mapping services like [Google Maps](https://developers.google.com/maps/documentation/static-maps/?hl=en), [OpenStreetMap](https://www.openstreetmap.org/) or [Stamen Maps](http://maps.stamen.com/), and plot them using the [ggplot2](https://www.r-graph-gallery.com/ggplot2-package.html) framework. It produces static maps like these. Click on an image to get the related code snippet.
The `ggmap` package produces static maps. This section describes its basic utilisation, just building background maps. Other section are available for adding data on it, like [bubble maps](https://www.r-graph-gallery.com/bubble-map.html) or [chloropleth maps](https://www.r-graph-gallery.com/chloropleth-map.html). The section is split in 2 parts: tiles coming from google and others coming from Stamen.
#### Building a Google Background
The `get_googlemap()` function allows to get google map tiles. Unfortunately, google now requires to sign up for an API keys for this code to work.
```r
# Library
library(ggmap)
# For google map, you have to give the center of the window you are looking at.
# Possibility for the map type argument: terrain / satellite / roadmap / hybrid
# get the map info
map <- get_googlemap("Montpellier, France", zoom = 8, maptype = "terrain")
# Plot it
ggmap(map) +
theme_void() +
ggtitle("terrain") +
theme(
plot.title = element_text(colour = "orange"),
panel.border = element_rect(colour = "grey", fill=NA, size=2)
)
```
![](https://www.r-graph-gallery.com/img/graph/324-map-background-with-the-ggmap-library1.png){width=50%}![](https://www.r-graph-gallery.com/img/graph/324-map-background-with-the-ggmap-library2.png){width=50%}
![](https://www.r-graph-gallery.com/img/graph/324-map-background-with-the-ggmap-library3.png){width=50%}![](https://www.r-graph-gallery.com/img/graph/324-map-background-with-the-ggmap-library4.png){width=50%}
### Calling Stamen Background
Using the same kind of code you can call stamen background. Just switch to the `get_stamenmap()` function.
The most famous background is probably the `watercolor` one.
```r
# Library
library(ggmap)
library(gridExtra)
# For stamen map, you have to give the extremity of the window you are looking at. here is an example with the watercolor background (Around brisbane)
map <- get_stamenmap( bbox = c(left = 110, bottom = -40, right = 160, top = -10), zoom = 4, maptype = "watercolor")
ggmap(map) +
theme_void() +
theme(
plot.title = element_text(colour = "orange"),
panel.border = element_rect(colour = "grey", fill=NA, size=2)
)
```
<center>
![](https://www.r-graph-gallery.com/324-map-background-with-the-ggmap-library_files/figure-html/thecode-1.png){width=75%}
</center>
Let's have a look to all the possibilities offered by this Stamen option:
```r
# Library
library(ggmap)
library(gridExtra)
# Let's check all the possibilities offered by stamen
maptype <- c("terrain-labels", "terrain-lines", "toner", "toner-2011",
"toner-background", "toner-hybrid", "toner-lines",
"toner-lite", "watercolor")
mylist <- vector("list", length(maptype))
# Loop through them:
num <- 0
for(i in maptype ){
num <- num+1
map <- get_stamenmap( bbox = c(left = 150, bottom = -30, right = 160, top = -25), zoom = 8, maptype = i)
p <- ggmap(map) +
theme_void() +
ggtitle(i) +
theme(
plot.title = element_text(colour = "orange"),
panel.border = element_rect(colour = "grey", fill=NA, size=2)
)
mylist[[num]] <- p
}
# Arrange all this map in the same image with gridExtra:
n <- length(mylist)
nCol <- floor(sqrt(n))
do.call("grid.arrange", c(mylist, ncol=nCol))
```
![](https://www.r-graph-gallery.com/324-map-background-with-the-ggmap-library_files/figure-html/unnamed-chunk-2-1.png)
### The `Maps`, `Mapdata` and `Oz` Packages to get Most Common Boundaries
A few libraries provide the most common spatial objects. It avoids the struggle to find the information somewhere on the web. Maps library: Canada, France, Italy, USA and its regions, world cities, NZ. Mapdata library (China, Japan, NZ, World in High resolution) and the oz library (Australia).
The [maps](https://www.r-graph-gallery.com/278-the-maps-library.html#maps), [mapdata](https://www.r-graph-gallery.com/278-the-maps-library.html#mapdata) and [oz](https://www.r-graph-gallery.com/278-the-maps-library.html#oz) packages provide the boundaries of the most common world regions like the US, Europe, New Zealand and more. This section describes how to use them to avoid struggling finding input data.
#### `maps` Package
The [maps](https://cran.r-project.org/web/packages/maps/maps.pdf) package is the best source of geospatial data in R. The whole list of offered data is available typing: `help(package='maps')`.
It includes:
* World: `world`, `world.cities`, `lakes`
* US: `states`, `county`, `state`, `usa`
* France: `france`
* Italy: `italy`
* New Zealand: `nz`
The code below shows how to use one of this geospatial object.
```r
# Load library
library(maps)
# Check all available geospatial objects:
# help(package='maps')
# Map of the world:
map('world',col="grey", fill=TRUE, bg="white", lwd=0.05, mar=rep(0,4),border=0, ylim=c(-80,80) )
```
![](https://www.r-graph-gallery.com/278-the-maps-library_files/figure-html/thecode-1.png)
### `mapdata` Package
The [mapdata](https://cran.r-project.org/web/packages/mapdata/mapdata.pdf) package extends the `maps` package with more geospatial datasets:
* `china`
* `japan`
* Other world versions like pacific Centric (`world2Hires`)
See complete list with `help(package='mapdata')`
```r
# Load library
library(mapdata)
# Check all available geospatial objects:
# help(package='mapdata')
# Map of Japan:
map('japan',col="black", lwd=1, mar=rep(0,4) )
```
![](https://www.r-graph-gallery.com/278-the-maps-library_files/figure-html/thecode2-1.png)
### `oz` Package
The [oz](https://github.com/cran/oz) package provides several geospatial object concerning Australia. Plot the general country using the `oz()` function, or states using `nsw()`, `qld()` and so on.
Type `help(package='oz')` for documentation.
```r
# Load library
library(oz)
# Check all available geospatial objects:
# help(package='oz')
# Map of Australia
par(mar=rep(0,4))
oz( states=TRUE, col="#69b3a2")
```
![](https://www.r-graph-gallery.com/278-the-maps-library_files/figure-html/thecode3-1.png)
### `Rgdal` and `Geojsonio` to Read Shapefiles and .geojson Files
If you are not satisfied with the previous options, you can search the web to find the spatial object you need. This information will most likely be stored under on of those 2 formats:
* [shape file](https://www.r-graph-gallery.com/168-load-a-shape-file-into-r.html): can be read with the `rgdal` package as described here.
* [geojson](https://www.r-graph-gallery.com/325-background-map-from-geojson-format-in-r.html) file: can be read with `geojsonio` as explained [here](https://www.r-graph-gallery.com/325-background-map-from-geojson-format-in-r.html).
#### Open and Plot Shapefiles in R
Shapefiles are a common way to store geospatial data. This section explains how to read it with `R` and the `rgdal` package, and how to plot it in base `R` or with `ggplot2`.
If you did not find the geospatial data you need in existing R packages (see the [map section](https://www.r-graph-gallery.com/maps.html)), you need to find this information elsewhere on the web.
Usually, you will find it as a shape file format. This format is composed by several files that you need to keep together in the same folder.
<u>Note</U>: if you found a `.geoJSON` file, read [this section](https://www.r-graph-gallery.com/325-background-map-from-geojson-format-in-r.html) instead.
### Find and Download a Shapefile
You need to dig the internet to find the shape file you are interested in. For instance, this [URL](http://thematicmapping.org/downloads/world_borders.php) will redirect you to a zipped shape file containing the world boundaries.
You can download it and unzip it with R:
```r
# Download the shapefile. (note that I store it in a folder called DATA. You have to change that if needed.)
download.file("http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip" , destfile="DATA/world_shape_file.zip")
# You now have it in your current working directory, have a look!
# Unzip this file. You can do it with R (as below), or clicking on the object you downloaded.
system("unzip DATA/world_shape_file.zip")
# -- > You now have 4 files. One of these files is a .shp file! (TM_WORLD_BORDERS_SIMPL-0.3.shp)
```
### Read it with `rgdal`
The `rgdal` package offers the `readOGR()` function that allows to read shapefile using the following syntax.
As a result you get a geospatial object (`my_spdf` here) that contains all the information we need for further mapping. Please try th following command to understand how this object works:
* `summary(my_spdf)`: tells you the max and min coordinates, the kind of projection in use.
* `length(my_spdf)`: how many regions you have.
* `head(my_spdf@data)`: the firs few rows of the data slot associated with the regions.
```r
# Read this shape file with the rgdal library.
library(rgdal)
my_spdf <- readOGR(dsn=path.expand("C:/Users/Downloads/Files/World-Shapefiles"), layer="TM_WORLD_BORDERS_SIMPL-0.3")
```
### Plot it with `base R`
The basic `plot()` function knows how to plot a geospatial object. Thus you just need to pass it `my_spdf` and add a couple of options to customize the output.
```r
# Basic plot of this shape file:
par(mar=c(0,0,0,0))
plot(my_spdf, col="#f2f2f2", bg="skyblue", lwd=0.25, border=0 )
```
![](https://www.r-graph-gallery.com/168-load-a-shape-file-into-r_files/figure-html/thecode4-1.png)
### Plot it with `ggplot2`
It is totally possible (and advised imo) to build the map with [ggplot2](https://www.r-graph-gallery.com/ggplot2-package.html). However, ggplot2 takes as input data frames, not geospatial data.
`my_spdf` thus needs to be transformed using the `tidy()` function of the `broom` package. The `region` argument of this function expect one of the column name if the @data slot. It will be the region name in the new dataframe.
Once the data frame is created, it is plotted using the `geom_polygon()` function as described below.
```r
# 'fortify' the data to get a dataframe format required by ggplot2
library(broom)
spdf_fortified <- tidy(my_spdf, region = "NAME")
# Plot it
library(ggplot2)
ggplot() +
geom_polygon(data = spdf_fortified, aes( x = long, y = lat, group = group), fill="#69b3a2", color="white") +
theme_void()
```
![](https://www.r-graph-gallery.com/168-load-a-shape-file-into-r_files/figure-html/thecode5-1.png)
### Open and Plot Geojson files in R
Geojson files are a common way to store geospatial data. This section explains how to read it with `R` and the `geojsonio` package, and how to plot it in base R or with `ggplot2`.
If you did not find the geospatial data you need in existing R packages (see the [map section](https://www.r-graph-gallery.com/maps.html)), you need to find this information elsewhere on the web.
It will often be stored as a `.geomJSON` format. This section explains how to read it.
<u>Note</u>: if you found a `shapefile`, read [this section](https://www.r-graph-gallery.com/168-load-a-shape-file-into-r.html) instead.
### Find and download a `.geoJSON` file
You need to dig the internet to find the geoJSON file you are interested in. For instance, this [URL](https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/communes.geojson) provides a file containing french region boundaries.
You can load it in R with:
```r
# Let's read the jeoJson file that is stored on the web with the geojsonio library:
library(geojsonio)
spdf <- geojson_read("https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/communes.geojson", what = "sp")
```
That's it! You now have a geospatial object called `spdf`. I strongly advise to read [this section](https://www.r-graph-gallery.com/169-170-basic-manipulation-of-shapefiles) to learn how to manipulate it.
Just in case, here is how to plot it in base R and with `ggplot2`.
### Plot it with `base R`
The basic `plot()` function knows how to plot a geospatial object. Thus you just need to pass it `spdf` and add a couple of options to customize the output.
```r
# Select only the region #6
spdf@data$mystate = substr( spdf@data$code, 1, 2)
spdf_region_6 = spdf[ spdf@data$mystate == "06" , ]
# plot the selected are with sp
library(sp)
par(mar=c(0,0,0,0))
plot(spdf_region_6, col="grey")
```
![](https://www.r-graph-gallery.com/325-background-map-from-geojson-format-in-r_files/figure-html/thecode4-1.png)
### Plot it with `ggplot2`
It is totally possible (and advised imo) to build the map with [ggplot2](https://www.r-graph-gallery.com/ggplot2-package.html). However, ggplot2 takes as input data frames, not geospatial data.
The geospatial object thus needs to be transformed using the `tidy()` function of the `broom` package.
Once the data frame is created, it is plotted using the `geom_polygon()` function as described below.
```r
# 'fortify' the data to get a dataframe format required by ggplot2
library(broom)
spdf_fortified <- tidy(spdf_region_6)
# Plot it
library(ggplot2)
ggplot() +
geom_polygon(data = spdf_fortified, aes( x = long, y = lat, group = group), fill="#69b3a2", color="white") +
theme_void() +
coord_map()
```
![](https://www.r-graph-gallery.com/325-background-map-from-geojson-format-in-r_files/figure-html/thecode5-1.png)
### Geospatial Data Manipulation
Once you've got your geospatial data loaded into R, you are ready to manipulate it. Examples below show how to select a region, how to simplfy the boundaries to get a lighter object, how to compute the region centroids and more.
#### Select a Region
You can filter the geospatial object to plot only a subset of the regions. The following code keeps only Africa and plot it.
```r
# Keep only data concerning Africa
africa <- my_spdf[my_spdf@data$REGION==2 , ]
# Plot africa
par(mar=c(0,0,0,0))
plot(africa , xlim=c(-20,60) , ylim=c(-40,35), col="steelblue", lwd=0.5 )
```
![](https://www.r-graph-gallery.com/169-170-basic-manipulation-of-shapefiles_files/figure-html/thecode4-1.png)
### Simplify Geospatial Object
It's a common task to *simplify* the geospatial object. Basically, it decreases the border precision which results in a lighter object that will be plotted faster.
The `rgeos` package offers the `gSimplify()` function to makes the simplification. Play with the `tol` argument to control simplification rate.
```r
# Simplification with rgeos
library(rgeos)
africaSimple <- gSimplify(africa, tol = 4, topologyPreserve = TRUE)
# Plot it
par(mar=c(0,0,0,0))
plot(africaSimple , xlim=c(-20,60) , ylim=c(-40,35), col="#59b2a3", lwd=0.5 )
```
![](https://www.r-graph-gallery.com/169-170-basic-manipulation-of-shapefiles_files/figure-html/thecode6-1.png)
### Compute Region Centroid
Another common task is to compute the centroid of each region to add labels. This is accomplished using the `gCentroid()` function of the `rgeos` package.
```r
# Load the rgeos library
library(rgeos)
# The gCentroid function computes the centroid of each region:
# gCentroid(africa, byid=TRUE)
# select big countries only
africaBig <- africa[which(africa@data$AREA>75000), ]
# Small manipulation to put it in a dataframe:
centers <- cbind.data.frame(data.frame(gCentroid(africaBig, byid=TRUE), id=africaBig@data$FIPS))
# Show it on the map?
par(mar=c(0,0,0,0))
plot(africa , xlim=c(-20,60) , ylim=c(-40,35), lwd=0.5 )
text(centers$x, centers$y, centers$id, cex=.9, col="#69b3a2")
```
![](https://www.r-graph-gallery.com/169-170-basic-manipulation-of-shapefiles_files/figure-html/thecode7-1.png)
## Cartogram
---
A [cartogram](https://www.data-to-viz.com/graph/cartogram.html) is a map in which the geometry of regions is distorted in order to convey the information of an alternate variable. The region area will be inflated or deflated according to its numeric value. In R, the `cartogram` package is the best way to build it, as illustrated in the examples below.
#### The Cartogram Package: Step by Step
The cartogram package allows to build cartograms in R. It requires a `geospatial object` as input, with a numeric variable in the data slot. This variable will be used to distort region shape. The following example will guide you through the process:
### Basic Cartogram with R
This section describes how to build a very simple [cartogram](https://www.r-graph-gallery.com/cartogram.html) with `R` and the `cartogram` package. It is a step a step approach leading to a choropleth map with distorted region size.
#### Very Basic Map
A [cartogram](https://www.r-graph-gallery.com/cartogram.html) is a map in which the geometry of regions is distorted in order to convey the information of an alternate variable. In this section, we are going to draw a map of Africa where the size of each country is distorted proportionally to its population.
First of all, you need to understand what a geospatial object is, and how to plot it with `R`. See the [background map section](https://www.r-graph-gallery.com/map.html) of the gallery!
Let's use the `maptools` library which provides a geospatial object with the Africa's boundaries. Note that you can get a similar object from a shapefile, or from a geojson file!
We can plot the boundaries using the `plot()` function:
```{r cartobin-maps-map-html, echo=TRUE, message=FALSE, warning=FALSE}
# Get the shape file of Africa
library(maptools)
data(wrld_simpl)
afr=wrld_simpl[wrld_simpl$REGION==2,]
# We can visualize the region's boundaries with the plot function
plot(afr)
```
### Distort Country Size with `cartogram`
The geospatial object has a `data slot`: an attached data frame that provides several information for each region. It notably gives the population of each country in 2005.
We can thus use the `cartogram` library to distort the size of each country, proportionally to this column. The new geospatial object we get can be draw with the same `plot` function!
See how Nigeria is now bigger?
```r
# We work with the cartogram library
library(cartogram)
# construct a cartogram using the population in 2005
afr_cartogram <- cartogram(afr, "POP2005", itermax=5)
# This is a new geospatial object, we can visualise it!
plot(afr_cartogram)
```
<center>
![](https://www.r-graph-gallery.com/331-basic-cartogram_files/figure-html/thecode2-1.png)
</center>
### Cartogram and Choropleth
Cartogram are very often used in combination with [choropleth map](https://www.r-graph-gallery.com/chloropleth-map.html). Since we have a spatial object and a numeric value associated with each region, it is possible to color each region according to its value.
Let's use [ggplot2](https://www.r-graph-gallery.com/ggplot2-package.html) to add some color, title, legend, background and so on. We now have a nice cartogram chloropleth map of Africa!
```r
# It is a new geospatial object: we can use all the usual techniques on it! Let's start with a basic ggplot2 chloropleth map:
library(tidyverse)
library(broom)
spdf_fortified <- tidy(afr_cartogram)
spdf_fortified = spdf_fortified %>% left_join(. , afr_cartogram@data, by=c("id"="ISO3"))
ggplot() +
geom_polygon(data = spdf_fortified, aes(fill = POP2005, x = long, y = lat, group = group) , size=0, alpha=0.9) +
coord_map() +
theme_void()
```
<center>
![](https://www.r-graph-gallery.com/331-basic-cartogram_files/figure-html/thecode3-1.png)
</center>
### Make it Pretty
Same thing with a tiny bit of customization. See more explanation in the [choropleth](https://www.r-graph-gallery.com/choropleth.html) an [ggplot2](https://www.r-graph-gallery.com/ggplot2-package.html) sections.
```r
# As seen before, we can do better with a bit of customization
library(viridis)
ggplot() +
geom_polygon(data = spdf_fortified, aes(fill = POP2005/1000000, x = long, y = lat, group = group) , size=0, alpha=0.9) +
theme_void() +
scale_fill_viridis(name="Population (M)", breaks=c(1,50,100, 140), guide = guide_legend( keyheight = unit(3, units = "mm"), keywidth=unit(12, units = "mm"), label.position = "bottom", title.position = 'top', nrow=1)) +
labs( title = "Africa 2005 Population" ) +
ylim(-35,35) +
theme(
text = element_text(color = "#22211d"),
plot.background = element_rect(fill = "#f5f5f4", color = NA),
panel.background = element_rect(fill = "#f5f5f4", color = NA),
legend.background = element_rect(fill = "#f5f5f4", color = NA),
plot.title = element_text(size= 22, hjust=0.5, color = "#4e4d47", margin = #margin(b = -0.1, t = 0.4, l = 2, unit = "cm")),
legend.position = c(0.2, 0.26)
) +
coord_map()
```
![](https://www.r-graph-gallery.com/331-basic-cartogram_files/figure-html/thecode4-1.png)
<
### Application on Hexbin Map
A [hexbin map](https://www.r-graph-gallery.com/hexbin-map.html) is a map where each region is represented as an hexagon. It is possible to apply a cartogram algorithm to such a map, as suggested in the example below. Note that you probably want to explore the [hexbin map](https://www.r-graph-gallery.com/hexbin-map.html) section before making a cartogram with it.
### Basic Cartogram with R
This section describes how to apply the [cartogram](https://www.r-graph-gallery.com/cartogram.html) method to a [hexbin map](https://www.r-graph-gallery.com/hexbin-map). Each region is represented as a hexagon which size is distorted according to a numeric variable. It uses the `cartogram` package.
#### Basic Hexbin Map
The first step is to build a basic [hexbin map](https://www.r-graph-gallery.com/hexbin-map.html) of the US. Note that the gallery dedicates a [whole section](https://www.r-graph-gallery.com/hexbin-map.html) to this kind of map.
Hexagones boundaries are provided [here](https://team.carto.com/u/andrew/tables/andrew.us_states_hexgrid/public/map). You have to download it at the `geojson` format and load it in R thanks to the `geojson_read()` function. You get a geospatial object that you can plot using the `plot()` function. This is widely explained in the [background map](https://www.r-graph-gallery.com/map.html) section of the gallery.
```{r basic-hexbin-map-html, echo=TRUE, message=FALSE, warning=FALSE}
# library
library(tidyverse)
library(geojsonio)
library(RColorBrewer)
library(rgdal)
# Download the Hexagones boundaries at geojson format here: https://team.carto.com/u/andrew/tables/andrew.us_states_hexgrid/public/map.
# Load this file. (Note: I stored in a folder called DATA)
spdf <- geojson_read("C:/Users/kwilliam/Downloads/us_states_hexgrid.geojson", what = "sp")
# Bit of reformating
spdf@data = spdf@data %>%
mutate(google_name = gsub(" \\(United States\\)", "", google_name))
# Show it
plot(spdf)
```
### Distort Hexagone Size with `cartogram`
The geospatial object has a **data slot**: an attached data frame that provides several information for each region. It is called `spdf@data` here.
We need to add a new column to this data frame. This column will provide the population per state, available at `.csv `format [here](https://raw.githubusercontent.com/holtzy/R-graph-gallery/master/DATA/pop_US.csv).
We can thus use the `cartogram` library to distort the size of each state (=hexagon), proportionally to this column. The new geospatial object we get can be drawn with the same `plot` function.
```r
# Library
library(cartogram)
# Load the population per states (source: https://www.census.gov/data/tables/2017/demo/popest/nation-total.html)
pop <- read.table("https://raw.githubusercontent.com/holtzy/R-graph-gallery/master/DATA/pop_US.csv", sep=",", header=T)
pop$pop <- pop$pop / 1000000
# merge both
spdf@data <- spdf@data %>% left_join(., pop, by=c("google_name"="state"))
# Compute the cartogram, using this population information
cartogram <- cartogram(spdf, 'pop')
# First look!
plot(cartogram)
```
![](https://www.r-graph-gallery.com/332-hexbin-chloropleth-cartogram_files/figure-html/thecode2-1.png)
### Cartogram and Choropleth
To get a satisfying result, let's:
* Color hexagones according to their population
* Add legend
* Add background color
* Add title
* Add state name. Label position is computed thanks to the `gCentroid()` function.
```r
# Library
library(broom) # for the tidy function
library(rgeos) # for the gcentroid function
# tidy data to be drawn by ggplot2 (broom library of the tidyverse)
carto_fortified <- tidy(cartogram, region = "google_name")
carto_fortified <- carto_fortified %>%
left_join(. , cartogram@data, by=c("id"="google_name"))
# Calculate the position of state labels
centers <- cbind.data.frame(data.frame(gCentroid(cartogram, byid=TRUE), id=cartogram@data$iso3166_2))
# plot
ggplot() +
geom_polygon(data = carto_fortified, aes(fill = pop, x = long, y = lat, group = group) , size=0.05, alpha=0.9, color="black") +
scale_fill_gradientn(
colours=brewer.pal(7,"BuPu"), name="population (in M)",
guide=guide_legend( keyheight = unit(3, units = "mm"),
keywidth=unit(12, units = "mm"),
title.position = 'top',
label.position = "bottom")
) +
geom_text(data=centers, aes(x=x, y=y, label=id), color="white", size=3, alpha=0.6) +
theme_void() +
ggtitle( "Another look on the US population" ) +
theme(
legend.position = c(0.5, 0.9),
legend.direction = "horizontal",
text = element_text(color = "#22211d"),
plot.background = element_rect(fill = "#f5f5f9", color = NA),
panel.background = element_rect(fill = "#f5f5f9", color = NA),
legend.background = element_rect(fill = "#f5f5f9", color = NA),
plot.title = element_text(size= 22, hjust=0.5, color = "#4e4d47", margin = margin(b = -0.1, t = 0.4, l = 2, unit = "cm")),
) +
coord_map()
```
![](https://www.r-graph-gallery.com/332-hexbin-chloropleth-cartogram_files/figure-html/thecode3-1.png)
#### Animated Version
The following example describes extensively how to make a smooth transition between a [choropleth map](https://www.r-graph-gallery.com/chloropleth-map) and a [cartogram](https://www.r-graph-gallery.com/cartogram.html). This is possible thanks to the `tweenR` and the `gganimate` libraries. See the explanations [here](https://www.r-graph-gallery.com/a-smooth-transition-between-chloropleth-and-cartogram.html). See the [animation section](https://www.r-graph-gallery.com/animation.html) for more examples of animation with `R`.
### A Smooth Transition between Choropleth and Cartogram
This section describes how to make a smooth transition GIF between a [choropleth map](https://www.r-graph-gallery.com/choropleth-map.html) and a [cartogram](https://www.r-graph-gallery.com/cartogram.html). It starts by doing a basic map of Africa and then distorts country size using the `cartogram` library. `ggplot2` is used to build a good looking [choropleth](https://www.r-graph-gallery.com/choropleth-map.html) map. Animation is made possible thanks to the `tweenR` and `gganimate` packages.
#### Goal and Packages
At the end of this tutorial, you should get a `gif` file containing the following animation.
Before we start, make sure you've got the following libraries:
```r
# Please Ignore, specific to a bug in the gallery
library(pacman)
pacman::p_unload(pacman::p_loaded(), character.only = TRUE)
# Load libraries
library(dplyr) # data wrangling
library(cartogram) # for the cartogram
library(ggplot2) # to realize the plots
library(broom) # from geospatial format to data frame
library(tweenr) # to create transition dataframe between 2 states
library(gganimate) # To realize the animation
library(maptools) # world boundaries coordinates
library(viridis) # for a nice color palette
```
### A Basic Map of Africa
The [maptools library](https://cran.r-project.org/web/packages/maptools/maptools.pdf) provides all the information we need to draw a map of Africa.
All the country boundaries are stored in the `world_simpl` object. Let's load this object, keep only Africa, and draw a basic representation. This requires only 3 lines of code.
![](https://www.r-graph-gallery.com/a-smooth-transition-between-chloropleth-and-cartogram_files/figure-html/thecode2-1.png)
### Compute Cartogram Boundaries
The `afr` object is a spatial object. Thus it has a data slot that gives a few information concerning each region. You can visualise this info typing `afr@data` in our case.
You will see a column called `POP2005`, providing the number of inhabitants per country in 2005.
Using this information we can use the `cartogram` library to build. a [cartogram](https://www.r-graph-gallery.com/cartogram.html)! Basically, it will distort the shape of every country proportionally to its number of inhabitants.
The output is a new geospatial object that we can map like we've done before. As you can see, Nigeria appears way bigger on this map, since it has a population of about 141M inhabitants.
```r
# construct a cartogram using the population in 2005
afr_cartogram <- cartogram(afr, "POP2005", itermax=7)
# A basic representation
plot(afr_cartogram)
```
![](https://www.r-graph-gallery.com/a-smooth-transition-between-chloropleth-and-cartogram_files/figure-html/thecode3-1.png)
### A Nicer Representation using `ggplot2`
Let's improve the appearance of the previous maps using the [ggplot2](https://www.r-graph-gallery.com/ggplot2-package.html) library.
Note that `ggplot2` uses data frame and not geospatial object. The transformation to a data frame is done using the `tidy()` function of the `broom` package. Since it does not transfer the data slot automatically, we merge it afterward.
The `geom_polygon()` function is used to draw map data. See the [graph #327](https://www.r-graph-gallery.com/327-chloropleth-map-from-geojson-with-ggplot2.html) of the gallery for more explanation on [choropleth](https://www.r-graph-gallery.com/choropleth-map.html) maps with `ggplot2`.
```r
# Transform these 2 objects in dataframe, plotable with ggplot2
afr_cartogram_df <- tidy(afr_cartogram) %>% left_join(. , afr_cartogram@data, by=c("id"="ISO3"))
afr_df <- tidy(afr) %>% left_join(. , afr@data, by=c("id"="ISO3"))
# And using the advices of chart #331 we can custom it to get a better result:
ggplot() +
geom_polygon(data = afr_df, aes(fill = POP2005/1000000, x = long, y = lat, group = group) , size=0, alpha=0.9) +
theme_void() +
scale_fill_viridis(name="Population (M)", breaks=c(1,50,100, 140), guide = guide_legend( keyheight = unit(3, units = "mm"), keywidth=unit(12, units = "mm"), label.position = "bottom", title.position = 'top', nrow=1)) +
labs( title = "Africa", subtitle="Population per country in 2005" ) +
ylim(-35,35) +
theme(
text = element_text(color = "#22211d"),
plot.background = element_rect(fill = "#f5f5f4", color = NA),
panel.background = element_rect(fill = "#f5f5f4", color = NA),
legend.background = element_rect(fill = "#f5f5f4", color = NA),
plot.title = element_text(size= 22, hjust=0.5, color = "#4e4d47", margin = margin(b = -0.1, t = 0.4, l = 2, unit = "cm")),
plot.subtitle = element_text(size= 13, hjust=0.5, color = "#4e4d47", margin = margin(b = -0.1, t = 0.4, l = 2, unit = "cm")),
legend.position = c(0.2, 0.26)
) +
coord_map()
# You can do the same for afr_cartogram_df
```
![](https://www.r-graph-gallery.com/a-smooth-transition-between-chloropleth-and-cartogram_files/figure-html/thecode4-1.png)
### Compute Several Intermediate Maps
The goal being to make a smooth animation between the 2 maps, we need to create a multitude of intermediate maps using interpolation.
This is possible thanks to the awesome [tweenr](https://github.com/thomasp85/tweenr) library. (See a few examples in the [animation section](https://www.r-graph-gallery.com/animation.html) of the gallery).
At the end we've got a big data frame which contains enough information to draw 30 maps. Three of these maps are presented above.
```r
# Give an id to every single point that compose the boundaries
afr_cartogram_df$id <- seq(1,nrow(afr_cartogram_df))
afr_df$id <- seq(1,nrow(afr_df))
# Bind both map info in a data frame. 3 states: map --> cartogram --> map
data <- rbind(afr_df, afr_cartogram_df, afr_df)
# Set transformation type + time
data$ease <- "cubic-in-out"
data$time <- rep(c(1:3), each=nrow(afr_df))
# Calculate the transition between these 2 objects?
dt <- tween_elements(data, time='time', group='id', ease='ease', nframes = 30)
# check a few frame
ggplot() +
geom_polygon(data = dt %>% filter(.frame==0) %>% arrange(order),
aes(fill = POP2005, x = long, y = lat, group = group), size=0, alpha=0.9
)
```
![](https://www.r-graph-gallery.com/a-smooth-transition-between-chloropleth-and-cartogram_files/figure-html/thecode5-1.png)
```r
ggplot() +
geom_polygon(data = dt %>% filter(.frame==5) %>% arrange(order),
aes(fill = POP2005, x = long, y = lat, group = group) , size=0, alpha=0.9
)
```
![](https://www.r-graph-gallery.com/a-smooth-transition-between-chloropleth-and-cartogram_files/figure-html/thecode5-2.png)
```r
ggplot() +
geom_polygon(data = dt %>% filter(.frame==10) %>% arrange(order),
aes(fill = POP2005, x = long, y = lat, group = group) , size=0, alpha=0.9
)
```
![](https://www.r-graph-gallery.com/a-smooth-transition-between-chloropleth-and-cartogram_files/figure-html/thecode5-3.png)
### Make the Animation with `gganimate`
The last step consists at building the 30 maps and compile them in a .gif file. This is done using the gganimate library. This library uses another aesthetic: frame. A new plot is made for each frame, that allows us to build the gif afterwards.
<u>Note</u>: This code uses the old version of `gganimate`. It needs to be updated. Please drop me a message if you can help me with that!
```r
# Plot
p <- ggplot() +
geom_polygon(data = dt %>% arrange(order) , aes(fill = POP2005/1000000, x = long, y = lat, group = group, frame=.frame) , size=0, alpha=0.9) +
theme_void() +
scale_fill_viridis(
name="Population (M)", breaks=c(1,50,100, 140),
guide = guide_legend(
keyheight = unit(3, units = "mm"), keywidth=unit(12, units = "mm"),
label.position = "bottom", title.position = 'top', nrow=1)
) +
labs( title = "Africa", subtitle="Population per country in 2005" ) +
ylim(-35,35) +
theme(
text = element_text(color = "#22211d"),
plot.background = element_rect(fill = "#f5f5f4", color = NA),
panel.background = element_rect(fill = "#f5f5f4", color = NA),
legend.background = element_rect(fill = "#f5f5f4", color = NA),
plot.title = element_text(size= 22, hjust=0.5, color = "#4e4d47", margin = margin(b = -0.1, t = 0.4, l = 2, unit = "cm")),
plot.subtitle = element_text(size= 13, hjust=0.5, color = "#4e4d47", margin = margin(b = -0.1, t = 0.4, l = 2, unit = "cm")),
legend.position = c(0.2, 0.26)
) +
coord_map()
# Make the animation
#animation::ani.options(interval = 1/9)
gganimate(p, "Animated_Africa.gif", title_frame = F)
```
<center>
![](https://www.r-graph-gallery.com/img/graph/Animated_Cartogram_Africa.gif)
</center>
#### <u>Note</u>: gganimate in this example deprecated. Check [https://github.com/thomasp85/gganimate](https://github.com/thomasp85/gganimate) for current usage.
#### Conclusion
This post uses several concepts that are extensively described in the [R graph gallery](https://www.r-graph-gallery.com/):
* The [choropleth map](https://www.r-graph-gallery.com/choropleth-map.html) section gives several examples of choropleth maps, using different input types and several tools.
* The [cartogram](https://www.r-graph-gallery.com/cartogram.html) section gives further explanation about cartograms.
* The [animation](https://www.r-graph-gallery.com/animation.html) section explains more deeply how `tweenR` and `gganimate` work
* The [map](https://www.r-graph-gallery.com/map.html) section is a good starting point if you are lost in the map related packages jungle.
If you are interested in dataviz, feel free to visit the [gallery](https://www.r-graph-gallery.com/), or to follow me on [twitter](https://twitter.com/R_Graph_Gallery)!
## Choropleth Map
---
A [choropleth](https://www.data-to-viz.com/graph/choropleth.html) map displays divided geographical areas or regions that are coloured in relation to a numeric variable. This section provides many examples build with R. It focuses on the `leaflet` package for interactive versions, and the `ggplot2` for static ones.
### Choropleth map with R and `ggplot2`
This section describes how to build a [choropleth map](https://www.r-graph-gallery.com/choropleth-map.html) with `R` and the `ggplot2` package. It shows how to load geospatial data in R, merge region features and build the map. Reproducible code is provided.
Two inputs are needed to build a choropleth map:
* A geospatial object providing region boundaries (city districts of the south of France in this example). Data are available at the geoJSON format [here](https://github.com/gregoiredavid/france-geojson), and this section explains in detail how to read and represent geoJSON format with R.
* A numeric variable that we use to color each geographical unit. Here we will use the number of restaurant per city. The data has been found [here](https://www.insee.fr/fr/accueil).
#### Find and Download a `.geoJSON` File
This step has been extensively describe in [chart #325](https://www.r-graph-gallery.com/325-background-map-from-geojson-format-in-r/). The `geojsonio` library allows to read this type of format in `R`. To plot it with `ggplot2`, we first need to transform it to a data frame using the tidy function of the `broom` library. Then, the `geom_polygon()` function allows to represent this type of object!
```r
# Geospatial data available at the geojson format
library(geojsonio)
spdf <- geojson_read("https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/communes.geojson", what = "sp")
# Since it is a bit to much data, I select only a subset of it:
spdf <- spdf[ substr(spdf@data$code,1,2) %in% c("06", "83", "13", "30", "34", "11", "66") , ]
```
### Basic Background Map
We now have a geospatial object called `spdf`. This object could be plotted as is using the `plot()` function as explained [here](https://www.r-graph-gallery.com/choropleth-map-in-r.html).
However, an additional step is required to plot it with `ggplot2` that expects a data frame as input. It is possible to make the conversion using the `tidy` function of the `broom` package as shown below.
Finally, `geom_polygon` is used to plot the shape.
```r
# I need to fortify the data AND keep trace of the commune code! (Takes ~2 minutes)
library(broom)
spdf_fortified <- tidy(spdf, region = "code")
# Now I can plot this shape easily as described before:
library(ggplot2)
ggplot() +
geom_polygon(data = spdf_fortified, aes( x = long, y = lat, group = group), fill="white", color="grey") +
theme_void() +
coord_map()
```
![](https://www.r-graph-gallery.com/327-chloropleth-map-from-geojson-with-ggplot2_files/figure-html/thecode10-1.png)
### Read the Numeric Variable
The number of restaurant per city district has been found on the internet and a clean version is stored on the gallery website. It is thus easy to read it with read.table. Before doing a choropleth map, it is a good practice to check the distribution of your variable.
Here, we have a 'long tail' distribution: a few cities have a lot of restaurant. Thus we will probably need to apply a log scale to our color palette. It will avoid that all the variation is absorbed by these high values.
```r
# read data
data <- read.table("https://raw.githubusercontent.com/holtzy/R-graph-gallery/master/DATA/data_on_french_states.csv", header=T, sep=";")
head(data)
# Distribution of the number of restaurant?
library(dplyr)
data %>%
ggplot( aes(x=nb_equip)) +
geom_histogram(bins=20, fill='skyblue', color='#69b3a2') + scale_x_log10()
```
![](https://www.r-graph-gallery.com/327-chloropleth-map-from-geojson-with-ggplot2_files/figure-html/thecode2-1.png)
### Merge Geospatial and Numeric Data
This is a key step in choropleth map: your 2 inputs must have a id in common to make the link between them!
```r
# Make the merge
spdf_fortified = spdf_fortified %>%
left_join(. , data, by=c("id"="depcom"))
# Note that if the number of restaurant is NA, it is in fact 0
spdf_fortified$nb_equip[ is.na(spdf_fortified$nb_equip)] = 0.001
```
### Read the Numeric Variable
We can make a first basic choropleth map. We just need to add fill = our value in the aesthetic of our polygons.
```r
ggplot() +
geom_polygon(data = spdf_fortified, aes(fill = nb_equip, x = long, y = lat, group = group)) +
theme_void() +
coord_map()
```
![](https://www.r-graph-gallery.com/327-chloropleth-map-from-geojson-with-ggplot2_files/figure-html/thecode3-1.png)
### Customized Choropleth Map with R and `ggplot2`
There is a bit of work to do to get a descent figure. We need to change the color palette, improve the legend, use a log scale transformation for the colorscale, change background and add titles and explanation. Here is the code to do that, and the final result!
```r
library(viridis)
p <- ggplot() +
geom_polygon(data = spdf_fortified, aes(fill = nb_equip, x = long, y = lat, group = group) , size=0, alpha=0.9) +