知乎上有人問如何實現精細化地圖?現有的excel、tableau、powerbi都只能套用有限的模板,是否有工具能實現高度定製化?
除了專業的Gis軟件外,我能想到相對完美的就是使用Python來實現。
如果想製作出版級的地圖可視化圖表,且處理大數據集,推薦使用matplotlib+cartopy+geopandas的組合,從GIS數據處理、到Geo、Map地圖繪製,到可視化圖片展示生成,它們都能完美解決。
matplotlib、cartopy、geopandas都是python的第三方工具庫,在可視化領域非常強大,下面一一介紹。
matplotlib是python圖表可視化的基礎庫,相信很多人都熟悉。它能創建靜態、動態、交互式圖表,支持自定義所有圖表元素,且對地圖製作非常友好。
cartopy是基於matplotlib接口的專業地理空間可視化庫,它利用PROJ、Numpy和Shapely庫,可以繪製出版級的地理圖表。
geopandas是在pandas數據類型上構建出來的地理空間數據處理分析庫,能對shapefile、geojson數據進行處理、分析及可視化。
總的來講,matplotlib用於圖表設計、cartopy用於地圖展示、geopandas用於gis數據處理,搭配起來使用幾乎可以媲美專業的gis軟件。
而且它們可定製性極強,你幾乎自行可以設計所有的地圖細節,這是tableau,finereport,excel所無法實現的。
因爲是基於python生態的地圖工具,處理大數據集不在話下,哪怕GB、TB級別的數據,也可以通過合適的數據處理手段來生成地圖。
cartopy繪圖
用 Cartopy 畫地圖的基本流程並不複雜:
- 創建畫布。
- 通過指定 projection 參數,創建 GeoAxes 對象。
- 調用 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主要用來處理地理空間數據,也可以通過matplotlib接口來展示地圖。
當然它也是依賴shapely、fiona、pyproj等衆多地理空間庫來進行數據分析、處理的,數據形態類似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處理地理空間數據也是現在的趨勢,學會將有很大幫助。