数据分析
首发于数据分析
Python绘制中国地图

Python绘制中国地图

Python绘制地图,可以分别用Basemap库和pyecharts库来实现。

一、Basemap

首先介绍Basemap库。这个库本身使用起来是不难的,但是安装有点小烦琐,依赖的库比较多,matplotlib、PROJ4、GEOS、Pillow都需要安装好。但是对于学习编程的各位来说,安装这个小事是难不倒你们的,多折腾几次就好,谁还没踩过几个坑。

官方安装文档

https://matplotlib.org/basemap/users/installing.htmlmatplotlib.org

知乎上找的一篇安装教程

步其:【我是解决安装问题系列_1】Mac python basemap安装zhuanlan.zhihu.com图标

对了,Mac电脑的话,强烈建议安装HomeBrew,一款软件管理神器,非常好用,谁用谁知道。

安装好Basemap后,还要下载中国地图shape文件。哪里下载呢?给大家提供一个专门下载各个国家地图数据的网站,GADM ,世界各国的地图数据都有。

https://gadm.org/download_country_v3.htmlgadm.org

然后还要准备一份各省的数据,下载数据的网站都准备好了,2010年的各省人口普查数据,任君下载。下载下来的Excel表格,处理一下表头就好。

indexwww.stats.gov.cn

准备工作做好之后,正式进入绘制地图并着色,参考文章:

用Python画一个中国地图 | 张京www.fengerzh.com图标https://www.fengerzh.com/draw-china-map-with-python-2/www.fengerzh.com

首先,我们绘制一个世界地图。前两行代码是引用库,第三行代码是指定图的大小,第四行创建一个地图,第五行绘制海岸线,第六行展示图。

是不是非常简单,为什么说“人生苦短,我用Python”,因为Python可引用的第三方库非常多,实现功能,往往几行代码就够了。

那怎么绘制中国地图,只需要在创建Basemap的时候,指定经纬度,然后画国家线就可以了。仔细看下面的代码,Basemap里面加入了经纬度,绘制国家线drawcountries


那如果我需要中国地图,并区分各省的形状和颜色怎么办呢?这就要用到我们下载的shape文件和各省的数据表格,前两个案例只是大致展示了怎么绘制地图,现在我们就要开始区分省并涂色。

from matplotlib.patches import Polygon
m.readshapefile(r'/Users/song/Downloads/gadm36_CHN_shp/gadm36_CHN_1', 'states', drawbounds=True)
ax = plt.gca()
for nshape, seg in enumerate(m.states):
    poly = Polygon(seg, facecolor='r')
    ax.add_patch(poly)

在之前的代码上,增加这几行,就可以得到下图红色的地图。

这次我们引入了Polygon,并且读取了shapefile文件。 gca是Get Current Axes的缩写,获得当前图形的座标轴。r是Red的缩写,我们开始循环,把图形文件中各个省,给它上了一个颜色,就是红色。

那怎么给不同的省上不同的颜色,只需要改变facecolor就好,也就是把它设为动态,赋予不同的值。

代码贴在这里,就不详细解释了。核心就是循环省份,根据省份的不同数据,着不同的颜色。台湾的shape文件需要单独下载,不然地图无法显示,但是pyecharts中就不存在这个问题。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
from matplotlib.colors import rgb2hex
plt.figure(figsize=(16,8))
m = Basemap(
    llcrnrlon=73.55770111084013, 
    llcrnrlat=18.159305572509766, 
    urcrnrlon=134.7739257812502, 
    urcrnrlat=53.56085968017586
)
# 31个省、直辖市、自治区
m.readshapefile(r'/Users/songrenqing/Downloads/gadm36_CHN_shp/gadm36_CHN_1', 'states', drawbounds=True)
df = pd.read_excel(r'/Users/song/Downloads/A0101a.xls')
df['省名'] = df.地区.str[:2]
df.set_index('省名', inplace=True)
statenames=[]
colors={}
cmap = plt.cm.YlOrRd
vmax = 100000000
vmin = 3000000
for shapedict in m.states_info:
    statename = shapedict['NL_NAME_1']
    p = statename.split('|')
    if len(p) > 1:
        s = p[1]
    else:
        s = p[0]
    s = s[:2]
    if s == '黑龍':
        s = '黑龙'
    statenames.append(s)
    pop = df['人口数'][s]
    colors[s] = cmap(np.sqrt((pop - vmin) / (vmax - vmin)))[:3]

ax = plt.gca()
for nshape, seg in enumerate(m.states):
    color = rgb2hex(colors[statenames[nshape]])
    poly = Polygon(seg, facecolor=color, edgecolor=color)
    ax.add_patch(poly)

plt.savefig(r'/Users/song/Downloads/test.png')
plt.show()


二、pyecharts

pyecharts的使用就更简单了。pyecharts是一个用于生成Echarts图表的类库,Echarts是百度开源的一个数据可视化JS库

安装库 pip install pyecharts

安装地图文件

全球国家地图: echarts-countries-pypkg

中国省级地图: echarts-china-provinces-pypkg

中国市级地图: echarts-china-cities-pypkg

全部直接使用python的pip安装,安装好之后,就可以使用了

pip install pyecharts
pip install echarts-countries-pypkg
pip install eecharts-china-provinces-pypkg
pip install echarts-china-cities-pypkg

pyecharts的使用,看这两个网站就够了,没有什么好讲的。知道那个参数是用来干什么的,能实现什么功能就好。

pyecharts - 首页pyecharts.herokuapp.com
A Python Echarts Plotting Librarypyecharts.org

给大家看一下官方的案例,就知道pyecharts绘制地图有多方便。pyecharts实现其他图表,比如柱状图、折线图也非常方便,毕竟echarts是专业的图表库。

from pyecharts import Map
import pandas as pd
#注意:省市不要包含“省"、"市"等字
data=[("广东",10430.03),("山东",9579.31),("河南",9402.36),("四川",8041.82),("江苏",7865.99),("河北",7185.42),("湖南",6568.37),("安徽",5950.1),("浙江",5442),("湖北",5723.77),("广西",4602.66),("云南",4596.6),("江西",4456.74),("辽宁",4374.63),("黑龙江",3831.22),("陕西",3732.74),("山西",3571.21),("福建",3552),("重庆",2884),("贵州",3476.65),("吉林",2746.22),("甘肃",2557.53),("内蒙古",2470.63),("上海",2301.391),("台湾",2316.2),("新疆",2181.33),("北京",1961.2),("天津",1293.82),("海南",867.15),("香港",709.76),("青海",562.67),("宁夏",630.14),("西藏",300.21),("澳门",55.23)]

data=pd.DataFrame(data)
data.columns=['city','popu']

map=Map("各省市人口数", "单位:万人", title_color="#fff", title_pos="center", width=1200,  height=600, background_color='#404a59')

attr=data['city']
value=data['popu']
map.add("", attr, value, visual_range=[min(value), max(value)],visual_text_color="#000", symbol_size=15,is_visualmap=True,is_label_show=True,label_pos = 'bottom')
map
from pyecharts import Geo
 
data = [
    ("海门", 9),("鄂尔多斯", 12),("招远", 12),("舟山", 12),("齐齐哈尔", 14),("盐城", 15),
    ("赤峰", 16),("青岛", 18),("乳山", 18),("金昌", 19),("泉州", 21),("莱西", 21),
    ("日照", 21),("胶南", 22),("南通", 23),("拉萨", 24),("云浮", 24),("梅州", 25),
    ("文登", 25),("上海", 25),("攀枝花", 25),("威海", 25),("承德", 25),("厦门", 26),
    ("汕尾", 26),("潮州", 26),("丹东", 27),("太仓", 27),("曲靖", 27),("烟台", 28),
    ("福州", 29),("瓦房店", 30),("即墨", 30),("抚顺", 31),("玉溪", 31),("张家口", 31),
    ("阳泉", 31),("莱州", 32),("湖州", 32),("汕头", 32),("昆山", 33),("宁波", 33),
    ("湛江", 33),("揭阳", 34),("荣成", 34),("连云港", 35),("葫芦岛", 35),("常熟", 36),
    ("东莞", 36),("河源", 36),("淮安", 36),("泰州", 36),("南宁", 37),("营口", 37),
    ("惠州", 37),("江阴", 37),("蓬莱", 37),("韶关", 38),("嘉峪关", 38),("广州", 38),
    ("延安", 38),("太原", 39),("清远", 39),("中山", 39),("昆明", 39),("寿光", 40),
    ("盘锦", 40),("长治", 41),("深圳", 41),("珠海", 42),("宿迁", 43),("咸阳", 43),
    ("铜川", 44),("平度", 44),("佛山", 44),("海口", 44),("江门", 45),("章丘", 45),
    ("肇庆", 46),("大连", 47),("临汾", 47),("吴江", 47),("石嘴山", 49),("沈阳", 50),
    ("苏州", 50),("茂名", 50),("嘉兴", 51),("长春", 51),("胶州", 52),("银川", 52),
    ("张家港", 52),("三门峡", 53),("锦州", 54),("南昌", 54),("柳州", 54),("三亚", 54),
    ("自贡", 56),("吉林", 56),("阳江", 57),("泸州", 57),("西宁", 57),("宜宾", 58),
    ("呼和浩特", 58),("成都", 58),("大同", 58),("镇江", 59),("桂林", 59),("张家界", 59),
    ("宜兴", 59),("北海", 60),("西安", 61),("金坛", 62),("东营", 62),("牡丹江", 63),
    ("遵义", 63),("绍兴", 63),("扬州", 64),("常州", 64),("潍坊", 65),("重庆", 66),
    ("台州", 67),("南京", 67),("滨州", 70),("贵阳", 71),("无锡", 71),("本溪", 71),
    ("克拉玛依", 72),("渭南", 72),("马鞍山", 72),("宝鸡", 72),("焦作", 75),("句容", 75),
    ("北京", 79),("徐州", 79),("衡水", 80),("包头", 80),("绵阳", 80),("乌鲁木齐", 84),
    ("枣庄", 84),("杭州", 84),("淄博", 85),("鞍山", 86),("溧阳", 86),("库尔勒", 86),
    ("安阳", 90),("开封", 90),("济南", 92),("德阳", 93),("温州", 95),("九江", 96),
    ("邯郸", 98),("临安", 99),("兰州", 99),("沧州", 100),("临沂", 103),("南充", 104),
    ("天津", 105),("富阳", 106),("泰安", 112),("诸暨", 112),("郑州", 113),("哈尔滨", 114),
    ("聊城", 116),("芜湖", 117),("唐山", 119),("平顶山", 119),("邢台", 119),("德州", 120),
    ("济宁", 120),("荆州", 127),("宜昌", 130),("义乌", 132),("丽水", 133),("洛阳", 134),
    ("秦皇岛", 136),("株洲", 143),("石家庄", 147),("莱芜", 148),("常德", 152),("保定", 153),
    ("湘潭", 154),("金华", 157),("岳阳", 169),("长沙", 175),("衢州", 177),("廊坊", 193),
    ("菏泽", 194),("合肥", 229),("武汉", 273),("大庆", 279)]
geo = Geo("全国主要城市空气质量", "data from pm2.5", title_color="#fff",
          title_pos="center", width=1000,
          height=600, background_color='#404a59')
attr, value = geo.cast(data)
geo.add("", attr, value, visual_range=[min(value), max(value)], maptype='china',visual_text_color="#fff", symbol_size=10, is_visualmap=True)
geo


这种动态图也可以实现,就在我上面给的网站中,大家好好研究吧,作出好看的可视化图表指日可待了。

from pyecharts import GeoLines, Style

style = Style(
    title_top="#fff",
    title_pos = "center",
    width=1000,
    height=500,
    background_color="#404a59"
)

style_geo = style.add(
    is_label_show=True,
    line_curve=0.2,
    line_opacity=0.6,
    legend_text_color="#eee",
    legend_pos="right",
    geo_effect_symbol="plane",
    geo_effect_symbolsize=15,
    label_color=['#a6c84c', '#ffa022', '#46bee9'],
    label_pos="right",
    label_formatter="{b}",
    label_text_color="#eee",
    legend_selectedmode="single", #指定单例模式
)

data_beijing = [
    ["北京", "上海"],
    ["北京", "广州"],
    ["北京", "南京"],
    ["北京", "重庆"],
    ["北京", "兰州"],
    ["北京", "杭州"]
]

data_guangzhou = [
    ["广州", "上海"],
    ["广州", "北京"],
    ["广州", "南京"],
    ["广州", "重庆"],
    ["广州", "兰州"],
    ["广州", "杭州"]
]
geolines = GeoLines("GeoLines 示例", **style.init_style)
geolines.add("从广州出发", data_guangzhou, **style_geo)
geolines.add("从北京出发", data_beijing, **style_geo)
geolines

编辑于 2018-09-27

文章被以下专栏收录