
Python 自動化實現地圖可視化Python生態系統中有多個專門用于地圖可視化的庫每個庫都有其獨特的特點和適用場景。以下是幾個最常用的庫及其核心功能pyecharts基于百度ECharts的Python接口支持高度可定制的交互式地圖特別適合中國地區的可視化需求。它能夠生成包含省、市、縣多級行政區劃的精細地圖并支持熱力圖、散點圖、遷徙圖等多種可視化形式。folium基于Leaflet.js構建可以創建交互式網頁地圖支持標記點、熱力圖、路徑繪制等功能。folium的優勢在于其簡潔的API和豐富的插件系統能夠輕松實現復雜的地圖效果。geopandas結合了pandas的數據處理能力和地理空間分析功能特別適合處理Shapefile等地理空間數據格式。它可以與matplotlib無縫集成創建靜態但高度專業的地圖。Cartopy專注于地圖投影和地理空間數據可視化的庫適合科學計算和氣象領域的需求。它支持多種地圖投影方式并能與matplotlib深度集成。Basemap已逐漸被Cartopy取代Matplotlib的擴展用于繪制二維地圖支持多種投影和地理特征繪制。在實際應用中我們可以根據需求選擇合適的庫或組合使用多個庫。例如pyecharts適合快速創建交互式業務報表folium適合構建網頁集成的地圖應用而geopandas和Cartopy則更適合科學研究和專業地理分析。1、 環境準備與安裝要使用pyecharts進行地圖可視化首先需要安裝必要的庫pip install pyecharts pip install echarts-countries-pypkg # 世界地圖 pip install echarts-china-provinces-pypkg # 中國省級地圖 pip install echarts-china-cities-pypkg # 中國市級地圖 pip install echarts-china-counties-pypkg # 中國區縣級地圖 pip install echarts-china-misc-pypkg # 中國區域地圖 pip install folium2、 pyecharts是目前Python生態中最流行的地圖可視化工具之一內置了中國各級行政區劃地圖無需額外配置即可使用。提供三種主要的地圖類型Map行政區域地圖、Geo地理坐標地圖和Bmap百度地圖。首先來看最基本的Map類型的使用。2.1 基礎地圖繪制假設有一份中國各省市人口數據文件population_2023.xlsx可以使用以下代碼創建可視化地圖import pandas as pd from pyecharts.charts import Map from pyecharts import options as opts # 讀取數據 data pd.read_excel(population_2023.xlsx) province list(data[省份]) population list(data[人口(萬人)]) data_pair [list(z) for z in zip(province, population)] # 創建地圖 map_chart ( Map(init_optsopts.InitOpts(width1000px, height600px)) .add(Population, data_pair, china) .set_global_opts( title_optsopts.TitleOpts(title2023年各省人口分布圖 單位:萬人), visualmap_optsopts.VisualMapOpts(max_110000, is_piecewiseTrue) ) ) map_chart.render(china_population_map.html)這段代碼會生成一個交互式的中國地圖各省份根據population大小顯示不同顏色顏色深淺表示數值大小。2.2 高級定制與主題切換pyecharts提供了豐富的定制選項可以調整地圖的視覺效果以滿足不同需求。分段型視覺映射將連續的數據分成幾個區間每個區間顯示不同顏色。visualmap_optsopts.VisualMapOpts( min_1000, max_110000, range_text[人口(萬人)顏色區間:, ], is_piecewiseTrue, # 分段顯示 pos_topmiddle, pos_leftleft, orientvertical, split_number10 # 分成10個區間 )主題切換pyecharts內置了十余種主題可以輕松改變地圖的整體風格。from pyecharts.globals import ThemeType map_chart Map(init_optsopts.InitOpts( width1000px, height600px, themeThemeType.DARK # 使用暗黑主題 ))pyecharts支持的主題包括WHITE默認、LIGHT、DARK、CHALK、ESSOS、INFOGRAPHIC、MACARONS、PURPLE_PASSION、ROMA、ROMANTIC、SHINE、VINTAGE、WALDEN等。2.3 Geo地圖與漣漪圖效果除了常規的行政區域地圖pyecharts還提供Geo類型可以基于經緯度坐標繪制地理要素并實現特殊的視覺效果如漣漪圖。from pyecharts.charts import Geo from pyecharts.globals import ChartType geo_chart ( Geo(init_optsopts.InitOpts(width1000px, height600px)) .add_schema(maptypechina) .add( GDP, data_pair, type_ChartType.EFFECT_SCATTER, # 漣漪圖效果 symbol_size10, large_threshold110000, ) .set_series_opts(label_optsopts.LabelOpts(is_showFalse)) .set_global_opts( visualmap_optsopts.VisualMapOpts(max_110000), title_optsopts.TitleOpts(title2019年各省GDP漣漪圖) ) ) geo_chart.render(geo_gdp_map.html)漣漪圖效果會在地圖上的數據點位置產生波紋狀的動畫效果非常適合突出顯示特定位置。2.4 百度地圖集成pyecharts還支持與百度地圖的集成Bmap這需要先到百度地圖開放平臺申請AK訪問密鑰。from pyecharts.charts import BMap bmap ( BMap(init_optsopts.InitOpts(width1000px, height600px)) .add_schema( baidu_akYOUR_BAIDU_MAP_AK, # 替換為你的百度地圖AK center[120.13066322374, 30.240018034923], # 地圖中心點 zoom5 # 縮放級別 ) .add( GDP, data_pair, type_heatmap, # 熱力圖類型 label_optsopts.LabelOpts(formatter{b}) ) .set_global_opts( title_optsopts.TitleOpts(title2019年各省GDP熱力圖), visualmap_optsopts.VisualMapOpts(max_110000) ) ) bmap.render(bmap_gdp_heatmap.html)百度地圖集成提供了真實的地理底圖適合需要精確定位或與真實地理要素結合的場合。3. folium是一個基于Leaflet.js的Python庫可以創建高度交互式的網頁地圖支持標記、熱力圖、路徑繪制等多種功能。3.1 基礎地圖創建Folium創建地圖非常簡單只需幾行代碼import folium # 創建地圖對象設置中心點和縮放級別 m folium.Map(location[39.9042, 116.4074], zoom_start12) # 北京坐標 # 保存為HTML文件 m.save(my_map.html)這段代碼會創建一個以北京為中心的地圖縮放級別為12適合查看城市級別的細節。3.2 添加標記點地圖上的標記點是最基本也是最常用的元素之一# 添加普通標記 folium.Marker( location[39.9042, 116.4074], popup北京市, iconfolium.Icon(colorred, iconinfo-sign) ).add_to(m) # 添加圓形標記 folium.Circle( location[39.9163, 116.3903], radius500, # 單位是米 colorblue, fillTrue, fill_opacity0.6, popup故宮博物院 ).add_to(m) m.save(map_with_markers.html)popup參數設置了點擊標記時顯示的文本icon可以改變標記的樣式和顏色。圓形標記適合表示區域范圍。3.3 繪制線條與多邊形對于路線或區域的可視化可以使用線條和多邊形# 創建新地圖 m2 folium.Map(location[39.9042, 116.4074], zoom_start12) # 繪制線條如步行路線 route [ [39.9042, 116.4074], # 起點 [39.9163, 116.3903], # 故宮 [39.9999, 116.3264] # 頤和園 ] folium.PolyLine( route, colorgreen, weight5, opacity0.8, tooltip北京一日游路線 ).add_to(m2) # 繪制多邊形如景區范圍 park_area [ [39.9999, 116.3264], [40.0050, 116.3300], [40.0080, 116.3200], [39.9999, 116.3264] # 最后一點要與第一點相同形成閉合 ] folium.Polygon( park_area, colororange, fillTrue, fill_coloryellow, fill_opacity0.4, popup頤和園區域 ).add_to(m2) m2.save(map_with_lines.html)注意繪制多邊形時最后一個點必須與第一個點相同才能形成閉合區域。3.4 熱力圖實現熱力圖非常適合展示數據的密集程度比如人口分布、犯罪熱點等from folium.plugins import HeatMap import numpy as np # 生成一些隨機數據點緯度經度強度 data ( np.random.normal(size(100, 3)) * np.array([[0.1, 0.1, 1]]) np.array([[39.90, 116.40, 1]]) ).tolist() m3 folium.Map(location[39.9042, 116.4074], zoom_start12) HeatMap(data, radius15).add_to(m3) # radius控制熱力點的半徑大小 m3.save(heatmap.html)熱力圖的數據格式是[緯度, 經度, 權重]權重表示熱點的強度值越大顏色越深。3.5 圖層控制與多底圖切換folium支持添加多個圖層并讓用戶自由切換m4 folium.Map(location[39.9042, 116.4074], zoom_start12) # 添加兩個不同的底圖圖層 folium.TileLayer(OpenStreetMap).add_to(m4) # 默認街道圖 folium.TileLayer(Stamen Terrain).add_to(m4) # 地形圖 # 添加標記 folium.Marker([39.9042, 116.4074], popup天安門).add_to(m4) folium.Marker([39.9163, 116.3903], popup故宮).add_to(m4) # 添加圖層控制 folium.LayerControl().add_to(m4) m4.save(map_with_layers.html)這樣用戶就可以在地圖右下角切換不同的底圖樣式了。3.6 標記聚合(MarkerCluster)當有大量標記時使用標記聚合可以提高性能from folium.plugins import MarkerCluster m folium.Map(location[39.9042, 116.4074]) # 創建MarkerCluster對象 marker_cluster MarkerCluster().add_to(m) # 添加多個標記到MarkerCluster folium.Marker([39.9042, -74.0060], popup紐約市).add_to(marker_cluster) folium.Marker([40.730610, -73.935242], popup布魯克林).add_to(marker_cluster) folium.Marker([40.650002, -73.949997], popup皇后區).add_to(marker_cluster) m.save(cluster_map.html)當地圖縮放時標記會自動聚合提高可讀性和性能。3.7 結合Pandas進行數據可視化folium可以很好地與Pandas配合實現基于數據的地圖可視化import pandas as pd # 假設我們有一個包含城市數據的DataFrame data { city: [北京, 上海, 廣州, 深圳], lat: [39.9042, 31.2304, 23.1291, 22.5431], lon: [116.4074, 121.4737, 113.2644, 114.0579], population: [2171, 2424, 1530, 1303] # 單位萬 } df pd.DataFrame(data) m5 folium.Map(location[35, 110], zoom_start5) # 為每個城市添加標記大小與人口成正比 for _, row in df.iterrows(): folium.CircleMarker( location[row[lat], row[lon]], radiusrow[population]/300, # 按比例縮放 popupf{row[city]}人口{row[population]}萬, colorblue, fillTrue ).add_to(m5) m5.save(china_cities.html)這個例子展示了如何將數據分析與地圖可視化結合圓圈大小直觀反映了城市人口規模。3.8 在Web應用中使用Folium地圖可以輕松嵌入到Flask等Web框架中from flask import Flask import folium app Flask(__name__) app.route(/) def show_map(): m folium.Map(location[39.9042, 116.4074]) # 地圖對象直接轉HTML return m._repr_html_() if __name__ __main__: app.run(debugTrue)在HTML模板中可以使用iframe嵌入地圖iframe stylewidth:100%; height:500px; src{{ url_for(show_map) }}/iframe4、geopandas與Cartopy專業地圖繪制對于需要更專業地理空間分析的應用場景geopandas和Cartopy提供了更強大的功能。4.1 geopandas基礎應用geopandas結合了pandas的數據處理能力和地理空間分析功能可以處理Shapefile等地理空間數據格式。安裝geopandaspip install geopandas使用geopandas讀取地理空間數據并繪制基礎地圖import geopandas as gpd # 讀取地理空間數據Shapefile格式 gdf gpd.read_file(path_to_shapefile.shp) # 創建基礎地圖 m folium.Map( location[gdf.geometry.y.mean(), gdf.geometry.x.mean()], zoom_start12 ) # 添加地理數據 folium.GeoJson(gdf).add_to(m) # 保存地圖 m.save(geopandas_map.html)geopandas特別適合處理行政區劃邊界、土地利用類型等面狀地理數據。4.2 Cartopy地圖投影與專業可視化Cartopy是一個專注于地圖投影和地理空間數據可視化的庫特別適合科學計算和氣象領域的需求。安裝Cartopypip install cartopy使用Cartopy創建帶有專業投影的世界地圖import cartopy.crs as ccrs import matplotlib.pyplot as plt # 創建圖形和坐標軸指定投影類型 fig plt.figure(figsize(10, 5)) ax fig.add_subplot(1, 1, 1, projectionccrs.PlateCarree()) # 添加海岸線和國家邊界 ax.add_feature(ccrs.cfeature.COASTLINE) ax.add_feature(ccrs.cfeature.BORDERS, linestyle:) # 添加底圖 ax.stock_img() plt.show()Cartopy支持多種地圖投影如PlateCarree等距圓柱投影、Mercator墨卡托投影、Orthographic正射投影等。4.3 結合Cartopy和matplotlib繪制專業地圖Cartopy與matplotlib深度集成可以創建高度定制化的專業地圖import cartopy.feature as cfeature # 創建圖形和坐標軸使用蘭伯特投影 ax fig.add_subplot(1, 1, 1, projectionccrs.LambertConformal()) # 添加地理特征 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, alpha0.5) ax.add_feature(cfeature.RIVERS) # 設置地圖范圍中國區域 ax.set_extent([70, 140, 15, 55], crsccrs.PlateCarree()) # 添加網格線 ax.gridlines() plt.title(專業地圖示例) plt.show()這種組合特別適合需要精確控制地圖要素和投影的科學可視化需求。實際應用案例1. 城市景點分布可視化import pandas as pd import folium from folium import plugins # 讀取景點數據 data pd.read_csv(poi_scenic_spot.csv, encodingutf-8) # 創建地圖 plotmap folium.Map(location[data[lat].mean(), data[lon].mean()], zoom_start12, control_scaleTrue) # 添加標記聚合 marker_cluster plugins.MarkerCluster().add_to(plotmap) for index, row in data.iterrows(): folium.Marker( [row[lat], row[lon]], popuprow[name] ).add_to(marker_cluster) plotmap.save(scenic_spots.html)2. 車流量可視化import folium # 示例數據經度, 緯度, 區域名稱, 車流量值 data [ [116.4, 39.9, 區域A, 50], [116.41, 39.91, 區域B, 30], [116.42, 39.92, 區域C, 70] ] m folium.Map(location[39.9, 116.4], zoom_start10) # 在地圖上添加散點圖圖層 for lon, lat, name, value in data: folium.CircleMarker( [lat, lon], radiusvalue * 2, # 散點大小與車流量成正比 popupf{name}: {value}, # 顯示懸浮框信息 fillTrue, fill_color#3186cc, fill_opacity0.5, colorgray, ).add_to(m) m.save(car_flow_map.html)3. 全國銷售數據可視化假設我們有一份全國各城市的銷售數據可以使用pyecharts創建交互式銷售分布圖from pyecharts.charts import Map from pyecharts import options as opts sales_data [ (北京, 356), (上海, 412), (廣州, 278), (深圳, 385), (成都, 192), (重慶, 156), (武漢, 231), (杭州, 298) ] map_chart ( Map() .add(銷售額, sales_data, china) .set_global_opts( title_optsopts.TitleOpts(title全國銷售分布圖), visualmap_optsopts.VisualMapOpts( max_500, is_piecewiseTrue, pieces[ {min: 300, label: 300-500, color: #c23531}, {min: 200, max: 300, label: 200-300, color: #dd6b66}, {min: 100, max: 200, label: 100-200, color: #f1c47b}, {max: 100, label: 0-100, color: #f8e0a1} ] ) ) ) map_chart.render(sales_map.html)4. 城市房價熱力圖使用folium創建城市房價熱力圖import folium from folium.plugins import HeatMap import pandas as pd import numpy as np # 生成模擬數據 np.random.seed(42) lat 39.9042 np.random.normal(0, 0.1, 100) lon 116.4074 np.random.normal(0, 0.1, 100) price np.random.randint(30000, 150000, 100) data np.column_stack([lat, lon, price]) # 創建熱力圖 m folium.Map(location[39.9042, 116.4074], zoom_start12) HeatMap(data, radius15, gradient{0.4: blue, 0.6: lime, 1: red}).add_to(m) m.save(house_price_heatmap.html)5. 動態時間軸地圖pyecharts的時間軸功能可以展示數據隨時間的變化from pyecharts.charts import Timeline, Map from pyecharts import options as opts import random # 模擬不同年份的數據 def generate_data(year): provinces [北京, 上海, 廣東, 江蘇, 浙江, 山東, 河南] return [(province, random.randint(50, 300)) for province in provinces] # 創建時間軸 timeline Timeline() # 為每個年份創建地圖 for year in range(2018, 2024): data generate_data(year) map_chart ( Map() .add(f{year}年銷售額, data, china) .set_global_opts( title_optsopts.TitleOpts(titlef{year}年全國銷售分布), visualmap_optsopts.VisualMapOpts(max_300) ) ) timeline.add(map_chart, f{year}年) # 配置時間軸播放選項 timeline.add_schema( play_interval1000, # 播放間隔1秒 is_auto_playTrue, # 自動播放 is_loop_playTrue # 循環播放 ) timeline.render(animated_sales_map.html)