matplotlib+cartopy+geopandas,實現(xiàn)專業(yè)地圖可視化
知乎上有人問如何實現(xiàn)精細化地圖?現(xiàn)有的excel、tableau、powerbi都只能套用有限的模板,是否有工具能實現(xiàn)高度定制化?

除了專業(yè)的Gis軟件外,我能想到相對完美的就是使用Python來實現(xiàn)。
如果想制作出版級的地圖可視化圖表,且處理大數(shù)據(jù)集,推薦使用matplotlib+cartopy+geopandas的組合,從GIS數(shù)據(jù)處理、到Geo、Map地圖繪制,到可視化圖片展示生成,它們都能完美解決。


matplotlib、cartopy、geopandas都是python的第三方工具庫,在可視化領域非常強大,下面一一介紹。
matplotlib是python圖表可視化的基礎庫,相信很多人都熟悉。它能創(chuàng)建靜態(tài)、動態(tài)、交互式圖表,支持自定義所有圖表元素,且對地圖制作非常友好。

cartopy是基于matplotlib接口的專業(yè)地理空間可視化庫,它利用PROJ、Numpy和Shapely庫,可以繪制出版級的地理圖表。

geopandas是在pandas數(shù)據(jù)類型上構建出來的地理空間數(shù)據(jù)處理分析庫,能對shapefile、geojson數(shù)據(jù)進行處理、分析及可視化。

總的來講,matplotlib用于圖表設計、cartopy用于地圖展示、geopandas用于gis數(shù)據(jù)處理,搭配起來使用幾乎可以媲美專業(yè)的gis軟件。
而且它們可定制性極強,你幾乎自行可以設計所有的地圖細節(jié),這是tableau,finereport,excel所無法實現(xiàn)的。
因為是基于python生態(tài)的地圖工具,處理大數(shù)據(jù)集不在話下,哪怕GB、TB級別的數(shù)據(jù),也可以通過合適的數(shù)據(jù)處理手段來生成地圖。
cartopy繪圖
用 Cartopy 畫地圖的基本流程并不復雜:
創(chuàng)建畫布。 通過指定 projection 參數(shù),創(chuàng)建 GeoAxes 對象。 調(diào)用 GeoAxes 的方法畫圖。
比如繪制海岸線:
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import matplotlib.pyplot as plt
def main():
fig = plt.figure(figsize=(8, 10))
# Label axes of a Plate Carree projection with a central longitude of 180:
ax1 = fig.add_subplot(2, 1, 1,
projection=ccrs.PlateCarree(central_longitude=180))
ax1.set_global()
ax1.coastlines()
ax1.set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
ax1.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter(zero_direction_label=True)
lat_formatter = LatitudeFormatter()
ax1.xaxis.set_major_formatter(lon_formatter)
ax1.yaxis.set_major_formatter(lat_formatter)
plt.show()
if __name__ == '__main__':
main()

繪制地圖:
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
def main():
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
ax.set_extent([-20, 60, -40, 45], crs=ccrs.PlateCarree())
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.add_feature(cfeature.LAKES, alpha=0.5)
ax.add_feature(cfeature.RIVERS)
plt.show()
if __name__ == '__main__':
main()

##geopandas繪圖
geopandas主要用來處理地理空間數(shù)據(jù),也可以通過matplotlib接口來展示地圖。
當然它也是依賴shapely、fiona、pyproj等眾多地理空間庫來進行數(shù)據(jù)分析、處理的,數(shù)據(jù)形態(tài)類似pandas的dataframe。
import geopandas as gpd
from matplotlib_scalebar.scalebar import ScaleBar
nybb = gpd.read_file(gpd.datasets.get_path('nybb'))
nybb = nybb.to_crs(32619) # Convert the dataset to a coordinate
# system which uses meters
ax = nybb.plot()
ax.add_artist(ScaleBar(1))

import geopandas
import contextily as cx
df = geopandas.read_file(geopandas.datasets.get_path('nybb'))
ax = df.plot(figsize=(10, 10), alpha=0.5, edgecolor='k')
df.crs
df_wm = df.to_crs(epsg=3857)
ax = df_wm.plot(figsize=(10, 10), alpha=0.5, edgecolor='k')
cx.add_basemap(ax)

你還可以通過folium讀取地圖進行可視化。

小結
matplotlib+cartopy+geopandas的組合非常強大,能解決地理空間大部分的可視化需求。
我想python處理地理空間數(shù)據(jù)也是現(xiàn)在的趨勢,學會將有很大幫助。
加入知識星球【我們談論數(shù)據(jù)科學】
500+小伙伴一起學習!

