matplotlib+cartopy+geopandas,實現專業地圖可視化

知乎上有人問如何實現精細化地圖?現有的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 畫地圖的基本流程並不複雜:

  1. 創建畫布。
  2. 通過指定 projection 參數,創建 GeoAxes 對象。
  3. 調用 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處理地理空間數據也是現在的趨勢,學會將有很大幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章