前言

本文以会议报告人所在机构的分布为例, 介绍了如何基于pyecharts制作地理分布图.

前段时间去深圳参加一个研究方向有关的会议, 国内做实验和理论研究的老师都来了, 于是心血来潮想有没有可能做一个统计来看看老师们所在机构的地理分布. 虽然报告人并不多, 但应该也能提供一些定性的信息, 也算是学习一种图片制作和数据展示技巧.
经过一番搜索, 决定采用Python包pyecharts中的地理图标Geo类来制作. 使用Python版本为3.7.1, pyecharts版本为1.5.1.

准备

首先通过pip安装pyecharts

1
pip install pyecharts

同时安装中国省市地图包

1
pip echarts-china-provinces-pypkg echarts-china-cities-pypkg

为方便直接输出图片, 安装snapshot_selenium或者snapshot_phantomjs

1
pip snapshot_selenium snapshot_phantomjs

初步尝试

简化一下存放在site-packages/example里的geo_example.py, 得到下面的代码

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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
from pyecharts import options as opts
from pyecharts.charts import Geo, Page
from pyecharts.faker import Collector
from pyecharts.render import make_snapshot
#from snapshot_selenium import snapshot
from snapshot_phantomjs import snapshot

# speaker.json存储了以speaker老师名字为key的字典
# 包含"省份"和"方向"两个key-value.
with open("speaker.json", 'r') as h:
speaker = json.load(h)
provs = [s["省份"] for s in speaker.values()]
data = [[p, provs.count(p)] for p in set(provs)]

C = Collector

@C.funcs
def geo_speakermap() -> Geo:
c = (
Geo()
.add_schema(maptype="china")
.add("", data)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
visualmap_opts=opts.VisualMapOpts(min_=0, max_=15, type_="size"),
title_opts=opts.TitleOpts(title="报告人分布"),
)
)
return c

make_snapshot(snapshot, Page().add(*[fn() for fn, _ in C.charts]).render(),
"speakermap.png", browser='Safari')

得到分布图如下

报告人主要分布在沿海城市的大学和研究所, 除了bug的帝都. 下面就作图涉及的几个点具体说明一下

Collector类

Collector是pyechart提供的一个convenient function, 源码很短, 提供了一个列表属性和一个静态方法用Collector.funcs装饰后, 函数返回的Geo实例会加入到列表Collector.charts中.

1
2
3
4
5
6
class Collector:
charts = []

@staticmethod
def funcs(fn):
Collector.charts.append((fn, fn.__name__))

Geo类及其方法的调用利用了方法链语法, 不需要换行符来强制换行.

全局变量控制

set_global_opts方法调整echarts图片的全局设置. 这个方法继承自Chart类.
参数visualmap_opts控制左下角标尺, 需要以pyecharts.options.VisualMapOpts实例作为输入.
这里因为总人数比较少, 所以调整了最大范围为15, 并用图标尺寸而非颜色来表示数值大小(type_), 加强对比.
其他全局变量设置可以参考官网.

图片生成

pyecharts.render.snapshot提供了make_snapshot函数. make_snapshot实际是selenium或phantomjs的snapshot同名函数的包装.

这里用phantomjs直接渲染更快一些, 且不会跳出Safari.

总结

本文基于pyecharts的Geo类制作了报告人所在机构的地理分布. 文中所描述的图片制作是一些简单尝试, 还有很多应该可以调教的地方, 比如标记的颜色, 标尺和主图的相对位置. 不过统计数据太少, 机构地点还只限制在省级, 所得到的结论比较trivial.

echarts还提供了包括全球和国内省市地图在内的其他地图以及word cloud等不同类型的图片呈现方式, 并有现成的例子可供参考, 为地理数据统计和展示提供了一种方便的选择.

参考资料

知乎 - Python绘制中国地图: 引导我使用pyecharts. 但是这个教程及其中链接的官方网站的API不适用于1.5.1版本.

pyecharts官网

Creating a Choropleth Map of the World in Python using GeoPandas: 做全球数据统计看上去很不错

Comments