用python如何畫出好看的地圖

最近正好在學空間數據處理,這次更一下用python如何畫出好看的地圖

下面主要是用

  • folium

  • poltly

  • geopandas+matplotlib

三種方式繪製地圖
在這裏插入圖片描述

1.folium

import folium
import pandas as pd
#輸入上海經緯度,尺度
latitude = 31.2
longitude = 121.5
sh_map = folium.Map(location=[latitude, longitude], zoom_start=10)
sh_map

在這裏插入圖片描述
默認爲’OpenStreetMap’風格,我們還可以選擇’Stamen Terrain’, 'Stamen Toner’等

sh_map = folium.Map(location=[latitude, longitude], zoom_start=10,tiles='Stamen Toner')
sh_map

在這裏插入圖片描述
有了底圖把帶有經緯度的數據點映射上去,這裏用上次上海poi中的火鍋數據
在這裏插入圖片描述
把火鍋店數據放到地圖上

# 創建特徵組
hotpots = folium.map.FeatureGroup()
# Loop through the 200 crimes and add each to the incidents feature group
for lat, lng, in zip(data.lat, data.lon):
    hotpots.add_child(
        folium.CircleMarker(
            [lat, lng],
            radius=7, # define how big you want the circle markers to be
            color='yellow',
            fill=True,
            fill_color='red',
            fill_opacity=0.4
        )
    )

# 把火鍋特徵組放到上海地圖上
sh_map =folium.Map(location=[latitude, longitude], zoom_start=10)
sh_map.add_child(hotpots)

在這裏插入圖片描述
點太多看不出什麼,我們下面只放嘉定區的數據
在這裏插入圖片描述
我們可以繼續添加火鍋店名字信息並標註在上圖

latitudes = list(datas.lat)
longitudes = list(datas.lon)
labels = list(datas.name)
for lat, lng, label in zip(latitudes, longitudes, labels):
    folium.Marker([lat, lng], popup=label).add_to(sh_map)      
sh_map

在這裏插入圖片描述
最後我們需要繪製每個區的火鍋數量的Choropleth Map,不同顏色代表火鍋數量
首先讀取上海行政區geojson文件
在這裏插入圖片描述
統計各個區火鍋數量

hots=data.groupby('adname',as_index=False).agg({'name':"count"})
hots.columns=['district','num']
hots

在這裏插入圖片描述
開始繪製Choropleth Map, 下面key_on='feature.properties.name’是因爲我們這裏下載的上海geojson中name對應於行政區,這個根據具體數據而定
在這裏插入圖片描述

#輸入上海經緯度,尺度
latitude = 31.2
longitude = 121.5
map = folium.Map(location=[latitude, longitude], zoom_start=12)
folium.Choropleth(
    geo_data=geo_data,
    data=hots,
    columns=['district','num'],
    key_on='feature.properties.name',
    #fill_color='red',
    fill_color='YlOrRd',
    fill_opacity=0.7,
    line_opacity=0.2,
    highlight=True,
    legend_name='Hotpot Counts in Shanghai'
).add_to(map)
map

在這裏插入圖片描述
浦東新區一馬當先,嘉定區榜上有名

2.poltly

用poltly畫Choropleth Map跟folium很類似,這裏直接繼續用前面處理好的數據

import plotly.express as px
import plotly.graph_objs as go
latitude = 31.2
longitude = 121.5
fig = px.choropleth_mapbox(
    data_frame=hots,
    geojson=geo_data,
    color='num',
    locations="district",
    featureidkey="properties.name",
    mapbox_style="carto-positron",
    color_continuous_scale='viridis',
    center={"lat": latitude, "lon": longitude},
    zoom=7.5,
)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()

在這裏插入圖片描述
設置mapbox_style="carto-darkmatter"換一種風格
在這裏插入圖片描述

3.geopandas+matplotlib

先利用geopandas繪製出各行政區輪廓

import matplotlib.pyplot as plt
import matplotlib as mpl
# 中文和負號的正常顯示
mpl.rcParams['font.sans-serif'] = ['Times New Roman']
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
# 裁剪上海shape
fig, ax = plt.subplots(figsize=(20, 10))
ax=geo_data.plot(ax=ax,facecolor='grey',edgecolor='white',linestyle='--',alpha=0.8)
ax.axis('off') # 移除座標軸

在這裏插入圖片描述
將統計的各個區的火鍋店數量與geo_data合併

need_data=pd.merge(geo_data,hots[['district','num']],left_on='name',
                 right_on='district')
need_data

在這裏插入圖片描述
此時數據已經是dataframe,不是需要的geodataframe了,所以需要繼續轉換一下

need_data = gpd.GeoDataFrame(need_data)
need_data.geom_type

在這裏插入圖片描述
可以看到這個時候need_data已經是geodataframe類型了

fig, ax = plt.subplots(figsize=(20, 10))
need_data.plot('num', cmap='OrRd',ax=ax)
ax.axis('off') # 移除座標軸
cmap = mpl.cm.get_cmap('OrRd')
norm = mpl.colors.Normalize(min(need_data['num']), max(need_data['num']))
fcb = fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap),ax=ax)
ax=geo_data.plot(ax=ax,facecolor='grey',edgecolor='white',linestyle='--',alpha=0.2)
ax.set_title('Hotpot Count in Shanghai', fontsize=20)

在這裏插入圖片描述
不熟悉上海的人是看不出來各個區的,這裏可以繼續加行政區標註

fig, ax = plt.subplots(figsize=(20, 10))
need_data.plot('num', cmap='OrRd',ax=ax)
for idx, _ in enumerate(need_data.geometry.representative_point()):
    # 提取行政區名稱
    region = need_data.loc[idx, 'name']
    ax.text(_.x, _.y, region, ha="center", va="center", size=8)
ax.axis('off') # 移除座標軸
cmap = mpl.cm.get_cmap('OrRd')
norm = mpl.colors.Normalize(min(need_data['num']), max(need_data['num']))
fcb = fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap),ax=ax)
ax=geo_data.plot(ax=ax,facecolor='grey',edgecolor='white',linestyle='--',alpha=0.2)
ax.set_title('Hotpot Count in Shanghai', fontsize=20)

在這裏插入圖片描述

本文的notebook及數據可公衆號後臺回覆地圖獲得

在這裏插入圖片描述

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