当前位置:首页 > 公众号精选 > AI科技大本营
[导读]作者|周萝卜来源|萝卜大杂烩今天来讲一讲在日常工作生活中我常用的几种绘制地图的方法,下面我将介绍下面这些可视化库的地图绘制方法,当然绘制漂亮的可视化地图还有很多优秀的类库,没有办法一一列举。pyecharts、plotly、folium、bokeh、basemap、geopand...


作者 | 周萝卜


来源 | 萝卜大杂烩


今天来讲一讲在日常工作生活中我常用的几种绘制地图的方法,下面我将介绍下面这些可视化库的地图绘制方法,当然绘制漂亮的可视化地图还有很多优秀的类库,没有办法一一列举。
pyecharts、plotly、folium、bokeh、basemap、geopandas、cartopy

Boken

首先我们先介绍 Boken 绘制地图的方法Bokeh 支持创建基本地图可视化和基于处理地理数据的地图可视化画一张世界地图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

# 读入中国地图数据并传给GeoJSONDataSource
with open("china.json", encoding="utf8") as f:
geo_source = GeoJSONDataSource(geojson=f.read())
# 设置一张画布
p = figure(width=500, height=500)
# 使用patches函数以及geo_source绘制地图
p.patches(xs='xs', ys='ys', source=geo_source)
show(p)


我们通过 GEO 地理数据来绘制地图同样非常方便,但是地图看起来有一些单调,我们把不同的省份绘制成不同的颜色来看看with open("china.json", encoding="utf8") as f:
data = json.loads(f.read())
# 判断是不是  北京地区数据
def isBeijing(district):
if 'beijing' in district['properties']['woe-name'].lower():
return True
return False
# data['features'] = list(filter(isInLondon, data['features']))
# 过滤数据
# 为每一个地区增加一个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"对应每个地区的color属性
source=geo_source)
p.axis.axis_label = None
p.axis.visible = False
p.grid.grid_line_color = None

show(p)


可以看到已经有内味了,唯一美中不足的就是南海的十三段线没有展示出来

geopandas

GeoPandas 是基于 Pandas 的地图可视化工具,其数据结构完全继承自 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 官网上的经典图片,可以看到非常简单,除去 import 代码,仅仅三行,就完成了地图的绘制下面我们继续绘制中国地图,这次我们加上九段线信息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 数据,里面的 number 字段是随机生成的测试数据,效果与 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 来绘制
下面我们继续绘制中国地图,使用一个高级 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="地区",
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 随之转正,下面我们主要介绍 Cartopy 工具Cartopy 利用了强大的 PROJ.4、NumPy 和 Shapely 库,并在 Matplotlib 之上构建了一个编程接口,用于创建发布高质量的地图先来绘制一个世界地图%matplotlib inline
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

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

plt.show()


这是一个 cartopy 绘制的非常经典且常见的世界地图,形式比较简单,下面我们增强该地图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()


我们通过上面的代码,绘制了当前时间世界昼夜图,还是很强的下面我们继续绘制中国地图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
#从文件中加载中国区域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 生态系统的数据应用能力和 Leaflet.js 库的映射能力之上的高级地图绘制工具,通过 Python 操作数据,然后在 Leaflet 地图中可视化,可以灵活的自定义绘制区域,并且展现形式更加多样化首先是三行代码绘制世界地图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=["地区", "确诊"],
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


作为专业地图工具,不仅渲染速度快,自定义程度也是非常高的,值得使用尝试

PyEcharts

最后我们介绍 PyEcharts,这款国产的精良可视化工具 绘制世界地图from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker


c = (
Map()
.add("测试数据", [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("测试数据", [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()


我们只需要把参数替换成 ”china“ 就可方便的绘制中国地图,真的很给力,当然对于 Pyecharts 还有很多种玩法,就不一一介绍了综合上面的示例,我们可以看出, Pyecharts 绘制地图最为简单,非常适合新手学习使用;而 foliumcartopy 则胜在自由度上,它们作为专业的地图工具,留给了使用者无限可能;至于 Plotly Bokeh 则属于更高级的可视化工具,它们胜在画质更加优美,API 调用也更加完善今天我们介绍了几种比较常用的绘制地图的类库,每一个工具都有其优缺点,我们只需要在选择的时候,明确目标,用心探索就好!
参考:https://gitee.com/kevinqqnj/cartopy_trial/blob/master/cartopy_province.py
https://zhuanlan.zhihu.com/p/112324234






本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

上海2024年4月17日 /美通社/ -- 每年4月17日是世界血友病日。今年,世界血友病日以"认识出血性疾病,积极预防和治疗"为主题,呼吁关注所有出血性疾病,提升科学认知,提高规范化诊疗水平,让每一位出血性疾病患者享有...

关键字: VII 动力学 软件 BSP

伦敦2024年4月16日 /美通社/ -- ATFX宣布任命Siju Daniel为首席商务官。Siju在金融服务行业拥有丰富的经验和专业知识,曾在全球各地的高管职位上工作了19年以上。Siju之前担任FXCM首席商务官...

关键字: NI AN SI BSP

常州2023年9月25日 /美通社/ -- 9月23日,由江苏省商务厅指导,世界中餐业联合会、常州市人民政府主办的"第三届中华节气菜大会暨首届江南美食节"在江苏常州开幕。文化和旅游部国际交流与合作局一...

关键字: BSP 可持续发展 大赛 质量控制

北京2023年9月25日 /美通社/ -- 9月21日,由中国质量报刊社·中国质量新闻网主办的第六届食品高质量发展交流会在北京举行,会议主题为"高质量,新生活",旨在推动食品行...

关键字: 自动化 BSP ISO9001 NAS

上海2023年9月25日 /美通社/ -- 回顾"中国制造"的崛起之路,我们逐渐从「志造」、「制造」一路走到了「智造」,在如今智能化主导的时代中,制造仍然是有志者们的主战场,硝烟未散。亿个制造强者,才...

关键字: 软件 TOP P10 离散

北京2023年9月23日 /美通社/ -- 近日,主线科技正式获准在北京市智能网联汽车政策先行区道路开启常态化测试与示范,将与物流客户在真实开放的城区道路场景中,率先开启基于L4级别自动驾驶能力的智能卡车运输示范。 随...

关键字: 智能卡 测试 高速公路 BSP

曼谷2023年9月18日 /美通社/ -- 作为东南亚的旅游胜地,泰国一直在全球范围内吸引着无数游客的目光。泰国旅游和体育部近日公布的报告显示,今年前7个月,泰国旅游业总收入约为1.08万亿泰铢(约合人民币2233亿元)...

关键字: BSP GEN 国美 AN

哥伦比卡尔达斯2023年9月22日 /美通社/ -- 近日,天合跟踪与中国电建签订拉美地区哥伦比亚泰普伊光伏电站跟踪支架供货协议,将为其提供108MW智能跟踪系统,其中包含开拓者1P智能跟踪支架、智能算法、以及智慧云平台...

关键字: 光伏电站 跟踪系统 控制器 BSP

2型炎症领域新突破 上海2023年9月22日 /美通社/ -- 赛诺菲今天宣布,达必妥®(度普利尤单抗注射液)获得中国国家药品监督管理局(NMPA)批准,用于治疗适合系统治疗的中度至重度结节性痒疹的成...

关键字: PRIME BSP REPORT SAR
关闭