Stata 绘制带 BGM 的动态地图

Stata 绘制带 BGM 的动态地图

在之前的教程里,我介绍了很多使用 R 语言绘制动态图表的,也介绍过使用 Stata 绘制地图的,今天我将使用疫情数据演示如何使用 Stata 绘制动态图表,当然这里使用的方法是先绘制一系列的静态地图然后再合成动态地图。静态图合成动图的方法很多,这里我使用的是前天介绍的,也就是使用 R 语言绘制带音效的动图。

视频讲解

获取疫情数据和地图数据

昨天我在知识星球上分享了一份疫情数据:https://t.zsxq.com/yFiIeMn 我们今天绘图使用的数据就是这份数据。我在本文的附件中为大家准备了三份数据:

  • chinamap: 中国地图数据
  • cnlabel:中国地图省份标签数据
  • worldmap:世界地图数据

我已经这些数据转换成 Stata 格式的数据了:

代码去哪了?

代码可以加入我的知识星球后从知识星球下载附件获取~
要了解如何加入我的知识星球,可以阅读关于界面或者添加我的微信咨询。

这样我们就得到了七份数据:

  1. china_prov_label.dta:中国省份名称标签位置数据;
  2. cncoord.dta:中国地图 coordinates 数据;
  3. cndb.dta:中国地图 dBase 数据;
  4. cnlabel.dta:中国地图标签位置数据(这个是没用的);
  5. cnlabelcoord.dta中国地图标签位置坐标系数据(这个是没用的);
  6. worldcoord.dta:世界地图 coordinates 数据;
  7. worlddb.dta:世界地图 dBase 数据;

最后,time_series_19-covid-Confirmed.csv 就是我们需要的疫情数据了,里面包含了世界各国各省/州的疫情数据。我们首先处理中国的。

中国的疫情地图

代码去哪了?

代码可以加入我的知识星球后从知识星球下载附件获取~
要了解如何加入我的知识星球,可以阅读关于界面或者添加我的微信咨询。

得到的省份分布数据是这样的:

在绘制动图地图之前我们先绘制一幅静态地图:

代码去哪了?

代码可以加入我的知识星球后从知识星球下载附件获取~
要了解如何加入我的知识星球,可以阅读关于界面或者添加我的微信咨询。

中国疫情省份分布的动态地图

下面我们循环绘制每天的静态地图:

代码去哪了?

代码可以加入我的知识星球后从知识星球下载附件获取~
要了解如何加入我的知识星球,可以阅读关于界面或者添加我的微信咨询。

这些绘制得到的静态图都被我保存到了 static 文件夹里面。

把多个图片合成 GIF 图 可以使用终端命令 convert,如果你的电脑(Windows)没有这个工具,可以使用 magick 工具,下载和使用方法可以阅读这里:https://www.imagemagick.org/script/command-line-processing.php

1
2
cd static
!convert -delay 30 *.png prov.gif

这里就不再建议使用这种方法了,因为又更好的选择了,我们可以使用 R 合成带有 BGM 的动图,代码和之前的一样:

代码去哪了?

代码可以加入我的知识星球后从知识星球下载附件获取~
要了解如何加入我的知识星球,可以阅读关于界面或者添加我的微信咨询。

世界疫情分布

首先还是整理数据:

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
import delimited using "time_series_19-covid-Confirmed.csv", clear encoding(utf8) varnames(nonames)
replace v2 = "China" if inlist(v2, "Mainland China", "Taiwan", "Hong Kong", "Macau")
drop v3 v4
foreach i of varlist _all{
replace `i' = "m" + `i' in 1
replace `i' = subinstr(`i', "/", "_", .)
}
nrow 1
destring, replace
ren mCountry_Region country
ren mProvince_State prov
gather m1_22_20 - m3_4_20

format prov %15s
replace variable = subinstr(variable, "m", "", .)
replace variable = subinstr(variable, "_20", "_2020", .)
gen date = date(variable, "MDY")
format date %tdCY-N-D
drop variable prov
compress
drop if date == .
bysort country date: egen confirmed = sum(value)
drop value
duplicates drop country date, force
save worlddata, replace

* 把疫情数据和地图数据合并
use worlddata, clear
ren country name
replace name = "Angola" if name == "Andorra"
replace name = "United Kingdom" if name == "UK"
replace name = "United States of America" if name == "US"
merge m:1 name using worlddb
drop _m
save worlddata, replace

还是先绘制一幅静态地图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
* 先绘制 3 月 3 号的
use worlddata, clear
keep if date == date("2020-03-03", "YMD") | missing(date)
replace confirmed = 0 if missing(confirmed)
local times = "截止 2020 年 3 月 3 号"
replace confirmed = 0 if missing(confirmed)
* 绘制地图
spmap confirmed using worldcoord, id(ID) ///
fcolor("68 1 84" "65 68 135" "42 120 142" "34 168 132" ///
"122 209 81" "253 231 37") ///
ocolor("white" ...) ///
clmethod(custom) clbreaks(0 0.9 9 99 999 9999 99999) ///
ti(新型冠状病毒肺炎疫情分布, size(*1.2) color(white)) ///
graphr(margin(medium)) ///
subti(`times', color(white)) ///
osize(vthin ...) ///
legend(size(*1.5) ///
order(2 "无" 3 "1~9 人" 4 "10~99 人" 5 "100~999 人" 6 "1000~9999人" 7 ">= 10000 人") ///
ti(确诊, size(*0.5) pos(11) color(white)) color(white)) ///
plotr(fcolor(24 24 24) lcolor(24 24 24)) ///
graphr(fcolor(24 24 24) lcolor(24 24 24)) xsize(10) ysize(5)

gr export 世界分布_20200303.png, width(2000) height(1000)

循环绘制每天的静态图:

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
/* 绘制多幅静态图 */
cd ~/Desktop/Stata绘制动态地图
use worlddata, clear
gen numdate = date
gsort date
* net install finance.pkg, from("https://czxa.top/pkg/finance")
numdate2string date
replace date = subinstr(date, "-", " 年 ", 1)
replace date = subinstr(date, "-", " 月 ", 2)
replace date = date + " 日"
replace date = "" if date == ". 年 . 月 . 日"
levelsof numdate, local(datelist)
replace confirmed = 0 if missing(confirmed)
foreach date in `datelist'{
preserve
keep if numdate == `date' | missing(numdate)
local times = "截止 `=date[1]'"
spmap confirmed using worldcoord, id(ID) ///
fcolor("68 1 84" "65 68 135" "42 120 142" "34 168 132" ///
"122 209 81" "253 231 37") ///
ocolor("white" ...) ///
clmethod(custom) clbreaks(0 0.9 9 99 999 9999 99999) ///
ti(新型冠状病毒肺炎疫情分布, size(*1.2) color(white)) ///
graphr(margin(medium)) ///
subti(`times', color(white)) ///
osize(vthin ...) ///
legend(size(*1.5) ///
order(2 "无" 3 "1~9 人" 4 "10~99 人" 5 "100~999 人" 6 "1000~9999人" 7 ">= 10000 人") ///
ti(确诊, size(*0.5) pos(11) color(white)) color(white)) ///
plotr(fcolor(24 24 24) lcolor(24 24 24)) ///
graphr(fcolor(24 24 24) lcolor(24 24 24)) xsize(10) ysize(5)
gr export "worldstatic/`date'.png", replace width(5584) height(2792)
restore
}

最后我们同样使用 R 语言合成带 BGM 的动图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 世界地图
makeplot2 <- function(){
datalist <- as.list(fs::dir_ls('worldstatic'))
lapply(datalist, function(data){
p <- ggdraw() +
draw_image(data)
print(p)
})
}

# round(72 * min(5584, 2792)/480)
av_capture_graphics(expr = makeplot2(),
output = "世界分布_BGM.mp4",
audio = "665.mp3", res = 419, width = 5584,
height = 2792, framerate = 4)

是不是也很酷炫呢,不过在酷炫的同时也掌握了不是 Stata 的命令!

知识星球附件链接:https://t.zsxq.com/2BIQJ6m

#

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×