(19)地图可视化

本文由SCY原创,转载注明出处。

本文主要讲解地图可视化

填充地图

1
2
3
4
5
6
library(sf)
library(readxl)
library(tidyverse)

read_sf("data/世界地图矢量数据(带九段线、南极).geojson") -> wdmp
wdmp
#> Simple feature collection with 254 features and 1 field
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -180 ymin: -89.9989 xmax: 180 ymax: 83.61018
#> Geodetic CRS:  WGS 84
#> # A tibble: 254 × 2
#>    code                                                                 geometry
#>    <chr>                                                      <MULTIPOLYGON [°]>
#>  1 AIA   (((-63.00121 18.22178, -63.16002 18.1714, -63.15335 18.20028, -63.0260…
#>  2 ALA   (((19.98951 60.35115, 20.0202 60.35089, 20.03385 60.35931, 20.08738 60…
#>  3 ATA   (((-57.02065 -63.37282, -56.92737 -63.50553, -56.78185 -63.57167, -56.…
#>  4 Ashm  (((123.5945 -12.4257, 123.5952 -12.43593, 123.5731 -12.43418, 123.5725…
#>  5 BLM   (((-62.83192 17.87648, -62.84691 17.87519, -62.85895 17.88366, -62.869…
#>  6 BMU   (((-64.73026 32.29346, -64.82015 32.25963, -64.84505 32.26229, -64.862…
#>  7 COK   (((-159.7405 -21.24925, -159.7725 -21.2495, -159.8131 -21.24206, -159.…
#>  8 CUW   (((-68.7511 12.05978, -68.80331 12.04547, -68.99514 12.14184, -69.1538…
#>  9 CYN   (((34.00447 35.06525, 33.96571 35.05678, 33.90328 35.08546, 33.86644 3…
#> 10 Gaza  (((34.24528 31.20833, 34.21252 31.29228, 34.19815 31.32261, 34.38729 3…
#> # ℹ 244 more rows
1
2
ggplot() +
geom_sf(data = wdmp)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
read_excel("data/世界发展指标.xlsx") -> df5
df5 |>
dplyr::filter(year ==2019) |>
select(`GDP (current US$)`, code, country) |>
full_join(wdmp) |>
st_sf() -> dfn

source("theme.R")
ggplot(dfn) +
geom_sf(aes(fill = `GDP (current US$)`), size = 0.2) +
scico::scale_fill_scico(palette = "davos") +
coord_sf(crs = "+proj=robin") +
guides(fill = guide_legend(label.position = "bottom")) +
scale_y_continuous(breaks = c(seq(-80, 60,20), 85)) +
labs(title = "2019 年世界各国 GDP 数据(现价美元)",
subtitle = "绘制:An Cao ",
caption = "数据来源:世界银行世界发展指标数据库\n<http://databank.worldbank.org/data/download/WDI_csv.zip>")

1
2
ggsave("temp.png", width = 10, height = 6)
knitr::plot_crop("temp.png")
#> [1] "temp.png"
1
2
ggsave("temp.pdf", width = 10, height = 6)
knitr::plot_crop("temp.pdf")
#> [1] "temp.pdf"
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
dfn |> 
mutate(gdp = case_when(
is.na(`GDP (current US$)`) ~ "无数据",
between(`GDP (current US$)`, 0, 1e8) ~ "< 1亿",
between(`GDP (current US$)`, 1e8, 1e9) ~ "1亿~10亿",
between(`GDP (current US$)`, 1e9, 1e10) ~ "10亿~100亿",
between(`GDP (current US$)`, 1e10, 1e11) ~ "100亿~1000亿",
between(`GDP (current US$)`, 1e11, 1e12) ~ "1000亿~1万亿",
between(`GDP (current US$)`, 1e12, 1e13) ~ "1万亿~10万亿",
between(`GDP (current US$)`, 1e13, 1e14) ~ "10万亿~100万亿"
)) |>
mutate(gdp = factor(gdp,
levels = c("无数据", "< 1亿",
"1亿~10亿", "10亿~100亿",
"100亿~1000亿", "1000亿~1万亿",
"1万亿~10万亿", "10万亿~100万亿"))) -> dfn

source("theme.R")
ggplot(dfn) +
geom_sf(aes(fill = gdp), size = 0.2) +
scico::scale_fill_scico_d(palette = "davos", direction = -1) +
coord_sf(crs = "+proj=robin") +
guides(fill = guide_legend(label.position = "bottom", nrow = 1)) +
scale_y_continuous(breaks = c(seq(-80, 60,20), 85)) +
labs(title = "2019 年世界各国 GDP 数据(现价美元)",
subtitle = "绘制:An Cao ",
caption = "数据来源:世界银行世界发展指标数据库\n<http://databank.worldbank.org/data/download/WDI_csv.zip>") +
theme(
legend.key.height = unit(0.2, "cm"),
legend.key.width = unit(1.25, "cm"),
legend.text = element_text(size = 8)
)

2019年各省地区生产总值

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
haven::read_dta("data/各省历年GDP.dta") |> 
dplyr::filter(年份 == 2019,
省份 != "中国"
) |>
dplyr::select(省代码,= 省份, 地区生产总值_亿元) -> provdf

# 新增因子型变量
provdf |>
mutate(
gdp = case_when(
is.na(地区生产总值_亿元) ~ "无数据",
between(地区生产总值_亿元, 0, 20000) ~ "< 20 千亿",
between(地区生产总值_亿元, 20000, 40000) ~ "20~40千亿",
between(地区生产总值_亿元, 40000, 60000) ~ "40~60千亿",
between(地区生产总值_亿元, 60000, 80000) ~ "60~80千亿",
between(地区生产总值_亿元, 80000, 150000) ~ "> 80千亿"
)
) |>
mutate(gdp = factor(
gdp,
levels = c("无数据",
"< 20 千亿",
"20~40千亿",
"40~60千亿",
"60~80千亿",
"> 80千亿")
)) -> provdf

read_sf("data/china_prov_full_map.json") |>
st_set_crs("+proj=lcc +lat_1=30 +lat_2=62 +lat_0=0 +lon_0=105 +x_0=0 +y_0=0 +ellps=krass +units=m +no_defs") -> prov

prov |>
left_join(provdf) |>
select(, 地区生产总值_亿元, gdp) -> provdf


library(ggspatial)
haven::read_dta('data/china_prov_label.dta') |>
dplyr::filter(!name %in% c("1000km", "N")) -> provlabel
provlabel
#> # A tibble: 35 × 4
#>       id         X        Y name  
#>    <dbl>     <dbl>    <dbl> <chr> 
#>  1     1  1623938. 5866667. 黑龙江
#>  2     2 -1609429. 5113455. 新疆  
#>  3     3   621816. 4559114. 山西  
#>  4     4    99683. 4501151. 宁夏  
#>  5     5 -1532343. 4038557. 西藏  
#>  6     6  1142137. 4495014. 山东  
#>  7     7   780159. 4174676. 河南  
#>  8     8  1325927. 4156136. 江苏  
#>  9     9  1142714. 3994883. 安徽  
#> 10    10   688818. 3846593. 湖北  
#> # ℹ 25 more rows
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
ggplot(provdf) + 
geom_sf(aes(fill = gdp),
color = "gray30",
size = 0.2) +
geom_text(aes(X, Y, label = name),
family = cnfont,
size = 3, color = "gray40",
data = provlabel) +
labs(title = "2019 年中国各省地区生产总值",
caption = "数据来源:CSMAR 国泰安数据库") +
scico::scale_fill_scico_d(palette = "davos",
name = NULL,
direction = -1) +
scale_x_continuous(expand = c(0.001, 0.001)) +
scale_y_continuous(expand = c(0.001, 0.001)) +
guides(fill = guide_legend(nrow = 1,
label.position = "top")) +
annotation_scale(
width_hint = 0.2,
text_family = cnfont
) +
annotation_north_arrow(
location = "tr", which_north = "false",
width = unit(1.6, "cm"),
height = unit(2, "cm"),
style = north_arrow_fancy_orienteering(
text_family = cnfont
)
) +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid.major = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank())

1
2
3
ggsave("2019中国各省GDP.png", width = 9, height = 9)

knitr::plot_crop('2019中国各省GDP.png')
#> [1] "2019中国各省GDP.png"

分面绘制

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
haven::read_dta('data/各省历年GDP.dta') |> 
dplyr::filter(省份 != "中国",
年份 %in% 2014:2019) |>
full_join(prov) |>
st_sf() |>
select(省份, 年份, 地区生产总值_亿元) -> provdf


bind_rows(
provdf |>
dplyr::filter(年份 == 2014 | is.na(年份)) |>
mutate(年份 = if_else(is.na(年份), 2014, 年份)),
provdf |>
dplyr::filter(年份 == 2015 | is.na(年份)) |>
mutate(年份 = if_else(is.na(年份), 2015, 年份)),
provdf |>
dplyr::filter(年份 == 2016 | is.na(年份)) |>
mutate(年份 = if_else(is.na(年份), 2016, 年份)),
provdf |>
dplyr::filter(年份 == 2017 | is.na(年份)) |>
mutate(年份 = if_else(is.na(年份), 2017, 年份)),
provdf |>
dplyr::filter(年份 == 2018 | is.na(年份)) |>
mutate(年份 = if_else(is.na(年份), 2018, 年份)),
provdf |>
dplyr::filter(年份 == 2019 | is.na(年份)) |>
mutate(年份 = if_else(is.na(年份), 2019, 年份))
) -> provdf2

# 增加gdp因子变量
provdf2 |>
mutate(gdp = case_when(
is.na(地区生产总值_亿元) ~ "无数据",
between(地区生产总值_亿元, 0, 20000) ~ "< 20 千亿",
between(地区生产总值_亿元, 20000, 40000) ~ "20~40千亿",
between(地区生产总值_亿元, 40000, 60000) ~ "40~60千亿",
between(地区生产总值_亿元, 60000, 80000) ~ "60~80千亿",
between(地区生产总值_亿元, 80000, 200000) ~ "> 80千亿",
)) |>
mutate(gdp = factor(gdp,
levels = c("无数据",
"< 20 千亿",
"20~40千亿",
"40~60千亿",
"60~80千亿",
"> 80千亿"))) -> provdf3


ggplot(provdf3) +
geom_sf(aes(fill = gdp),
color = "gray30",
size = 0.2) +
facet_wrap(~年份, nrow = 2) +
labs(title = "2014~2019 年中国各省地区生产总值",
caption = "数据来源:CSMAR 国泰安数据库") +
scico::scale_fill_scico_d(palette = "davos",
name = NULL,
direction = -1) +
scale_x_continuous(expand = c(0.001, 0.001)) +
scale_y_continuous(expand = c(0.001, 0.001)) +
annotation_scale(
width_hint = 0.2,
height = unit(0.15, "cm"),
text_family = cnfont
) +
annotation_north_arrow(
location = "bl", which_north = "false",
pad_y = unit(0.4, "cm"),
pad_x = unit(0.8, "cm"),
width = unit(0.6, "cm"),
height = unit(0.8, "cm"),
style = north_arrow_fancy_orienteering(
text_family = cnfont
)
) +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
strip.text = element_text(family = cnfont,
colour = "gray30",
hjust = 0.5),
legend.position = "bottom",
plot.margin = unit(rep(0.5, 4), "cm"),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
panel.grid.major = element_blank()) +
guides(fill = guide_legend(nrow = 1,
title.position = "top",
title.hjust = 0.5,
label.position = "top"))

瞄点地图

1
2
3
4
5
6
# 描点地图
library(sf)
library(readr)
library(tidyverse)
library(hrbrthemes)
library(ggtext)
1
2
3
4
5
6
7
8
9
read_sf('data/世界地图矢量数据(带九段线、南极).geojson') |> 
st_transform(crs = 4326) -> worldmap

read_csv('data/data-bKvwd.csv') |>
st_as_sf(coords = c("Lon", "Lat"), crs = 4326) |>
select(`2000-2016`, City, category, geometry) |>
mutate(`2000-2016` = as.numeric(`2000-2016`)) -> df

df
#> Simple feature collection with 503 features and 3 fields
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: -123.12 ymin: -37.81 xmax: 174.77 ymax: 60.17
#> Geodetic CRS:  WGS 84
#> # A tibble: 503 × 4
#>    `2000-2016` City           category                 geometry
#>  *       <dbl> <chr>          <chr>                 <POINT [°]>
#>  1         1.3 Melbourne      between 0 and 2.5 (144.96 -37.81)
#>  2         1.5 Auckland       between 0 and 2.5 (174.77 -36.87)
#>  3         0.6 Adelaide       between 0 and 2.5  (138.6 -34.93)
#>  4         0.4 Montevideo     between 0 and 2.5 (-56.17 -34.83)
#>  5         1.3 Buenos Aires   between 0 and 2.5  (-58.4 -34.61)
#>  6         1.9 Cape Town      between 0 and 2.5  (18.42 -33.93)
#>  7         1.3 Port Elizabeth between 0 and 2.5  (25.57 -33.92)
#>  8         0.7 Sydney         between 0 and 2.5 (151.21 -33.87)
#>  9         0.9 Santiago       between 0 and 2.5 (-70.65 -33.46)
#> 10         1.2 Rosario        between 0 and 2.5 (-60.64 -32.95)
#> # ℹ 493 more rows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ggplot(worldmap) + 
geom_sf(size = 0.1, color = "black",
fill = "#F3F3F3") +
geom_sf(data = df, aes(size = `2000-2016` + 1,
color = category),
alpha = 0.5) +
scale_size_continuous(range = c(1, 5)) +
scale_color_manual(values = c("negative" = "#FDAB62",
"between 0 and 2.5" = "#9CDAE6",
"between 2.5 and 5" = "#189DB6",
"5 or more" = "#244C6A",
"null" = NA)) +
theme(legend.position = "none",
axis.text.x = element_blank()) +
labs(title = "大城市发展的有多快?",
subtitle = "该图展示了 2016 年所有人口超过 100 万的大城市,圆圈的大小和颜色表示 2000 年到 2016 年间城市人口的平均增长速度。<b><span style='color:\"#FDAB62\"'>负增长</span> / <span style='color:\"#9CDAE6\";'>0 - 2.5%</span> / <span style='color:\"#189DB6\";'>2.5% - 5%</span> / <span style='color:\"#244C6A\";'>超过 5%</span></b>",
caption = "数据来源: How fast do big cities grow? | Created with Datawrapper\n<https://www.datawrapper.de/_/bKvwd/>") +
theme(plot.subtitle = element_textbox_simple(),
plot.background = element_rect(color = "gray80")) +
coord_sf(crs = "+proj=robin")

-------------已经到底啦-------------