當前位置:首頁 > 公眾號精選 > AI科技大本營
[導讀]作者|周蘿卜來源|蘿卜大雜燴今天來講一講在日常工作生活中我常用的幾種繪制地圖的方法,下面我將介紹下面這些可視化庫的地圖繪制方法,當然繪制漂亮的可視化地圖還有很多優(yōu)秀的類庫,沒有辦法一一列舉。pyecharts、plotly、folium、bokeh、basemap、geopand...


作者 | 周蘿卜


來源 | 蘿卜大雜燴


今天來講一講在日常工作生活中我常用的幾種繪制地圖的方法,下面我將介紹下面這些可視化庫的地圖繪制方法,當然繪制漂亮的可視化地圖還有很多優(yōu)秀的類庫,沒有辦法一一列舉。
pyecharts、plotly、folium、bokeh、basemap、geopandas、cartopy

Boken

首先我們先介紹 Boken 繪制地圖的方法Bokeh 支持創(chuàng)建基本地圖可視化和基于處理地理數(shù)據(jù)的地圖可視化畫一張世界地圖from bokeh.plotting import figure, show
from bokeh.tile_providers import CARTODBPOSITRON, get_provider
from bokeh.io import output_notebook


output_notebook()
tile_provider = get_provider(CARTODBPOSITRON)

p = figure(x_range=(-2000000, 6000000), y_range=(-1000000, 7000000),
x_axis_type="mercator", y_axis_type="mercator")
p.add_tile(tile_provider)

show(p)


再畫一張中國地圖看看from bokeh.plotting import curdoc, figure
from bokeh.models import GeoJSONDataSource
from bokeh.io import show

# 讀入中國地圖數(shù)據(jù)并傳給GeoJSONDataSource
with open("china.json", encoding="utf8") as f:
geo_source = GeoJSONDataSource(geojson=f.read())
# 設置一張畫布
p = figure(width=500, height=500)
# 使用patches函數(shù)以及geo_source繪制地圖
p.patches(xs='xs', ys='ys', source=geo_source)
show(p)


我們通過 GEO 地理數(shù)據(jù)來繪制地圖同樣非常方便,但是地圖看起來有一些單調(diào),我們把不同的省份繪制成不同的顏色來看看with open("china.json", encoding="utf8") as f:
data = json.loads(f.read())
# 判斷是不是  北京地區(qū)數(shù)據(jù)
def isBeijing(district):
if 'beijing' in district['properties']['woe-name'].lower():
return True
return False
# data['features'] = list(filter(isInLondon, data['features']))
# 過濾數(shù)據(jù)
# 為每一個地區(qū)增加一個color屬性
for i in range(len(data['features'])):
data['features'][i]['properties']['color'] = ['red', 'blue', 'yellow', 'orange', 'gray', 'purple'][i % 6]
data['features'][i]['properties']['number'] = random.randint(0, 20_000)
geo_source = GeoJSONDataSource(geojson=json.dumps(data))
p = figure(width=500, height=500, tooltips="@name, number: @number")
p.patches(xs='xs', ys='ys', fill_alpha=0.7,
line_color='white',
line_width=0.5,
color="color", # 增加顏色屬性,這里的"color"對應每個地區(qū)的color屬性
source=geo_source)
p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None

show(p)


可以看到已經(jīng)有內(nèi)味了,唯一美中不足的就是南海的十三段線沒有展示出來

geopandas

GeoPandas 是基于 Pandas 的地圖可視化工具,其數(shù)據(jù)結(jié)構(gòu)完全繼承自 Pandas,對于熟悉潘大師的同學來說還是非常友好的還是先畫一張世界地圖import pandas as pd
import geopandas
import matplotlib.pyplot as plt
%matplotlib inline

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world.plot()
plt.show()


這也是 geopandas 官網(wǎng)上的經(jīng)典圖片,可以看到非常簡單,除去 import 代碼,僅僅三行,就完成了地圖的繪制下面我們繼續(xù)繪制中國地圖,這次我們加上九段線信息china_nine = geopandas.read_file(r"geojson/九段線GS(2019)1719號.geojson")
china = geopandas.read_file('china-new.json')
fig, ax = plt.subplots(figsize=(12, 8),dpi=80)
ax = china.plot(ax=ax, column='number')
ax = china_nine.plot(ax=ax)
plt.show()


我們復用了前面處理的 china.json 數(shù)據(jù),里面的 number 字段是隨機生成的測試數(shù)據(jù),效果與 Bokeh 不相上下

plotly

接下來我們介紹 plotly,這也是一個非常好用的 Python 可視化工具,如果要繪制地圖信息,我們需要安裝如下依賴!pip install geopandas==0.3.0
!pip install pyshp==1.2.10
!pip install shapely==1.6.3
接下來我們先繪制一個世界地圖import plotly.graph_objects as go

fig = go.Figure(go.Scattermapbox(
mode = "markers lines",
lon = [10, 20, 30],
lat = [10, 20,30],
marker = {'size': 10}))

fig.add_trace(go.Scattermapbox(
mode = "markers lines",
lon = [-50, -60,40],
lat = [30, 10, -20],
marker = {'size': 10}))

fig.update_layout(
margin ={'l':0,'t':0,'b':0,'r':0},
mapbox = {
'center': {'lon': 113.65000, 'lat': 34.76667},
'style': "stamen-terrain",
'center': {'lon': -20, 'lat': -20},
'zoom': 1})

fig.show()
這里我們使用底層 API plotly.graph_objects.Choroplethmapbox 來繪制
下面我們繼續(xù)繪制中國地圖,使用一個高級 API plotly.express.choropleth_mapboximport pandas as pd
import plotly.express as px
import numpy as np
import json

with open(r"china_province.geojson", encoding='utf8') as f:
provinces_map = json.load(f)

df = pd.read_csv(r'data.csv')
df.確診 = df.確診.map(np.log)

fig = px.choropleth_mapbox(
df,
geojson=provinces_map,
color='確診',
locations="地區(qū)",
featureidkey="properties.NL_NAME_1",
mapbox_style="carto-darkmatter",
color_continuous_scale='viridis',
center={"lat": 37.110573, "lon": 106.493924},
zoom=3,
)
fig.show()


可以看出繪制出的交互式地圖還是非常漂亮的,不過渲染速度有些感人,這個就看個人的需求了,如果你對渲染速度有要求,那么 Ployly 可能不是最好的選擇~

Cartopy/Basemap

之所以把這兩個庫放到一起,是因為他們都是基于 Matplotlib 之上的,而隨著 Python2 的不再維護,Basemap 也被 Matplotlib 放棄,Cartopy 隨之轉(zhuǎn)正,下面我們主要介紹 Cartopy 工具Cartopy 利用了強大的 PROJ.4、NumPy 和 Shapely 庫,并在 Matplotlib 之上構(gòu)建了一個編程接口,用于創(chuàng)建發(fā)布高質(zhì)量的地圖先來繪制一個世界地圖%matplotlib inline
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines()

plt.show()


這是一個 cartopy 繪制的非常經(jīng)典且常見的世界地圖,形式比較簡單,下面我們增強該地圖import datetime
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.feature.nightshade import Nightshade


fig = plt.figure(figsize=(10, 5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

date = datetime.datetime(2021, 12, 2, 21)

ax.set_title(f'Night time shading for {date}')
ax.stock_img()
ax.add_feature(Nightshade(date, alpha=0.2))
plt.show()


我們通過上面的代碼,繪制了當前時間世界晝夜圖,還是很強的下面我們繼續(xù)繪制中國地圖import cartopy.io.shapereader as shpreader
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import cartopy.io.shapereader as shapereader
import matplotlib.ticker as mticker
#從文件中加載中國區(qū)域shp
shpfile = shapereader.Reader(r'ne_10m_admin_0_countries_chn\ne_10m_admin_0_countries_chn.shp')
# 設置 figure 大小
fig = plt.figure(figsize=[8, 5.5])
# 設置投影方式并繪制主圖
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.add_geometries(
shpfile.geometries(),
ccrs.PlateCarree())
ax.set_extent([70, 140, 0, 55],crs=ccrs.PlateCarree())
plt.show()


使用 cartopy 繪制地圖最大的特點就是靈活度高,那么相對應的代價就是編寫代碼也會更難一些,比如如果想要給不同省份填充不同顏色,我們需要編寫的代碼就有點多import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import shapely.geometry as sgeom

import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader

font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14)

def sample_data():
#    lons = [110, 115, 120, 122, 124 ]
lons = [124, 122, 120, 115, 110 ]
lats = [33, 32, 28, 30, 28 ]
return lons, lats

#ax = plt.axes([0, 0, 1, 1], projection=ccrs.LambertConformal())
ax = plt.axes(projection=ccrs.PlateCarree())


ax.set_extent([70, 140, 0, 55],crs=ccrs.Geodetic())

shapename = 'admin_1_states_provinces'
states_shp = shpreader.natural_earth(resolution='10m', category='cultural', name=shapename)


lons, lats = sample_data()

# to get the effect of having just the states without a map "background"
# turn off the outline and background patches
ax.background_patch.set_visible(False)
ax.outline_patch.set_visible(False)

plt.title(u'China Province Level', fontproperties=font)

# turn the lons and lats into a shapely LineString
track = sgeom.LineString(zip(lons, lats))

track_buffer = track.buffer(1)

for state in shpreader.Reader(states_shp).geometries():
# pick a default color for the land with a black outline,
# this will change if the storm intersects with our track
facecolor = [0.9375, 0.9375, 0.859375]
edgecolor = 'black'

if state.intersects(track):
facecolor = 'red'
elif state.intersects(track_buffer):
facecolor = '#FF7E00'

ax.add_geometries([state], ccrs.PlateCarree(),
facecolor=facecolor, edgecolor=edgecolor)


# make two proxy artists to add to a legend
direct_hit = mpatches.Rectangle((0, 0), 1, 1, facecolor="red")
within_2_deg = mpatches.Rectangle((0, 0), 1, 1, facecolor="#FF7E00")
labels = [u'省份level1',
'省份level2']
plt.legend([direct_hit, within_2_deg], labels,
loc='lower left', bbox_to_anchor=(0.025, -0.1), fancybox=True, prop=font)
ax.figure.set_size_inches(14, 9)
plt.show()

folium

folium 是建立在 Python 生態(tài)系統(tǒng)的數(shù)據(jù)應用能力和 Leaflet.js 庫的映射能力之上的高級地圖繪制工具,通過 Python 操作數(shù)據(jù),然后在 Leaflet 地圖中可視化,可以靈活的自定義繪制區(qū)域,并且展現(xiàn)形式更加多樣化首先是三行代碼繪制世界地圖import folium


# define the world map
world_map = folium.Map()
# display world map
world_map


接下來繪制中國地圖# 繪制邊界
import json

df = pd.read_csv(r'plotly-choropleth-mapbox-demo-master/data.csv')
# read china border
with open(r"plotly-choropleth-mapbox-demo-master/china_province.geojson", encoding='utf8') as f:
china = json.load(f)

chn_map = folium.Map(location=[40, 100], zoom_start=4)


folium.Choropleth(
geo_data=china,
name="choropleth",
data=df,
columns=["地區(qū)", "確診"],
key_on="properties.NL_NAME_1",
fill_color="YlGn",
fill_opacity=0.7,
line_opacity=0.2,
legend_name="新冠確診",
).add_to(chn_map)

folium.LayerControl().add_to(chn_map)

chn_map


作為專業(yè)地圖工具,不僅渲染速度快,自定義程度也是非常高的,值得使用嘗試

PyEcharts

最后我們介紹 PyEcharts,這款國產(chǎn)的精良可視化工具 繪制世界地圖from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker


c = (
Map()
.add("測試數(shù)據(jù)", [list(z) for z in zip(Faker.country, Faker.values())], "world")
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-世界地圖"),
visualmap_opts=opts.VisualMapOpts(max_=200),
)
)
c.render_notebook()


通過 Pyecharts 繪制地圖的一個好處就是不需要處理 GEO 文件,我們直接出入國家名稱,就可以自動匹配到地圖上,非常方便再繪制中國地圖c = (
Map()
.add("測試數(shù)據(jù)", [list(z) for z in zip(Faker.provinces, Faker.values())], "china")
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-VisualMap(中國)"),
visualmap_opts=opts.VisualMapOpts(max_=200, is_piecewise=True),
)
)
c.render_notebook()


我們只需要把參數(shù)替換成 ”china“ 就可方便的繪制中國地圖,真的很給力,當然對于 Pyecharts 還有很多種玩法,就不一一介紹了綜合上面的示例,我們可以看出, Pyecharts 繪制地圖最為簡單,非常適合新手學習使用;而 foliumcartopy 則勝在自由度上,它們作為專業(yè)的地圖工具,留給了使用者無限可能;至于 Plotly Bokeh 則屬于更高級的可視化工具,它們勝在畫質(zhì)更加優(yōu)美,API 調(diào)用也更加完善今天我們介紹了幾種比較常用的繪制地圖的類庫,每一個工具都有其優(yōu)缺點,我們只需要在選擇的時候,明確目標,用心探索就好!
參考:https://gitee.com/kevinqqnj/cartopy_trial/blob/master/cartopy_province.py
https://zhuanlan.zhihu.com/p/112324234






本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉