知乎上有人問(wèn)如何實(shí)現(xiàn)精細(xì)化地圖,?現(xiàn)有的excel、tableau,、powerbi都只能套用有限的模板,,是否有工具能實(shí)現(xiàn)高度定制化?
除了專業(yè)的Gis軟件外,,我能想到相對(duì)完美的就是使用Python來(lái)實(shí)現(xiàn),。
如果想制作出版級(jí)的地圖可視化圖表,且處理大數(shù)據(jù)集,,推薦使用matplotlib+cartopy+geopandas的組合,,從GIS數(shù)據(jù)處理,、到Geo、Map地圖繪制,,到可視化圖片展示生成,,它們都能完美解決。
matplotlib,、cartopy,、geopandas都是python的第三方工具庫(kù),在可視化領(lǐng)域非常強(qiáng)大,,下面一一介紹,。
matplotlib是python圖表可視化的基礎(chǔ)庫(kù),相信很多人都熟悉,。它能創(chuàng)建靜態(tài),、動(dòng)態(tài)、交互式圖表,,支持自定義所有圖表元素,,且對(duì)地圖制作非常友好。
cartopy是基于matplotlib接口的專業(yè)地理空間可視化庫(kù),,它利用PROJ,、Numpy和Shapely庫(kù),可以繪制出版級(jí)的地理圖表,。
geopandas是在pandas數(shù)據(jù)類型上構(gòu)建出來(lái)的地理空間數(shù)據(jù)處理分析庫(kù),,能對(duì)shapefile、geojson數(shù)據(jù)進(jìn)行處理,、分析及可視化,。
總的來(lái)講,matplotlib用于圖表設(shè)計(jì),、cartopy用于地圖展示,、geopandas用于gis數(shù)據(jù)處理,搭配起來(lái)使用幾乎可以媲美專業(yè)的gis軟件,。
而且它們可定制性極強(qiáng),,你幾乎自行可以設(shè)計(jì)所有的地圖細(xì)節(jié),這是tableau,,finereport,,excel所無(wú)法實(shí)現(xiàn)的。
因?yàn)槭腔趐ython生態(tài)的地圖工具,,處理大數(shù)據(jù)集不在話下,,哪怕GB、TB級(jí)別的數(shù)據(jù),也可以通過(guò)合適的數(shù)據(jù)處理手段來(lái)生成地圖,。
cartopy繪圖
用 Cartopy 畫(huà)地圖的基本流程并不復(fù)雜:
創(chuàng)建畫(huà)布,。
通過(guò)指定 projection 參數(shù),創(chuàng)建 GeoAxes 對(duì)象,。
調(diào)用 GeoAxes 的方法畫(huà)圖,。
比如繪制海岸線:
import cartopy.crs as ccrsfrom cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatterimport matplotlib.pyplot as pltdef 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 ccrsimport cartopy.feature as cfeatureimport matplotlib.pyplot as pltdef 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主要用來(lái)處理地理空間數(shù)據(jù),也可以通過(guò)matplotlib接口來(lái)展示地圖,。
當(dāng)然它也是依賴shapely,、fiona、pyproj等眾多地理空間庫(kù)來(lái)進(jìn)行數(shù)據(jù)分析,、處理的,,數(shù)據(jù)形態(tài)類似pandas的dataframe。
import geopandas as gpdfrom matplotlib_scalebar.scalebar import ScaleBarnybb = gpd.read_file(gpd.datasets.get_path('nybb'))nybb = nybb.to_crs(32619) # Convert the dataset to a coordinate# system which uses metersax = nybb.plot()ax.add_artist(ScaleBar(1))
import geopandasimport contextily as cxdf = geopandas.read_file(geopandas.datasets.get_path('nybb'))ax = df.plot(figsize=(10, 10), alpha=0.5, edgecolor='k')df.crsdf_wm = df.to_crs(epsg=3857)ax = df_wm.plot(figsize=(10, 10), alpha=0.5, edgecolor='k')cx.add_basemap(ax)
你還可以通過(guò)folium讀取地圖進(jìn)行可視化,。
小結(jié)
matplotlib+cartopy+geopandas的組合非常強(qiáng)大,,能解決地理空間大部分的可視化需求。
我想python處理地理空間數(shù)據(jù)也是現(xiàn)在的趨勢(shì),,學(xué)會(huì)將有很大幫助,。
|