城市设计/数据分析/技术分享/摄影记录

0%

新冠病毒疫情分析学习08-绘制第一张数据地图

本章将利用python图表工具包matplotlib以及空间数据处理工具包geopandas绘制数据地图

准备数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 读取数据
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
# 设置不弹出警告
df = pd.read_excel('*/*/data_ncov.xlsx')

# 时间序列转换
df['date'] = df['date'].astype('str') # 先将字段转化为字符串
df['date'] = pd.to_datetime(df['date']) # 再进行时间序列转换

# 提取2020-2-1日数据
data_0201 = df[df['date'] == '2020-2-1']
data_0201.head()

绘图模块Matplotlib.pyplot & 空间数据处理模块Geopandas

Matplotlib介绍
Matplotlib是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。通过 matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直方图,功率谱,条形图,错误图,散点图等。

我们本章主要使用的是matplotlibpyplot模块,导入方法:

1
import matplotlib.pyplot as plt

Geopandas介绍
GeoPandas是一个开源项目,它的目的是使得在Python下更方便的处理地理空间数据。GeoPandas扩展了pandas的数据类型,允许其在几何类型上进行空间操作。

  • 几何操作由 shapely执行__
  • GeoPandas进一步依赖于 fiona进行文件存取和 descartes ,matplotlib 进行绘图。
    导入方法:
1
import geopandas as gpd

如何读取空间数据?

之前我们读取xlsx的数据,但不包括地理空间信息,我们用pandas读取以后以pandas.DataFrame来存储的

代码如下:

1
2
3
4
5
6
7
8
9
# 导入geopandas工具包读取空间数据"${ohstudy}/nCov/chinadata.json"
import geopandas as gpd
china_spatial = gpd.GeoDataFrame.from_file('*/*/chinadata.json')

# 查看数据基本情况
china_spatial.info()

# 输出数据
china_spatial.head()

知识点

我们通过geopandas.GeoDataFrame.from_file()方法来读取数据,对于空间数据的格式常见的为:

  • .json,本节课用的就是json格式
  • .shapefile,非常常见的空间数据格式,一般GIS类软件产品较长使用
    可以看到数据类型为geopandas.geodataframe.GeoDataFrame,并不是pandas读取后的pandas.DataFrame,但由于geopandas结合了pandasshapely的功能,所以对于表格的处理方法基本和pandas一致。
  • 可以这样理解,GeoDataFrame是向DataFrame增加了地理数据支持的功能
    我们也能发现新的数据字段类型:geometry,该类型字段代表的是空间信息,比如这里的数据其实是我国省级行政区划的面数据,面数据的空间属性为:面中每个节点的经纬度坐标构成

用GeoDataFrame绘制一张地图

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 绘制全国地图
import matplotlib.pyplot as plt
# 设置图表大小
plt.figure(figsize=(15,10))

# 设置图表标题
plt.title('全国地图')

# 绘制空间数据
china_spatial.plot(ax=plt.subplot(1,1,1))

# 设置网格线
plt.grid(True)

输出结果为:


知识点

  • plt.figure(),用于创建1个绘图对象,其中figsize = ()参数用来设置图表大小

  • plt.title(),用于设置图表标题

  • GeoDataFrame.plot(),用于绘制空间图表

    • ax = plt.subplot(横向图表数量,纵向图表数量,第几张表),这个参数使得china_spatial所绘制的图表是在之前创建的绘图对象中,(1,1,1)指该绘图对象的一共只有1张表
  • plt.grid(),用于设置网格线,可选参数


数据合并,绘制疫情地图

现有的空间数据china_spatial只有空间属性并没有疫情相关数据,我们现在需要将data_0201中疫情相关字段匹配进china_spatial中,这里需要用pandas.merge()来操作

  • pandas中的数据匹配是用pandas.merge(),类似于Excel中的Vlookup函数、SQL中的JOIN语句

代码如下:

1
2
3
4
5
6
# 匹配数据
data_china0201 = pd.merge(china_spatial, data_0201, left_on = 'name', right_on = '省市', how = 'left')

# 删除多余字段
del data_china0201['name']
data_china0201.head()

输出结果为:

centerlng centerlat geometry 区域编码 省市 疑似 确诊 死亡 date
0 117.226 31.8257 POLYGON ((119.62594 31.13353, 119.64401 31.114… 340000 安徽省 160 340 0 2020-02-01
1 116.412 40.1844 POLYGON ((117.38359 40.22566, 117.37170 40.216… 110000 北京市 0 183 1 2020-02-01
2 117.981 26.0783 MULTIPOLYGON (((118.25399 24.44654, 118.27072 … 350000 福建省 99 159 0 2020-02-01
3 100.612 37.8776 POLYGON ((104.29087 37.43066, 104.30275 37.415… 620000 甘肃省 20 40 0 2020-02-01
4 108.789 23.8206 MULTIPOLYGON (((107.15419 21.75961, 107.15774 … 450000 广西壮族自治区 319 111 0 2020-02-01

知识点

  • pandas.merge(left, right, how = ,on = ,left_on = ,right_on = )的参数解释:
    +left:第一个DataFrame
    • right:第二个DataFrame
    • how:合并方式
      • inner:默认,取交集
      • outer:取并集,数据缺失范围NaN
      • left:按照left数据为参考合并,数据缺失范围NaN
      • right:按照right数据为参考合并,数据缺失范围NaN
    • on:参考键
    • left_o:当键不为一个列时,单独设置左键
    • right_on:当键不为一个列时,单独设置右键
  • 我们可以看到china_spatial数据的name字段与data_0201数据中省市字段是可以用来匹配的

合并数据后,我们可以用确诊字段来绘制疫情地图,如下:

1
2
3
4
5
6
7
8
9
10
# 绘制疫情地图
# 设置图表大小及标题
plt.figure(figsize=(20,20))
plt.title('2020-2-1 全国确诊病例', fontsize = 20)

# 绘制疫情地图
data_china0201.plot(ax=plt.subplot(1,1,1), alpha=1,edgecolor='k', linewidth = 0.5,
legend=True, scheme = 'FisherJenks', column='确诊', cmap = 'Reds')
# 设置网格线
plt.grid(True,alpha=0.5)

输出结果为:


知识点

  • GeoDataFrame.plot()的参数解释:
  • edgecolor/linewidth/alpha:设置面数据描边颜色、宽度及透明度
    • cmap:设置色系,可选参数:Reds/Reds_r/Blues/Blues_r/…
    • legend:是否显示图例
    • scheme = 'FisherJenks':分类方法,者利用了Jenks自然间断点方法,可以更好地将数据分为多个类,且能使得各类之间差异最大化

数据地图加工,设置文字信息

我们还需要 在地图上增加每个省市的名称,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 绘制疫情地图并添加省市信息
# 设置图表大小及标题
plt.figure(figsize=(20,20))
plt.title('2020-2-1 全国确诊病例', fontsize = 20)

# 绘制疫情地图
data_china0201.plot(ax=plt.subplot(1,1,1), alpha=1,edgecolor='k', linewidth = 0.5,
legend=True, scheme = 'FisherJenks', column='确诊', cmap = 'Reds')
# 设置网格线
plt.grid(True,alpha=0.5)

# 添加省市信息
lst = data_china0201[['省市','centerlng','centerlat','确诊']].to_dict(orient = 'record')
print(lst[:5]) # 查看输出结果

for i in lst:
plt.text(i['centerlng'], i['centerlat'], i['省市'] +':' + str(i['确诊']))

输出结果如下:


知识点

  • matplotlib.pyplot.text(x,y,value)的参数解释:
    • x:文字x值,这里是省市行政区域中心点坐标 - 经度
    • y:文字y值,这里是省市行政区域中心点坐标 - 纬度
    • value:文字内容,这里显示”省市名称” + “确诊病例数量”

快来试一下吧!

吃颗糖
  • 本文作者: Erek
  • 本文链接: https://erek.top/2020/008-xg/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!