聊一聊我常用的6种绘制地图的方法

article/2025/10/11 6:50:55

a45b607bd5233061efd79ddce2910d51.gif

来源:萝卜大杂烩

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

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_notebookoutput_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)

8be2de80623a3607fbc473a20e92745f.png

再画一张中国地图看看

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)

3c997b31d24284ab38557e1319b07c3e.png

我们通过 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 Truereturn 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 = Noneshow(p)

d9268d7b1a733f9d3207328f66871c1c.png

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

geopandas

GeoPandas 是基于 Pandas 的地图可视化工具,其数据结构完全继承自 Pandas,对于熟悉潘大师的同学来说还是非常友好的

还是先画一张世界地图

import pandas as pd
import geopandas
import matplotlib.pyplot as plt
%matplotlib inlineworld = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world.plot()
plt.show()

1bf0842d8a5cf062355561ae8d98469b.png

这也是 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()

d84f2580d41a3caaf4603efc8dad4b58.png

我们复用了前面处理的 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 gofig = 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 来绘制

d7c5c78674a2185dbaa1964a2c3a6c1c.png

下面我们继续绘制中国地图,使用一个高级 API plotly.express.choropleth_mapbox

import pandas as pd
import plotly.express as px
import numpy as np
import jsonwith 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()

5c2b46d91ee6585034331fb799e827e7.png

可以看出绘制出的交互式地图还是非常漂亮的,不过渲染速度有些感人,这个就看个人的需求了,如果你对渲染速度有要求,那么 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 pltax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines()plt.show()

cd0d943db17f53f7054afd7677aeb6a8.png

这是一个 cartopy 绘制的非常经典且常见的世界地图,形式比较简单,下面我们增强该地图

import datetime
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.feature.nightshade import Nightshadefig = 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()

7da73012ae0fc6a8c806e90e70a07855.png

我们通过上面的代码,绘制了当前时间世界昼夜图,还是很强的

下面我们继续绘制中国地图

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()

a1656404f4f58cabee5fd0a6ae4f8f33.png

使用 cartopy 绘制地图最大的特点就是灵活度高,那么相对应的代价就是编写代码也会更难一些,比如如果想要给不同省份填充不同颜色,我们需要编写的代码就有点多

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import shapely.geometry as sgeomimport cartopy.crs as ccrs
import cartopy.io.shapereader as shpreaderfont = 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 trackfacecolor = [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()

e75f4b1236ce27f01601a9080ccd8d2c.png

folium

folium 是建立在 Python 生态系统的数据应用能力和 Leaflet.js 库的映射能力之上的高级地图绘制工具,通过 Python 操作数据,然后在 Leaflet 地图中可视化,可以灵活的自定义绘制区域,并且展现形式更加多样化

首先是三行代码绘制世界地图

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

ef5ec8957f3e66e03ef2dcbf690375be.png

接下来绘制中国地图

# 绘制边界
import jsondf = 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

12ce61b10237703e5bde3690de091593.png

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

PyEcharts

最后我们介绍 PyEcharts,这款国产的精良可视化工具 

绘制世界地图

from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Fakerc = (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()

9d1f9567e8c99b9eefcf7afb8ecadfed.png

通过 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()

f6643a35f30c5eb3e49f240648f5c3bf.png

我们只需要把参数替换成 ”china“ 就可方便的绘制中国地图,真的很给力,当然对于 Pyecharts 还有很多种玩法,就不一一介绍了

6b0f7e0ef1f15b74583174e7e7fc46ab.png

综合上面的示例,我们可以看出, Pyecharts 绘制地图最为简单,非常适合新手学习使用;而 folium 和 cartopy 则胜在自由度上,它们作为专业的地图工具,留给了使用者无限可能;至于 Plotly Bokeh 则属于更高级的可视化工具,它们胜在画质更加优美,API 调用也更加完善

314ba24b5a73c2107bcc2a8c585564d9.png

今天我们介绍了几种比较常用的绘制地图的类库,每一个工具都有其优缺点,我们只需要在选择的时候,明确目标,用心探索就好!

好了,今天就分享到这里,给个“在看”再走吧!

参考:https://gitee.com/kevinqqnj/cartopy_trial/blob/master/cartopy_province.py
https://zhuanlan.zhihu.com/p/112324234

-------- End --------

ef7665ae007e45bbf47feaedc0eaa0d8.png

精选资料

回复关键词,获取对应的资料:

关键词资料名称
600《Python知识手册》
md《Markdown速查表》
time《Python时间使用指南》
str《Python字符串速查表》
pip《Python:Pip速查表》
style《Pandas表格样式配置指南》
mat《Matplotlib入门100个案例》
px《Plotly Express可视化指南》

精选视频

可视化: Plotly Express

财经: Plotly在投资领域的应用 | 绘制K线图表

排序算法: 汇总 | 冒泡排序 | 选择排序 | 快速排序 | 归并排序 | 堆排序 | 插入排序 | 希尔排序 | 计数排序 | 桶排序 | 基数排序

af1456b4d2160dae5c4ea4f2eb3cb9bf.png

http://chatgpt.dhexx.cn/article/3VMPk9QQ.shtml

相关文章

HBase数据库表的创建

实验三 HBase分布式数据库操作与编程 1、HBase Shell数据库表创建 【实验内容】 根据以下关系型数据库表,使用HBase Shell设计并创建适宜的HBase数据表。 2、创建表以及插入学生信息数据 (1)、启动Hadoop (2)、启…

Hbase笔记 —— 利用JavaAPI的方式操作Hbase数据库(往hbase的表中批量插入数据)

目录 直接在main函数中执行语句借助Test来运行方法删除表修改表结构列出来所有的表插入一条数据获取一行数据创建表批量读取文件中的数据&#xff0c;并且批量插入表中获取一组数据的值利用CellUtil改善读取数据方式 导入依赖 <dependency><groupId>org.apache.hba…

Java 访问Hbase数据库

须知 Hbase数据最终是在hdfs上的&#xff0c;具体来说应该是在hdfs上一个叫做/hbase的目录下。具体结构如下&#xff1a; 所以java访问Hbase其实就是访问hdfs&#xff0c;所以环境搭建跟hadoop开发环境使用没什么不同。 实战部分 1.导入需要的jar包&#xff0c;此处在java项…

大数据之HBase数据库

一、了解HBase 1.1 HBase简介 HBase是Apache的Hadoop项目的子项目 HBase不同于一般的关系数据库&#xff0c;它是一个适合于非结构化数据存储的数据库 建立在Hadoop文件系统之上的分布式面向列的数据库 属于开源项目&#xff0c;可以进行横向扩展 适用于需要实时地随机访问…

pinpoint的Hbase数据库的数据优化

pinpoint的Hbase数据库的数据优化 写的原因&#xff1a; 因为是测试服务器&#xff0c;在运行测试项目时&#xff0c;需要日志的打印输出&#xff0c;由于发现磁盘空间不足&#xff0c;想删除些东西&#xff0c;释放空间&#xff0c;然后发现pinpoint服务的Hbase数据库占据了1…

2.使用HBase数据库操作_实验环境Ubuntu

实验前期准备 ssh localhost //检测自己的ssh服务器设置 cd /usr/local/hadoop ./sbin/start-dfs.sh //启动Hadoop jps //查看hadoop是否启动成功 cd /usr/local/hbase bin/start-hbase.sh //启动hbase jps //查看hadoop是否启动成功 bin/hbase shell //打开hbase的…

猿如意工具Redis数据库,Memcached数据库,MongoDB数据库,HBase数据库等等

按照参考样例&#xff1a; 安装教程 在电脑上安装好猿如意之后。因为第一次使用就搜了下各种数据库使用的方式 猿如意工具 Redis数据库Memcached数据库MongoDB数据库HBase数据库MySQL WorkbenchDBeaverNavicat Lite Redis数据库 点击搜索了下Redis数据库&#xff0c;可看到以…

hbase数据库详解

本文首先简单介绍了HBase,然后重点讲述了HBase的高并发和实时处理数据 、HBase数据模型、HBase物理存储、HBase系统架构&#xff0c;HBase调优、HBase Shell访问等。 不过在此之前&#xff0c;你可以先了解 Hadoop生态系统 &#xff0c;若想运行HBase&#xff0c;则需要先搭建…

Java连接HBASE数据库

HBASE是建立在Hadoop分布式系统基础之上的列模式数据库&#xff0c;Java连接HBASE需要如下几个jar包&#xff1a;hadoop-common、hadoop-mapreduce-client-core、hbase-common、hbase-client。这些jar包在maven仓库里都有&#xff0c;地址&#xff1a;https://mvnrepository.co…

Hbase数据库

第一关&#xff1a;Hbase数据库的安装 任务描述 本关任务&#xff1a;安装与配置HBase数据库。 相关知识 在安装HBase之前你需要先安装Hadoop和Zookeeper&#xff0c;如果你还没有安装可以通过这两个实训来学习&#xff1a;Hadoop安装与配置&#xff0c;Zookeeper安装与配置…

Hbase

Hbase 简介hadoop的局限HBase与NoSQLHBase的数据模型HBase的逻辑架构HBase物理存储结构数据模型Hbase基本结构&#xff08;不完整版&#xff09; 简介 hadoop的局限 hadoop主要实现批量数据的处理&#xff0c;并且通过顺序方式访问数据 要查找数据必须搜索整个数据库&#xf…

HBase介绍

第1章 HBase简介 1.1 HBase定义 HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库。 1.2 HBase数据模型 逻辑上&#xff0c;HBase的数据模型同关系型数据库很类似&#xff0c;数据存储在一张表中&#xff0c;有行有列。但从HBase的底层物理存储结构&#xff08;K…

hbase数据库介绍,HBASE的特点,表结构逻辑视图,Row Key,列族,时间戳,Cell

HBASE数据库 1. Hbase基础 1.1 hbase数据库介绍 1、简介nosql hbase是bigtable的开源java版本。是建立在hdfs之上&#xff0c;提供高可靠性、高性能、列存储、可伸缩、实时读写nosql的数据库系 统。 它介于nosql和RDBMS之间&#xff0c;仅能通过主键(row key)和主键的ran…

大数据工具——HBASE数据库(一)

一、HBASE基础概念 1.HBASE概念 HBASE是一个数据库----可以提供数据的实时随机读写。HBASE与mysql、oralce、db2、sqlserver等关系型数据库不同&#xff0c;它是一个NoSQL数据库&#xff08;非关系型数据库&#xff09; 2.HBase特性 - HBase的表模型与关系型数据库的表模型…

HBase详细总结

1 HBase 浅析 1.1 HBase 是啥 HBase 是一款面向列存储&#xff0c;用于存储处理海量数据的 NoSQL 数据库。它的理论原型是Google 的 BigTable 论文。你可以认为 HBase 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统。 HBase 的存储是基于HDFS的&#xff0c;HDFS 有…

HBase详细概述

本文首先简单介绍了HBase,然后重点讲述了HBase的高并发和实时处理数据 、HBase数据模型、HBase物理存储、HBase系统架构&#xff0c;HBase调优、HBase Shell访问等。 不过在此之前&#xff0c;你可以先了解 Hadoop生态系统 &#xff0c;若想运行HBase&#xff0c;则需要先搭建…

JPG,PNG,BMP图片无损压缩软件

怎么压缩图片文件的大小呢&#xff1f;现在的科技发展迅速&#xff0c;手机或者摄像机拍摄的图片的像素很高&#xff0c;这样也就导致了图片比较大&#xff0c;我们想要将图片上传作为网站的头像或者其他网站平台都会对图片文件大小进行限制&#xff0c;今天教给大家一种压缩图…

深入前端图片压缩

前言 任何研究都不是凭空产生&#xff0c;至少博主是这样的。 在手机端拍照后图片很大&#xff0c;有的甚至有 10M 多。这个时候再去上传图片&#xff0c;可想而知&#xff0c;速度是很慢的。正因如此&#xff0c;便有了前端图片压缩这个需求。 图片格式 传统的图片格式有 gi…

html图片无损压缩,有损压缩和无损压缩的区别是什么

区别:无损压缩是可以完全还原的;而有损压缩还原后不能和原来文件一样,是有一定损耗的。有损压缩两种的基本机制(有损变换编解码和预测编解码);而无损压缩原理有行程编码、霍夫曼编码和算术编码等。 本教程操作环境:windows10系统、thinkpad t480电脑。 有损压缩是利用了人…

6种比较好的“在线图片无损压缩工具”+PDF转换工具

目录 第一&#xff1a;Tinypng 第二&#xff1a;Compressor.io 第三&#xff1a;Kraken.io 第四&#xff1a;Giftofspeed 第五&#xff1a; OptimiZilla 第六&#xff1a;Imagerecycle 第七&#xff1a;&#xff08;PDF转换工具&#xff09;ToePub 第一&#xff1a;Tiny…