中国行政单位树形图的可视化实战!
我国幅员辽阔,共有34个省级行政单位,包括23个省、5个自治区、4个直辖市、2个特别行政区。除去香港澳门2个特别行政区和台湾省特殊外,大陆地区共有31个省级区划单位。每个省级单位又可以细分为市级,县级,乡镇和村。
行政区划的关系可以用如下的一个树形图表示:根节点(第〇层)为中国(大陆),树的第一层为31个省级单位节点,第二层为省所辖的地级市,第三层(叶子节点)为市所辖区/县,每一个非叶子节点都可以向下展开到叶子节点。每一个叶节点也可以向上追溯至其所属父节点。动态演示过程可点击下方视频查看。
点击上方视频号链接查看动态效果
本篇文章主要来学习从爬虫获取数据到最终实现可视化的过程。
数据来源
本文所用的行政单位划分来自国家统计局2020年的最新标准,其最初目的是为保证第七次全国人口普查的顺利进行。如下图所示,参见文末链接。
网页分析
我们曾经在「实例讲解利用python进行数据获取与数据预处理」一文中提到过爬虫的流程为:请求,解析,存储。示意图如下所示。可在点击链接直接查看或后台回复”北京公交“获取。
省级数据解析
本次使用的网页是比较简单的静态网页,在网页上右键选择“显示网页源代码”就可以看到下图所示内容。可以发现我们的数据是嵌套在一个table
(表格)标签中,见下图第30行。各省市名称和相应的链接是在第40行的tr
标签中,并且可以看到有比较明显的样式标记
class='provincetr'
。所以可以使用xpath
进行数据解析,定位到tr
标签下每一个td
标签,获取相应a
标签的href
属性和文本,就得到了每个省的链接。
市级和县级数据解析
上一部分得到了每个省的链接,每个链接的内容是该省下的市级单位,如河北省的链接内容是石家庄等市。如果是北京这样的直辖市,则直接显示“市辖区”。
在网页结构上,市一级的数据和省级非常类似:我们需要的数据在class='citytr'
的tr
标签中。每一个市的名称和链接,也同样在相应td
标签下的a
标签中,下图分别是河北省与北京市的源代码。
获取了市级(如北京“市辖区”)的链接之后,用同样的思路和方法,分析市级下区/县的内容。也有几乎同样的规律:每个区/县的名称和链接在class='countrytr'
的tr
标签中。如下图是“北京市辖区”的链接内容,td
下有朝阳区,海淀区等的名称和链接信息。
区县再往下一级到乡镇/街道,乡镇再往下到居委会,也是同样的道理 。相应的tr
分别为class='towntr'
和class='villagetr'
。居委会已经是最小的行政单位,所以没有下一级的链接。由于获取方式相似,我们最终只采集和展示只到了区县一级。另外,由于乡镇及以下数量众多,在频繁请求时,可能会出现失败的情况。
数据获取和存储
前面的分析可以看到,每一级数据的获取是相似的,且获取数据的过程都是先请求再解析。因此可以把一些操作进行一定的封装。在实践时会发现,数据解析时,第一级(省级)和最后一级(居委会级)的解析和其余中间级别有一定的差别,主要是xpath
路径的差异,因此需要分别进行处理。下面来看具体代码。
代码设计编写
经过以上分析,我把数据获取部分写成了一个简单的类ContentParse
。类的结构示意如下图,包含一个成员变量info
和5个方法,分别用于初始化,请求和解析不同级别的数据。
由于对面向对象的理解比较粗浅,这样的设计只追求简单实用,不见得完美,你也可以有其他更科学合理的设计方式,代码也有很多优化的空间。
需要指出,这样的写法并不是一开始就是这样的,中间经过了很多调试和分析,在走通流程的基础上,增加了一些对异常,特殊情况等的处理,才最终形成了这个“能跑通”的版本。为方便理解,我在代码中做了详细的注释。
在后台回复“行政”,可获取全部代码,数据和结果文件。关于xpath
的语法和获取方式这里略过,可以在网上或之前的文章里查看,重要的是多实践,在应用中熟练和掌握。
下面类的代码用于构造ContentParse
类,是后续操作的基础,可以结合注释,在实践时理解和体会。
以上我们定义了一个类用于数据获取和解析,接下来看一下对类的具体使用。我画了一个示意图帮助理解(可能不是特别标准)。
首先需要初始化一个对象,传入初始url
获取各省级单位的名称和链接,如①所示。接下来在②处,初始化一个获取市级单位的对象,对于①中的每一个省级url
,获取相应的市级单位和链接。之后以此类推,③处的对象用于根据市级url
获取县级单位。继续获取乡镇和村也要初始化相应的对象。对每一个url
都需要调用get_content()
方法和相应的parse_content
方法。
关键代码如下,完整代码文件可在后台回复“行政”获取。
①处代码,获取省级单位
②处代码,获取市级单位
③处代码,获取县级单位
数据存储
以上代码中,最终得到的dataframe就是相应级别的行政区划数据。由于数据量较小,可以直接存储在文件中,使用dataframe的to_excel
方法即可实现。我已将后续可视化环节用到的区/县一级的完整数据,保存成了一个文件中countydf.xlsx
。如果前面的代码你没有运行成功,可以直接使用最终结果的文件用于可视化。后台回复“行政”即可获取。
可视化部分
需求分析
使用上一步保存好的文件进行文章开头树形图的绘制。pyecharts
中的树形图很容易绘制,关键在于把数据调整为需要的格式,见下面代码的data
。最后再进行一些美化设置即可。
tree=(Tree().add("", data).set_global_opts(title_opts=opts.TitleOpts(title="Tree-基本示例")))
tree.render()
对于data
的具体格式要求,我们可以从官网例子中找到答案。请看下图,展示了树形效果和相应的数据。
可以看出,每一个节点是一个字典格式,这个字典有两个key
,一个是name
,另一个是children
。name
的值为节点名称,children
比较复杂。如果节点没有子节点(如节点F
),则没有name
同级别的children
。如果节点有子节点,children
的值为一个列表,列表为其所有子节点的字典形式(如节点C
)。如果子节点还有子节点,则children
会形成嵌套结构。最终的data
是一个list
,且只有一个字典元素(即根节点)。
代码实现
从pandas
读入的原始数据样式如下,我们需要用到的是最后三个字段:name
,city
,province
。
需要把dataframe中的数据处理成前面分析的字典格式。核心代码如下,虽然比较简洁,但还是经过了多次思考和调试。下面进行讲解:
第2行我们选出了需要的三个字段。由于省市两级都有子节点,意味着同样的name
对应的children
是嵌套的,原始数据里,省和市也是重复出现的。所以对省和市要先“分组”,再统一处理其子节点,用到了groupby
操作。如代码第2行和第4行。
代码第5、6行是对同一市下的县(区)做处理。第5行首先通过lambda
构造出县(区)名称的列表。第6行利用列表推导式,把每一个县(区)的名字前加上name
,做成字典,由于县(区)都没有子节点,不需要有children
。但他们是属于每个城市的children
,而相应城市的名字是由外层循环传入的。需要注意每次进入内层循环时,都需要把区的列表置空。第6行之后,每一个城市都得到了相应的县(区)列表。append
操作把所有城市的县(区)结果放在一个country_name
列表中。
代码第7、8行是对同一省下的市做处理。第7行和第5行类似,得到市名称的列表。第8行直接将内层循环的结果作为children
的值,并加上相应省份的name
。最终把所有省的结果通过append
加入了res_name
列表。形成最终data
时,再把res_name
作为children
的值,并手动加入根节点。可视化的代码如下所示。
上面代码虽然比较长,但第12行到第30行都是给图装饰用的。具体的含义详见官方文档,参见文末链接。
简要说明几处:第18行控制初始只展示根节点,不展开。第20行到第24行控制非叶子节点的标签位置,标签与节点的距离和字体大小。第25到第30行控制叶子节点的标签位置,标签与节点的距离和字体大小。
需要注意第9行有一个对动画控制的阈值。当单个系列显示的图形数量大于这个阈值时会关闭动画,参见文末链接,默认为2000,需要设置这个阈值稍微大点,否则展开时不会有动画效果。
第35行通过render
方法进行渲染并生成HTML
结果文件。最终实现效果如下,实心的节点都可以通过手动点击进行展开。后台回复“行政” 可以获取本文完整的数据,代码和结果文件。下图和本文开头有些区别,这是由于在之前代码基础上,调整了23行的字体大小。
小结
本文完成了一个从数据获取到数据可视化的数据分析全过程。
数据获取部分进行了网页结构分析,封装工具类,爬取数据并存储等环节。数据可视化部分完成了对原始数据的加工,构造成需要的格式,使用了pandas
的groupby
,apply
和列表推导式,列表追加等操作,还学习了pyecharts
中对于图表样式的配置。
本文代码较多,实操性强,感兴趣还可以尝试在县级单位后续增加上乡镇和村级。您可以在后台回复“行政”获取全部代码,数据和结果文件,遇到问题,欢迎随时交流,快快动起手来吧!
reference
本文数据源-国家统计局:http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/index.html
树图链接:https://pyecharts.org/#/zh-cn/tree_charts?id=tree%ef%bc%9a%e6%a0%91%e5%9b%be
pyecharts全局配置项:https://pyecharts.org/#/zh-cn/global_options
推荐阅读
「超哥的杂货铺」原创文章导航
七步搞定一个综合案例,掌握pandas进阶用法!
实例讲解利用python进行数据获取与数据预处理
Pandas tricks 之 transform的用法
中国行政单位树形图的可视化实战!相关推荐
- 教程:获取中国行政单位shapefile文件
1.阿里云地图小工具:http://datav.aliyun.com/tools/atlas 在"范围选择器"中,选择自己需要的行政区域范围,可以下载JSON格式文件. 2.使用免 ...
- 【中国各省级行政单位编码及缩写】
中国各省级行政单位编码及缩写 包含 34个省级行政区,其中 24 个省 .5 个自治区.4个直辖市.2个特别行政区 序号 编码 地区 缩写 1 100000 中国 2 110000 北京 BJ 3 1 ...
- 中国省市SQL表---省级行政单位表
中国34个省级行政单位 23个省 5个自治区 4个直辖市 2特别行政区 -- 省级行政单位INSERT INTO `ckcx_sysinfo`.`_ud_province_city` ( `RUID` ...
- 众筹编写《微生物组数据分析与可视化实战》——成为宏基因组学百科全书的创始人...
众筹编写<微生物组数据分析与可视化实战>--成为宏基因组学百科全书的创始人 高通量测序的发展极大地推动了微生物组/宏基因组领域的发展.微生物组的数据分析和解读需要微生物学.生物信息学.统计 ...
- 刘永鑫:20分钟讲解微生物组数据分析与可视化实战
编者按: 2020 年 12 月 21 日,国内著名英文期刊 Protein & Cell 与热心肠研究院合作,成功举办了"Protein & Cell人类微生物组专刊线上论 ...
- R语言ggplot2可视化移除数据中的NA值再可视化实战:消除图形中非常突出的NA柱状图、使用subset函数、使用drop_na函数
R语言ggplot2可视化移除数据中的NA值再可视化实战:消除图形中非常突出的NA柱状图.使用subset函数.使用drop_na函数 目录
- R语言使用ggplot2包使用geom_dotplot函数绘制分组点图(双分类变量分组可视化)实战(dot plot)
R语言使用ggplot2包使用geom_dotplot函数绘制分组点图(双分类变量分组可视化)实战(dot plot) 目录 R语言使用ggplot2包使用geom_dotplot函数绘制分组点图(双 ...
- R语言sunburst图(sunburst plot)可视化实战:使用sunburstR包和ggplot2包进行可视化
R语言sunburst图(sunburst plot)可视化实战:使用sunburstR包和ggplot2包进行可视化 目录 R语言sunburst图
- python包NiBabel对医学影像文件格式进行读写并可视化实战:查看和显示.nii.gz、.nii文件
python包NiBabel对医学影像文件格式进行读写并可视化实战:查看和显示.nii.gz..nii文件 目录 python包NiBabel对医学影像文件格式进行读写并可视化实战:查看和显示.nii ...
最新文章
- 判断线程是否执行完毕_关于线程池你不能不知道的东西
- Android Studio导入Eclipse项目的两种方法
- 06 Java程序员面试宝典视频课程之Javascript
- 深度学习核心技术精讲100篇(五十九)-多业务融合推荐策略实战应用
- .NET Core 下使用 Kafka
- JavaScript基础简单入门
- 检测空指针 静态检测_Parasoft为G3提供专注于安全性和整体软件质量的静态分析解决方案...
- poj 1125 Floyd简单
- linux设备驱动原理与本质
- dnf手游体验服显示无法连接服务器,《DNF手游》体验服服务器人数上限怎么办 体验服服务器人数上限解决办法...
- 计算机二级题目之c运算符和表达式练习学习
- 组策略 禁止用户策略下发到指定计算机,使用组策略禁止域用户运行特定程序...
- 【题解】P3939数颜色
- 【设计】1359- Umi3 如何实现插件化架构
- Android性能优化:如何让App更快、更稳、更省(含内存、布局优化等)
- 用Linux做wifi热点/无线路由
- QQ2012 Beta3-QQ2013 Beta1聊天协议剖析
- css盒模型(css盒模型包括)
- 新人想要做好视频号;一下几点一定要明白。
- Python爬虫入门 | 5 爬取小猪短租租房信息
热门文章
- js history对象 back() foward() go()
- html设置打印规则,css @page规则控制打印设置选项
- linux向日葵控制软件下载链接(有些情况下打不开向日葵官方网站)
- 前端直接跨域到腾讯云ocr文字识别(失败)
- 腾讯云服务器小白保姆级教程
- 慌乱之中get到一个小技能----如何将CAJ转换成PDF
- 物理机如何迁移到云服务器?
- c语言局部变量怎么定义,深入了解C语言(局部变量的定义)
- pdfminer3k读取pdf文件
- Kendo UI:简介