【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