(数据科学进修手札78)基于geopandas的空间数据剖析——基本可视化
你一定看得懂的 DDD+CQRS+EDA+ES 核心思想与极简可运行代码示例
本文对应代码和数据已上传至我的
Github
堆栈
1 简介
经由历程前面的文章,我们已对geopandas
中的数据结构、坐标参考系以及文件IO有了较为深切的进修,在拿到一份矢量数据入手下手剖析时,对其举行可视化无疑是探究相识数据阶段重要的步骤。
作为基于geopandas的空间数据剖析系列文章的第四篇,经由历程本文你将会进修到基于geopandas
的基础可视化。
2 基础可视化
geopandas
应用matplotlib
作为画图后端,应用plot()
要领对GeoSeries
或GeoDataFrame
举行可视化,简简朴单即可完成基础的可视化,再连系上matplotlib
的一些分外元素补充,便能够建立出越发优美的可视化作品,下面我们离别举行引见。
2.1 GeoSeries
GeoSeries
由于唯一零丁一列多少对象,无对应的数值故不触及数值向视觉元素的映照,因而可视化相对简朴,下面我们先来看看GeoSeries.plot()
的经常使用的参数有哪些,假如你已对matplotlib
有肯定相识,想必邃晓这些参数起来会越发轻松:
figsize:传入(宽度, 高度)情势的元组或列表,用于掌握绘制出图象的宽度和高度,单元均为英寸
facecolor:设置多少对象的添补色,可接受颜色称号和十六进制颜色,设置为'none'时不添补颜色
edgecolor:设置多少对象的边境色,对面数据和点数据效果较为显著,不发起对线数据设置该参数,传入花样同facecolor
linewidth:设置多少对象边境宽度,对面数据和点数据效果较为显著,不发起对线数据设置该参数
linestyle:字符串范例,用于设置多少对象边境及线数据的线型
markersize:设置点数据的大小
marker:字符串范例,用于设置点数据的外形
alpha:设置对应多少对象全局的颜色透明度,0-1,越大越不透明
label:实用于地道的线数据或点数据,在须要增添图例时实用,用作各个对象在图例中显现的称号
hatch:字符型,用于设置面数据内部的添补线款式下文的例子中将细致举例申明
ax:
matplotlib
坐标轴对象,假如须要在同一个坐标轴内叠加多个图层就须要用这个参数传入先前待叠加的ax
下面我们从现实例子上手,深切邃晓上述各参数,我们应用到的数据china-shapefiles.zip
为中国领土+南海九段线,你能够在本文开头列出的Github
堆栈对应本文的途径下找到它。
起首应用上一篇文章引见的读取.zip
文件中数据的要领,将我们所需的陆地及九段线数据离别读入(个中由于原始数据china.shp
中每一个要素不是零丁的省份而是面,即有的包含浩瀚岛屿的省份会由多少行配合组成,因而应用geopandas
地舆操纵中的融会dissolve()
根据OWNER
列融会星散的面为多面,从而使得每一行是对应的完全的省份,关于更多地舆操纵将会在后续的对应的文章引见):
import geopandas as gpd
import matplotlib.pyplot as plt
# 设置matplotlib画图形式为嵌入式
%matplotlib inline
plt.rcParams["font.family"] = "SimHei" # 设置全局中笔墨体为黑体
# 读入中国领土面数据
china = gpd.read_file('zip://china-shapefiles.zip!china-shapefiles/china.shp',
encoding='utf-8')
# 由于每行数据是零丁的面,因而根据其省份列OWNER融会
china = china.dissolve(by='OWNER').reset_index(drop=False)
# 读入南海九段线线数据
nine_lines = gpd.read_file('zip://china-shapefiles.zip!china-shapefiles/china_nine_dotted_line.shp',
encoding='utf-8')
用plot()
要领叠加绘制不带任何个性化参数的原始舆图(CRS
为EPSG:4326即WGS84):
# 初始化图床
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.plot(ax=ax)
ax = nine_lines.geometry.plot(ax=ax)
fig.savefig('图1.png', dpi=300)
图1
接下来我们一步一步,将实用于GeoSeries.plot()
的参数展现应用:
- Step1:挑选适宜的投影
在之前关于坐标参考系的文章中我们相识过绘制舆图时投影的重要性,参考超图对绘制中国舆图投影选用方面的发起(),我们应用绘制中国舆图经常使用的Albers Equal Area作为投影,在https://proj.org/operations/projections/aea.html查询到其信息申明:
图2
将其proj
信息传入to_crs()
要领中(注重根据将增添上中央经线105度和规范纬度局限25到47度),统一到一切图层中:
# 定义CRS
albers_proj = '+proj=aea +lat_1=25 +lat_2=47 +lon_0=105'
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax)
fig.savefig('图3.png', dpi=300)
图3
这时刻的外形较为靠近真实情况,看起来也比较天然。
- Step2:修正颜色
下面我们来调解面数据的添补色与表面色,线数据(九段线)的颜色,并离别设置透明度alpha
,这里为了雅观,将坐标轴趁便移除:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
alpha=0.4)
ax.axis('off') # 移除坐标轴
fig.savefig('图4.png', dpi=300)
图4
- Step3:修正线型与线宽
接下来我们在图4的基础上,修正线型和线宽,个中线型参数linestyle
与matplotlib
完全一致,差别挑选对应款式如图5:
图5
参考图5,我们保持九段线线型稳定但恰当增大其宽度为3,面数据的表面则设置为'--'
:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off') # 移除坐标轴
fig.savefig('图6.png', dpi=300)
图6
- Step4:修正面添补暗影线款式
接下来我们应用hatch
参数来修正面数据添补暗影款式,重要款式对应以下,如'-'
代表横线添补:
图7
参考图7,我们设置面数据的添补暗影款式为'x'
,值得一提的是,hatch
参数关于同一种暗影形式,能够经由历程增添字符数目来进步暗影密度,以下图是hatch='x'
时:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
hatch='x',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off') # 移除坐标轴
fig.savefig('图8.png', dpi=300)
图8
而hatch='xxxx'
时绘制出的舆图以下:
图9
更有意义的是,差别暗影形式能够夹杂在一起,比如我们下面设置hatch='x**'
:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
hatch='x**',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off') # 移除坐标轴
fig.savefig('图10.png', dpi=300)
图10
- Step5:点数据个性化
GeoSeries.plot()
中的markersize
和marker
特地针对点数据举行设置,然则我们的数据里并没有点数据,为了举例申明,下面我们来从已有的数据中生成点数据,我最入手下手的主意是为每一个面生成重心,作为每一个省份的中间点:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
hatch='xxxx',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax = china.geometry.centroid.to_crs(albers_proj).plot(ax=ax,
facecolor='black')
ax.axis('off') # 移除坐标轴
fig.savefig('图11.png', dpi=300)
图11
然则仔细视察能够发明,有些省份的重心很为难地落在表面,比如甘肃省,由于它是一个异常典范的非凸多边形(凸多边形内部恣意两点间连线都不会穿过其边境),因而计算出来的重心落在了外部,幸亏geopandas
为我们供应了representative_point()
要领,用于求出恣意多边形内部的一个典范点:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
hatch='xxxx',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax = china.geometry.representative_point()
.to_crs(albers_proj)
.plot(ax=ax,
facecolor='black')
ax.axis('off') # 移除坐标轴
fig.savefig('图12.png', dpi=300)
图12
这时刻能够发明生成的点相符了我们的需求,下面我们为此基础上,应用marker
调解点数据的款式,参考图13:
图13
比如我们将marker
修正为'*'
,并调解相干的其他参数使得点看起来越发显著,
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
hatch='xxxx',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax = china.geometry.representative_point()
.to_crs(albers_proj)
.plot(ax=ax,
facecolor='white',
edgecolor='black',
marker='*',
markersize=200,
linewidth=0.5)
ax.axis('off') # 移除坐标轴
fig.savefig('图14.png', dpi=300)
图14
- Step6:图例与笔墨标注
接下来我们来进修如作甚舆图增添图例和笔墨标注,为了看着清晰我们移除暗影添补并降低点的大小,然后为九段线与点数据增添参数label
,末了应用ax.legend()
增添图例并设置响应参数:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4,
label='南海九段线')
ax = china.geometry.representative_point()
.to_crs(albers_proj)
.plot(ax=ax,
facecolor='white',
edgecolor='black',
marker='*',
markersize=100,
linewidth=0.5,
label='省级单元')
# 零丁提早设置图例标题大小
plt.rcParams['legend.title_fontsize'] = 14
# 设置图例标题,位置,分列体式格局,是不是带有暗影
ax.legend(title="图例", loc='lower left', ncol=1, shadow=True)
ax.axis('off') # 移除坐标轴
fig.savefig('图15.png', dpi=300)
图15
接下来我们把标记每一个省级单元的星星换成称号笔墨,这里应用到matplolib
中的text()
要领,其以此传入对应轮回到的点的x、y、笔墨内容,ha
与va
用于调解笔墨水平和竖直对齐体式格局,size
调解笔墨大小,更细致的参数能够去matplotlib
官网搜刮检察,本文不做重点引见:
fig, ax = plt.subplots(figsize=(12, 8))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4,
label='南海九段线')
# 根据转换过投影的代表点,轮回增添笔墨至舆图上对应位置
for idx, _ in enumerate(china.geometry.representative_point().to_crs(albers_proj)):
# 提取省级单元简称
if ('自' in china.loc[idx, 'OWNER'] or '特' in china.loc[idx, 'OWNER'])
and china.loc[idx, 'OWNER'] != '内蒙古自治区':
region = china.loc[idx, 'OWNER'][:2]
else:
region = china.loc[idx, 'OWNER'].replace('省', '')
.replace('市', '')
.replace('自治区', '')
ax.text(_.x, _.y, region, ha="center", va="center", size=6)
# 零丁提早设置图例标题大小
plt.rcParams['legend.title_fontsize'] = 14
# 设置图例标题,位置,分列体式格局,是不是带有暗影
ax.legend(title="图例", loc='lower left', ncol=1, shadow=True)
ax.axis('off') # 移除坐标轴
fig.savefig('图16.png', dpi=300)
图16
- Step7:增添小舆图
人人日常平凡假如留领悟记得,我们平常看到的中国舆图其南海区域都是零丁在右下角的小舆图里显现出来的,在geopandas
里制造这类舆图异常简朴,我们只须要连系matplotlib
中增添子图区域的add_axes()
,即可完成制造,先来认识一下add_axes()
的功用,它最重要的参数是rect
,经由历程传入形如(bottom, left, width, height)
来实如今图床中拓荒子区域,让我们从下面简朴的例子动身好好邃晓,起首我们应用plt.figure()
建立一个方形画布,并在画布上应用add_axes((0, 0, 1, 1))
:
图17
发明道理了吗?我们传入的(0, 0, 1, 1)
,其前两位实在代表着子图区域左下角坐标在全部画布中的比例坐标!然后两位则代表则代表着子图区域的相干于全部画布的比例宽度与长度!接着我们再为fig
拓荒新的子区域,并在新拓荒的子区域正中间写上笔墨:
图18
新的子图区域左下角坐标位于画布的底边中点,比例长宽均为0.5,所以获得了如图所示的效果,搞邃晓了这些以后,下面我们就能够来画带小舆图的中国舆图啦:
起首我们须要离别对中国舆图以及南海插图的经纬度局限举行限制,由于并没有找到严厉的局限划定,所以这里我们大抵定义一下中国舆图和南海插图的最小最大经纬度,生成GeoDataFrame
并增添矢量信息,末了举行适宜的投影转换:
from shapely.geometry import Point
bound = gpd.GeoDataFrame({
'x': [80, 150, 106.5, 123],
'y': [15, 50, 2.8, 24.5]
})
# 增添矢量列
bound.geometry = bound.apply(lambda row: Point([row['x'], row['y']]), axis=1)
# 初始化CRS
bound.crs = 'EPSG:4326'
# 再投影
bound.to_crs(albers_proj, inplace=True)
bound
图19
接下来的步骤就一览无余了,只须要把前文绘制舆图部份的手段离别移植到两个子图上即可:
fig = plt.figure(figsize=(8, 8))
# 建立掩盖全部画布的子图1
ax = fig.add_axes((0, 0, 1, 1))
ax = china.geometry.to_crs(albers_proj).plot(ax=ax,
facecolor='grey',
edgecolor='white',
linestyle='--',
alpha=0.8)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4,
label='南海九段线')
# 零丁提早设置图例标题大小
plt.rcParams['legend.title_fontsize'] = 14
# 设置图例标题,位置,分列体式格局,是不是带有暗影
ax.legend(title="图例", loc='lower left', ncol=1, shadow=True)
ax.axis('off') # 移除坐标轴
ax.set_xlim(bound.geometry[0].x, bound.geometry[1].x)
ax.set_ylim(bound.geometry[0].y, bound.geometry[1].y)
# 建立南海插图对应的子图,这里的位置和大小信息是我调好的,你能够试着调治看看有什么差别
ax_child = fig.add_axes([0.75, 0.15, 0.2, 0.2])
ax_child = china.geometry.to_crs(albers_proj).plot(ax=ax_child,
facecolor='grey',
edgecolor='white',
linestyle='--',
alpha=0.8)
ax_child = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax_child,
edgecolor='grey',
linewidth=3,
alpha=0.4,
label='南海九段线')
ax_child.set_xlim(bound.geometry[2].x, bound.geometry[3].x)
ax_child.set_ylim(bound.geometry[2].y, bound.geometry[3].y)
# 移除子图坐标轴刻度,由于这里的子图须要有边框,所以只移除坐标轴刻度
ax_child.set_xticks([])
ax_child.set_yticks([])
fig.savefig('图20.png', dpi=300)
图20
2.2 GeoDataFrame
引见完了缭绕GeoSeries
睁开的画图要领,下面我们来进修geopandas
中缭绕GeoDataFrame
睁开的可视化要领。
与GeoSeries
比拟,GeoDataFrame
具有多列数据,即我们能够将辅佐列的数值信息映照到舆图的视觉元素上,因而在GeoSeries
经常使用参数的基础上,新增了更多参数:
column:用于指定映照舆图视觉元素的数值信息,能够是对应
GeoDataFrame
的列名,或是直接传入与多少对象一一对应得数值序列,默以为Nonecmap:传入映照视觉元素时的颜色计划,细致应用体式格局下文中会做细致引见
categorical:bool型,True示意指定映照目的列采用离散示意,关于数值型的列有意义,当对应目的列为种别型时自动变成True
legend:bool型,为True时会为舆图增添图例
scheme:str型,用于指定区域散布图分层设色的数值分别计划,下文中会做细致引见
k:int型,用于指定分层设色的色阶数目
vmin:None或float,用于指定分层设色的数值局限下限,默以为None即以对应数据中的最小值为下限
vmax:None或float,用于指定分层设色的数值局限上限,默以为None即以对应数据中的最大值为上限
legend_kwds:字典范,传入与图例相干的个性化参数
classification_kwds:字典范,传入与分层设色相干的个性化参数
missing_kwds:字典范,传入与缺失值处置惩罚相干的个性化参数,用于对缺失值部份的视觉映照做个性化设置
一样的,我们以现实例子动身,这里我们应用新冠肺炎疫情数据,数据泉源: ,一样地你能够在本文开头列出的Github
堆栈中对应本文的途径下找到下文所应用的数据,起首我们先对原数据做一些预处置惩罚,以获得每一个省份最新一次更新纪录的数据:
图21
如许就获得我们所需的数据。
2.2.1 区域散布图与分层设色
区域散布图(Choropleth Map),指的是根据指定属性举行条理分别,并将对应的条理映照到对应多少对象的颜色之上,下面我们先将上面处置惩罚好的表格数据与china
相干联,由于geopandas
支撑pandas
的衔接操纵,所以我们应用pd.merge()
以省级单元称号为键来衔接两张表(由于衔接以后的表格会变成pandas.DataFrame
,所以这里将其转换回GeoDataFrame
):
data_with_geometry = pd.merge(left=temp.replace('澳门', '澳门特别行政区'),
right=china,
left_on='provinceName',
right_on='OWNER',
how='right'
).loc[:, ['provinceName',
'provinceEnglishName',
'province_confirmedCount',
'province_suspectedCount',
'province_curedCount',
'province_deadCount',
'geometry'
]]
# 将数据从DataFrame转换为GeoDataFrame
data_with_geometry = gpd.GeoDataFrame(data_with_geometry, crs='EPSG:4326')
data_with_geometry.head()
图22
有了数据,我们先很“愚昧冒失”地直接将province_confirmedCount
即区域确诊数作为映照值传入参数column
,并挑选cmap
为典范的Reds
赤色渐变配色,以及调解一些前文中我们已很熟悉的参数,看看获得什么样的效果:
图23
为何会获得如许新鲜的效果?让我们一一来剖析一下问题所在:
- 台湾省跑那里去了?
仔细的你肯定会发明,我们的宝岛台湾不见了,这并非我们的多少对象中缺失了它,一个中国一寸地皮都不可缺乏,真正使得它消逝的缘由在于我们的原始数据中实在缺失香港和台湾的数据,我们前面衔接历程应用的右衔接的要领使得我们保留了一切的地皮,然则台湾和香港由于数据缺失,对应数据位置是NaN,因而在数值映照到颜色的历程当中变成了默许的白色,这时刻候missing_kwds
参数就起到大用处了:
fig, ax = plt.subplots(figsize=(12, 12))
# 新增缺失值处置惩罚参数
ax = data_with_geometry.to_crs(albers_proj).plot(ax=ax,
column='province_confirmedCount',
cmap='Reds',
missing_kwds={
"color": "lightgrey",
"edgecolor": "black",
"hatch": "////"
})
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off')
fig.savefig('图24.png', dpi=300)
图24
在字典花样的missing_kwds
参数中,我们用color
设置了缺失值区域的底色,用edgecolor
设置了缺失值区域的线条颜色,而且用hatch
设置了暗影添补款式,如许一来哪些地方缺失数据纪录就一览无余了。
- 为何只要湖北省颜色这么深?
确实,如许的舆图给我们的觉得就是:湖北省很严峻,其他地方没什么区分嘛,我们在图24的基础上加上数值-颜色参考:
fig, ax = plt.subplots(figsize=(12, 12))
ax = data_with_geometry.to_crs(albers_proj).plot(ax=ax,
column='province_confirmedCount',
cmap='Reds',
missing_kwds={
"color": "lightgrey",
"edgecolor": "black",
"hatch": "////"
},
legend=True)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off')
fig.savefig('图25.png', dpi=300)
图25
这下我们搞清晰了,本来是由于湖北省的数据过于大,使得数值在匀称向有序色阶上映照时,除湖北省以外的其他数据都被压缩到异常淡色的区域,这时刻就到了本小结的主题——分层设色,这里就触及到相干的中心参数scheme
以及k
,个中scheme
决议了数据分层的要领,其经由历程挪用第三方包mapclassify
中用于给数据分层的要领),来完成geopandas
中的分层设色,譬以下面我们在图25的基础上,应用我们脍炙人口的天然断点法对应的'NaturalBreaks'
作为参数,挑选分段数目k=5
,来看看会有什么样的效果:
fig, ax = plt.subplots(figsize=(12, 12))
ax = data_with_geometry.to_crs(albers_proj).plot(ax=ax,
column='province_confirmedCount',
cmap='Reds',
missing_kwds={
"color": "lightgrey",
"edgecolor": "black",
"hatch": "////"
},
legend=True,
scheme='NaturalBreaks',
k=5)
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off')
fig.savefig('图26.png', dpi=300)
图26
这时刻能够看到,区域颜色的散布越发温文,也使得我们看出了差别区域在疫情严峻程度上的区分,且由于这时刻变成了离散的分层,所以图例也由比色卡变成更加规范的分类图例,然则这个图例默许在右上角,对舆图形成了较为显著的遮挡,下面我们在图26的基础上,应用参数legend_kwds
,以及missing_kwds
参数下的label
,对其举行美化:
fig, ax = plt.subplots(figsize=(12, 12))
ax = data_with_geometry.to_crs(albers_proj).plot(ax=ax,
column='province_confirmedCount',
cmap='Reds',
missing_kwds={
"color": "lightgrey",
"edgecolor": "black",
"hatch": "////",
"label": "缺失值"
},
legend=True,
scheme='NaturalBreaks',
k=5,
legend_kwds={
'loc': 'lower left',
'title': '确诊数目分级',
'shadow': True
})
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off')
fig.savefig('图27.png', dpi=300)
图27
至此我们的舆图已比最入手下手雅观了许多,再为其增添大标题、小标题和数据申明笔墨,如许一张谈不上悦目但还拼集的疫情舆图便制造终了:
fig, ax = plt.subplots(figsize=(12, 12))
ax = data_with_geometry.to_crs(albers_proj).plot(ax=ax,
column='province_confirmedCount',
cmap='Reds',
missing_kwds={
"color": "lightgrey",
"edgecolor": "black",
"hatch": "////",
"label": "缺失值"
},
legend=True,
scheme='NaturalBreaks',
k=5,
legend_kwds={
'loc': 'lower left',
'title': '确诊数目分级',
'shadow': True
})
ax = nine_lines.geometry.to_crs(albers_proj).plot(ax=ax,
edgecolor='grey',
linewidth=3,
alpha=0.4)
ax.axis('off')
plt.suptitle('新型冠状肺炎累计确诊数目区域散布', fontsize=24) # 增添最高等别标题
plt.title('停止2020年02月27日', fontsize=18) # 增添大标题
plt.tight_layout(pad=4.5) # 调解差别标题之间间距
ax.text(-2800000, 1000000, '* 原始数据泉源:丁香园,n个中台湾及香港数据缺失') # 增添数据申明
fig.savefig('图28.png', dpi=300)
图28
2.2.2 搭配matplotlib完成创作
geopandas
虽然自带了云云雄厚的舆图绘制功用,但许多时刻作图仅仅靠它是不够的,想要完成越发个性化的效果,须要连系matplotlib
中雄厚的功用,以下图是我随便连系matplotlib
中的多少功用完成的个性化可视化,叠加了较多元素,由于篇幅有限,代码不在此放出,你能够去文章开头的Github
堆栈检察本文一切代码,尝试用你喜好的颜色来对舆图调色:
图29
2.2.3 在模拟中进修
成为数据可视化专家不是一件轻易的事,但我们能够先从模拟其他巨匠的优秀作品动身,比如图30来自于Github
堆栈https://github.com/Z3tt/TidyTuesday ,这个堆栈包含了浩瀚基于R
的优秀作品,而图30就是个中之一,对澳洲大火形成的影响举行可视化:
图30
而下面的图31就是我应用geopandas
对图30的大抵模拟,个中字体部份原始的R
剧本中应用ggtext
完成轻易的富文本生成,而Python
中我临时没找到相似功用的轮子,所以这里笔墨部份比较大略:
图31
对应的代码以下,个中应用到的矢量数据是我汇集到的精度较高的世界舆图数据:
world = gpd.read_file('world')
world['SOVEREI']
smoke_list = ['Denmark', 'France', 'Spain', 'Sweden', 'Norway', 'Germany', 'Finland', 'Poland', 'Italy', 'Greenland']
burnt_list = ['Latvia']
fig, ax = plt.subplots(figsize=(8, 8))
crs = '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs'
# 绘制过烟区域
ax = world[world['SOVEREI'].isin(smoke_list)]
.to_crs(crs)
.plot(ax=ax,
facecolor='#d9c09e',
edgecolor='#c49c67',
linewidth=0.2)
# 绘制拉脱维亚
ax = world[world['SOVEREI'].isin(burnt_list)]
.to_crs(crs)
.plot(ax=ax,
facecolor='#c82626',
edgecolor='#9d1e1e',
linewidth=0.2)
# 绘制盈余国度
ax = world[-(world['SOVEREI'].isin(smoke_list) | world['SOVEREI'].isin(burnt_list))]
.to_crs(crs)
.plot(ax=ax,
facecolor='lightgrey',
edgecolor='grey',
linewidth=0.05,
alpha=0.7)
ax.set_xlim([-3200000, 2300000])
ax.set_ylim([4100000, 9000000])
ax.axis('off')
# 增添笔墨
plt.text(-3*10**6, 5.5*10**6,
'''
由2019/20澳洲大火所致使
的灌木丛、丛林以及公园焚
毁面积比拉脱维亚领土还要
大,发生的浓烟也已掩盖
了丹麦全境(包含格陵兰岛
和法罗群岛)岛屿)、法国、
西班牙、瑞典、挪威、德国、
芬兰、波兰和意大利
''',
fontdict={
'color': 'black',
'weight': 'bold',
'size': 13
})
plt.savefig('图31.png', dpi=500)
以上就是本文的全部内容,若有笔误望指出,接下来的文章我将会继承引见更高等的舆图可视化要领,敬请期待!
进阶之路 | 奇妙的IPC之旅