【Python数据可视化】使用geoplotlib绘制地理空间数据(1)


1、简介

  Geoplotlib 是地理空间数据可视化的开源Python库,包含了大量的地理空间可视化操作,并且支持硬件加速。

本文是整理《Python数据可视化》一书而来,书中的源码地址:https://github.com/TrainingByPackt/Data-Visualization-with-Python,文中出现的数据资源也可也从中寻找并下载。源码中有ipynb文件,方便大家学习!

2、环境基础

  运行环境为python3,我们需要提前安装数据处理相关的Python库。

1、pandas

2、numpy

3、Geoplotlib(pip install geoplotlib)

3、两个例子

  本文将介绍四种数据呈现方法:dot(画点)、hist(二维直方图)、voronoi(维诺图)、delaunay(三角剖分)

  dot方法没什么说的,就是把每个数据 映射成地图上的一个点

  hist方法可以用 方块的颜色深浅 反应数据的分布情况。

  voronio方法类似。

  delaunay方法通过 三角形的大小与密度 反应数据的分布情况。

  我们这里通过两个例子讲述这四种呈现方式。

exp1:显示盗猎时间的Voronio可视化结果

  使用pandas的read方法读取csv,当你输入点之后发现有read_excel等方法,以后读取数据都可以使用pandas的方法。返回一个数据对象。

  使用dot方法将数据映射到地图上:

import pandas as pd
import geoplotlib as gpl
from geoplotlib.utils import DataAccessObject
import os
pd_dataset=pd.read_csv('poaching_points_cleaned.csv')

#地图资源链接如下:
#https://github.com/TrainingByPackt/Data-Visualization-with-Python/blob/master/Lesson05/Exercise06/data/poaching_points_cleaned.csv
#放到当前目录下就行了,如果有路径问题用cd改一下终端的地址
dataset
=DataAccessObject(pd_dataset)#新建DataAccessObject对象用于存储数据集 print(pd_dataset.head())#打印前五行信息 #lat lon为经纬度信息 #通过画点的方式将目标信息绘制出来(在大地图上) gpl.dot(dataset) gpl.show() #如果没有前面那些操作,则geoplotlib.show结果为一张世界地图

 

  可以对这些数据进行进一步可视化操作,这里使用 hist方法 可以呈现大致的热力图,颜色越深表示数据越密集。

gpl.dot(dataset)
gpl.hist(dataset,binsize=20)
gpl.show()

 

 

exp2:人口密度可视化

  先输出基本信息。

  注意到这里dataset直接用pandas的read方法获取,没有使用DataAccessObject方法转换。

  pandas的这种数据格式可以很快的处理数据,使用groupby()方法可以获取纵列数据,注意该方法的参数是['City']而非'City',虽然结果一样,但是不加中括号会慢很多,groupby('City')需要遍历所有数据,而groupby(['City'])直接获取纵列信息。groupby()方法返回的是DataFrameGroupBy结构,包含这组数据的相关信息。

  另外最后输出前20个国家的统计信息时使用dataset.groupby(['Country']).size().head(20)。先用size()方法统计纵列信息,倘若不加size()方法,则只会结果为打印所有原数据,后面加了head(20)也没有用。

  在输出每个国家的平均城市数量时,size().agg('mean')与size().mean()方法等价。

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
'''读取人口信息'''
dataset=pd.read_csv(r'world_cities_pop.csv', dtype={'Region': np.str})
#地图资源链接如下:
#https://github.com/TrainingByPackt/Data-Visualization-with-Python/blob/master/Lesson05/Activity27/data/world_cities.zip
print(dataset.dtypes)
print(dataset.head())
​
'''输出人口的基本信息'''
print('len of data:',len(dataset))
#print('len of City:',len(dataset.groupby(['City'])))
#len of City比较大,计算时间比较长,自己跑的时候调了半天原来卡在这里
print('len of Country:',len(dataset.groupby(['Country'])))
​
'''输出每个国家的平均城市数量'''
CountryInfo=dataset.groupby(['Country'])
print(CountryInfo.size().head(5))
print(CountryInfo.size().agg('mean'))
print(CountryInfo.size().mean())
#后两个方法等价

 

  接下来我们将人口信息绘制到地图上

  在绘制之前还有一个步骤就是修改一下原数据的标签,因为geoplotlib通过纵列的标签索引进行相关操作的,因此要把原数据的Latitude名字改为Lat,Longitude改为lon,分别对应经纬度信息。

dataset['lat'] = dataset['Latitude']
dataset['lon'] = dataset['Longitude']
gpl.dot(dataset)
gpl.show()

  绘制完我们可以发现图像比较粗糙,点都聚集在一起,因此需要对人口数据选择性处理。

  首先就是只选择人口数大于0的部分,也就是参与统计的数据,避免无效数据的干扰。

  随后选择只绘制人口数大于10万的城市,图像一下清晰多了。

#有效信息,统计到人口信息的城市/国家才参与后续计算
dataset_with_pop = dataset[(dataset['Population'] > 0)]
print('Original data:', len(dataset))
print('Data with useful information', len(dataset_with_pop))
​
dataset_100k = dataset_with_pop[(dataset_with_pop['Population'] >= 100_000)]
#注意到数字是这种表达方式
print('The number of Cities with over 100,000 population:',len(dataset_100k))
#超过10万的人口的城市个数
​
gpl.dot(dataset_100k)
gpl.set_bbox(BoundingBox.WORLD)
​
gpl.show()

  将这些数据进行voronio处理,以热力图的形式呈现。这里建议alpha值不要设置成255,不然只有黑黑红红的一片而没有呈现在地图上。

gpl.voronoi(dataset_100k, cmap='hot_r', max_area=1e3, alpha=125)
gpl.show()

 

Ps:cmap可以改颜色的噢,颜色列表:

'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens',
'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r',
'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r',
'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r',
'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'winter', 'winter_r'

  可以把前面的gpl.dot(dataset_100k)注释掉看看,这样地图上不会化小红点点,可能好看一些()

 

  对数据的密度还有一种呈现方式就是delaunay方法,可以用三角网格的方式表现数据。

  这里我们选择中国的数据进行处理。如果想同时包含多个地区,可以用''|''运算符进行添加,比如dataset_europe = dataset_100k[(dataset_100k['Country'] == 'de') | (dataset_100k['Country'] == 'gb')](选择德国与英国的数据)

#选取中国的数据
dataset_china = dataset_100k[(dataset_100k['Country'] == 'cn')]
print('Cities in China with over 100,000 population:', len(dataset_china))
​
gpl.dot(dataset_china)
gpl.delaunay(dataset_china, cmap='Wistia')
#这个颜色好看!!
gpl.show()

  网格越密集,则人口密度越大。可以发现中国的大人口城市主要集中在东部地区。

 

4、结语

  啊啊啊啊第一次写博客好紧张,最近会把可视化方面的资料整理出来,趁暑假比较闲尽量日更()。

  如有疑问和意见,欢迎留言!萌新会马不停蹄去查资料的!

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM