当前位置: 首页 > news >正文

[Python/地图] 基于Python绘制地图

0 概述:基于Python绘制地图

1 基于 PyEcharts 绘制地图

PyEchart库

  • pyecharts 是一个基于 百度开源的 Apache EChartsPython 数据可视化库。

ECharts 是一个使用 JavaScript 实现的开源可视化库,而 Pyecharts 则是 ECharts 的 Python 封装,使得在 Python 中使用 ECharts 变得更加方便。

CASE 绘制中国国的全国省级地图

  • 安装依赖
pyecharts# 需要注意,自从 v0.3.2 开始,为了缩减项目本身的体积以及维持 pyecharts 项目的轻量化运行,pyecharts 将不再自带地图 js 文件。为了绘制地图,还要单独安装对应的地图文件包:
echarts-china-provinces-pypkg
# 全球国家地图:世界地图和 213 个国家,包括中国地图 (可以根据自己的需求进行对应下载)
# echarts-countries-pypkg
# 中国省级地图
# echarts-china-provinces-pypkg
# 中国地级市地图
# echarts-china-cities-pypkg
# 中国县级地图
# echarts-china-counties-pypkg
# 中国区域地图
# echarts-china-misc-pypkg

查看版本安装情况

C:\Users\xxx> pip list | findstr "charts"
echarts-china-provinces-pypkg 0.0.3
pyecharts                     2.0.8
pyecharts-jupyter-installer   0.0.3
  • 准备数据

  • 编写、运行 Python 脚本

from pyecharts.charts import Map
from pyecharts import options as opts# @description CASE 绘制中国国的全国省级地图
# @updateTime 2025-10-08 15:11# 准备数据
province_distribution = {'河南省': 59.23, '北京市': 37.56, '河北省': 21, '辽宁省': 12, '江西省': 6,'上海市': 20, '安徽省': 10, '江苏省': 16, '湖南省': 9, '浙江省': 13,'海南省': 2, '广东省': 22, '湖北省': 8, '黑龙江省': 11, '澳门特别行政区': 1,'陕西省': 11, '四川省': 7, '内蒙古自治区': 3, '重庆市': 3, '云南省': 6,'贵州省': 2, '吉林省': 3, '山西省': 12, '山东省': 11, '福建省': 4,'青海省': 1, '天津市': 1, '其他': 1
}
# 特别注意: 必须用 "省" 或 "市" 结尾,否则数据匹配不上 (例如: "xx省" ,"xx自治区" , "xx市", "xx特别行政区")
provinces = list(province_distribution.keys())
# provinces = ["北京", "上海", "广东", "江苏", "浙江", "四川", "湖北", "湖南", "河南", "山东"]
values = list(province_distribution.values())
# values = [100, 90, 80, 70, 60, 50, 40, 30, 20, 10]# 将数据转换为Pyecharts需要的格式
data = list(zip(provinces, values))# 创建地图
map = Map(init_opts=opts.InitOpts(width="1000px", height="600px"))
map.add( # 添加1个图例series_name="series_001" # 允许设置为空字符串(""),不显示图例, data_pair=data # [list(z) for z in data], maptype="china" # 指定绘制地图区域, is_map_symbol_show=False # 显示省份标签# , is_selected=False # 是否默认选中 (此属性,已不再被支持)
)
map.set_global_opts(title_opts=opts.TitleOpts(title="中国地图",pos_left="center",  # 标题居中pos_top="20px"  # 标题位置), legend_opts=opts.LegendOpts(is_show=True) # 显示图例, visualmap_opts=opts.VisualMapOpts(max_=50)
)
map.render("china_map.html") # 渲染地图(生成HTML文件)

运行成功后,将输出1个html文件: china_map.html

image

浏览器打开:

image

CASE 绘制指定省份的地级市数据,且替换掉默认的行政区划中文名称为自定义的英文名称

  • 安装依赖
  • 准备数据集

hubei.csv

Province Province-Chinese Number
Wuhan 武汉市 10
Huang-gang 黄冈市 9
Xiao-gan 孝感市 8
Huang-shi 黄石市 5
Shi-yan 十堰市 5
Xian-ning 咸宁市 2
Xiang-yang 襄阳市
Shen-nong-jia 神农架林区 2
Shi-En 恩施土家族苗族自治州
Yi-Chang 宜昌市
Jing-zhou 荆州市 2
Qian-jiang 潜江市
Jing-men 荆门市 7
Tian-men 天门市
Xian-tao 仙桃市 2
E-zhou 鄂州市 2
Sui-zhou 随州市
  • 运行python脚本
from pyecharts.charts import Map
from pyecharts import options as opts
import pandas as pd
import os,sys# @description CASE 绘制指定省份的地级市数据,且替换掉默认的行政区划中文名称为自定义的英文名称
# @updateTime 2025-10-08 16:07# step1 准备数据
city = 'hubei'  # 地级市名称(英文)
city_chinese = '湖北' # 地级市名称(中文)#file = r'C:\Users\EDY\Desktop\map\{0}{1}'.format(city,'.csv') # 'C:\Users\EDY\Desktop\map\\hubei.csv'
#os.chdir("../dataset/");path=os.getcwd() + os.sep;file = path + r'{0}{1}'.format(city,'.csv')
file = os.path.abspath( os.path.join('..', 'dataset', city + '.csv') )
print(f"file:{file}");
data = pd.read_csv(file, encoding='gbk')
list = [list(z) for z in zip(data['Province'],data['Number'])]
areaNameMap = dict(zip(data['Province-Chinese'],data['Province'])) # 行政区划中文与英文映射关系
print(f"areaNameMap:{areaNameMap}") # {'武汉市': 'Wuhan', '黄冈市': 'Huang-gang', '孝感市': 'Xiao-gan', '黄石市': 'Huang-shi', '十堰市': 'Shi-yan', '咸宁市': 'Xian-ning', '襄阳市': 'Xiang-yang', '神农架林区': 'Shen-nong-jia', '恩施土家族苗族自治州': 'Shi-En', '宜昌市': 'Yi-Chang', '荆州市': 'Jing-zhou', '潜江市': 'Qian-jiang', '荆门市': 'Jing-men', '天门市': 'Tian-men', '仙桃市': 'Xian-tao', '鄂州市': 'E-zhou', '随州市': 'Sui-zhou'}# step2 地图的初始化与参数配置
map = Map(opts.InitOpts(width='1200px',height='1200px'))
map.add( # 添加1个图例series_name='province', data_pair=list, maptype=city_chinese, is_map_symbol_show = True, name_map=areaNameMap
)
map.set_global_opts(title_opts=opts.TitleOpts(title=city),visualmap_opts = opts.VisualMapOpts(max_=2, is_piecewise=False, range_color=['#8EC0E4','#67D5B5'])
)
map.set_series_opts(label_opts=opts.LabelOpts(font_size = 22 # font_size 调整字体大小,font_family="Times New Roman" # 字体,is_show=True, color="blue" # 颜色)
)# step3 渲染(输出 html 文件)
map.render(city + '.html')

浏览器打开: hubei.html

image

推荐文献

  • Echarts
  • https://05x-docs.pyecharts.org/#/zh-cn/prepare

参考文献

  • 使用pyecharts绘制中国地图 - 博客园
  • 求助!Pyecharts地图构建为什么不显示颜色和内容? - Zhihu

"把北京改为北京市,如果有自治区,就写,比如内蒙古自治区,湖南省"

  • Python pyecharts实现绘制中国地图的实例详解 - zhangshengrong.com
  • 使用pyecharts绘制中国地图或省地图 - 博客园

"为啥是要用拼音呢?因为项目中所画的图是要投国外期刊,需要转换成英文,那这样的话,需要有一个中英文转换,也就是代码中namemap的作用"

2 基于 Geopandas + geopandas 库绘制地图

Geopandas 与 geopandas 库的介绍

  • GeoPandas 库

一个开源的、用于处理地理数据的Python库,它基于Pandas和Shapely,提供了方便的地理数据操作和可视化功能。
它扩展了Pandas库的功能,使得在Python中可以方便地处理地理空间数据。
GeoDataFrameGeoPandas中的一个核心数据结构,它继承自PandasDataFrame,但增加了对地理空间数据的支持。

  • Geopandas.GeoDataFrame 组件

GeoDataFrame是一个表格型的数据结构,它不仅包含了数据的属性信息,还包含了地理信息,即几何对象
这些几何对象可以是点(Point),线(LineString),或者多边形(Polygon)等。
每个GeoDataFrame都有一个名为"geometry"(几何学)的列,用来存储几何对象,这使得GeoDataFrame能够与GIS软件中的矢量数据进行交互。

  • geodatasets 库

一个用于获取和缓存空间数据示例文件的 Python 包。
它提供了一个 API,可以从包含地理空间信息的外部托管数据集中提取链接或下载数据,这些数据集对于说明性和教育目的非常有用。

  • 安装
pip install geodatasets

CASE 基于经纬度数据集,绘制中国地图 by geopandas + matplotlib 【TODO】

import geopandas as gpd
import matplotlib.pyplot as plt
import pandas as pd
import os# @description 基于经纬度数据集,绘制中国地图 by geopandas + matplotlib
# @note 此脚本尚无法直接运行
# @reference-doc
# [1] R-ggplot2 标准中国地图制作 【推荐】 - Weixin/DataCharm - https://mp.weixin.qq.com/s?__biz=Mzg3MDY4ODI3MQ==&mid=2247497916&idx=1&sn=7d41c62dce027ef16e71c137898f4819&source=41&poc_token=HNIl5mijRifNCiMyGRCsMnIWbie0xhO1sSFFfMKC
# [2] Python-geopandas 中国地图绘制 【推荐】 - 腾讯云/DataCharm - https://cloud.tencent.com/developer/article/1790603
# @updateTime 2025-10-08 16:07file = os.path.abspath( os.path.join('..', 'dataset', '中国省级地图GS(2019)1719号.geojson') ) # https://github.com/dlming123/China-map-information/blob/main/%E4%B8%AD%E5%9B%BD%E7%9C%81%E7%BA%A7%E5%9C%B0%E5%9B%BEGS%EF%BC%882019%EF%BC%891719%E5%8F%B7.geojson
nine = os.path.abspath( os.path.join('..', 'dataset', '九段线GS(2019)1719号.geojson') ) # https://github.com/dlming123/China-map-information/blob/main/%E4%B9%9D%E6%AE%B5%E7%BA%BFGS%EF%BC%882019%EF%BC%891719%E5%8F%B7.geojson
china_main = gpd.read_file(file)
china_nine = gpd.read_file(nine)fig, ax = plt.subplots(figsize=(8,5),dpi=200,)
plt.rcParams['font.family'] = ['Times New Roman']ax = china_main.geometry.to_crs(epsg=2343).plot(fc="white",ec="black",linewidth=.8,ax=ax)
ax = china_nine.geometry.to_crs(epsg=2343).plot(color="gray",linewidth=.9,ax=ax)# 创建散点数据集 scatter
scatter_data = [[29.580000, 106.550000, 'cluster1', 1],[40.705295, 114.931254, 'cluster1', 3],[31.366458, 118.381979, 'cluster1', 2],[32.935000, 117.365000, 'cluster1', 2],[32.630000, 116.970000, 'cluster1', 4]## ... more data
]
# 指定列名
scatter_columns = ['lat', 'lon', 'class', 'data']
# 创建 DataFrame
scatter = pd.DataFrame(scatter_data, columns=scatter_columns)scattergdf = gpd.GeoDataFrame(scatter, geometry=gpd.points_from_xy(scatter.lon, scatter.lat),crs="EPSG:4326"
)scattergdf.head();scattergdf_2343 = scattergdf.to_crs(epsg=2343, inplace=True)
# china_nine_2343 = //todofor loc, size,class_name in zip(scattergdf_2343.geometry.representative_point(),\scattergdf_2343["data"],scattergdf_2343["class"]):ax.scatter(loc.x,loc.y,s=10*size,fc=class_color[class_name],ec="black",lw=.5,zorder=2)
#添加刻度线
for spine in ['top','left',"bottom","right"]:ax.spines[spine].set_color("none")#ax.set_xlim(china_nine_2343.geometry[0].x-500000, china_nine_2343.geometry[1].x)
#ax.set_ylim(china_nine_2343.geometry[0].y, china_nine_2343.geometry[1].y)
ax.set_xticks([])
ax.set_yticks([])
#单独绘制图例散点
ax.scatter([], [], c='#E21C21', s=30,  label='cluster1',ec="black",lw=.5)
ax.scatter([], [], c='#3A7CB5', s=30,  label='cluster2',ec="black",lw=.5)
ax.scatter([], [], c='#51AE4F', s=30,  label='cluster3',ec="black",lw=.5)ax.scatter([], [], c='white', s=1*10,label='1', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=2*10,label='2', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=3*10,label='3', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=4*10,label='4', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=5*10,label='5', edgecolor='black',lw=.5)ax.legend(frameon=False,ncol=8,loc="upper center",fontsize=9,columnspacing=.2)ax.text(.91,-0.02,'\nVisualization by DataCharm',transform = ax.transAxes,ha='center', va='center',fontsize = 6,color='black')#添加南海小地图
ax_child = fig.add_axes([0.688, 0.125, 0.2, 0.2])
ax_child = china_main.geometry.to_crs(epsg=2343).plot(ax=ax_child,fc="white",ec="black",)
ax_child = china_nine.geometry.to_crs(epsg=2343).plot(ax=ax_child,color="gray",linewidth=.9,)for loc, size,class_name in zip(scattergdf_2343.geometry.representative_point(),\scattergdf_2343["data"],scattergdf_2343["class"]):ax_child.scatter(loc.x,loc.y,s=10*size,fc=class_color[class_name],ec="black",lw=.5,zorder=2)#ax_child.set_xlim(china_nine_2343.geometry[2].x, china_nine_2343.geometry[3].x)
#ax_child.set_ylim(china_nine_2343.geometry[2].y, china_nine_2343.geometry[3].y)
# 移除子图坐标轴刻度,
ax_child.set_xticks([])
ax_child.set_yticks([])# 添加南海小地图
ax_child = fig.add_axes([0.688, 0.125, 0.2, 0.2])
ax_child = (china_main.geometry.to_crs(epsg=2343).plot(ax=ax_child,fc="white",ec="black",));ax_child = china_nine.geometry.to_crs(epsg=2343).plot(ax=ax_child,color="gray",linewidth=.9,)for loc, size,class_name in zip(scattergdf_2343.geometry.representative_point(),\scattergdf_2343["data"],scattergdf_2343["class"]):ax_child.scatter(loc.x,loc.y,s=10*size,fc=class_color[class_name],ec="black",lw=.5,zorder=2)#ax_child.set_xlim(china_nine_2343.geometry[2].x, china_nine_2343.geometry[3].x)
#ax_child.set_ylim(china_nine_2343.geometry[2].y, china_nine_2343.geometry[3].y)
# 移除子图坐标轴刻度,
ax_child.set_xticks([])
ax_child.set_yticks([])#单独绘制图例散点
ax.scatter([], [], c='#E21C21', s=30,  label='cluster1',ec="black",lw=.5)
ax.scatter([], [], c='#3A7CB5', s=30,  label='cluster2',ec="black",lw=.5)
ax.scatter([], [], c='#51AE4F', s=30,  label='cluster3',ec="black",lw=.5)ax.scatter([], [], c='white', s=1*10,label='1', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=2*10,label='2', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=3*10,label='3', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=4*10,label='4', edgecolor='black',lw=.5)
ax.scatter([], [], c='white', s=5*10,label='5', edgecolor='black',lw=.5)ax.legend(frameon=False,ncol=8,loc="upper center",fontsize=9,columnspacing=.2)

CASE 使用geopandas提取地理信息数据,并绘制地图

  • 推荐文献
  • 使用geopandas提取地理信息数据并绘制地图 - Zhihu/大气飞行物 【推荐】

中国科学院大学 环境科学博士
http://datav.aliyun.com/portal/school/atlas/area_selector

推荐文献

  • Python-geopandas 中国地图绘制 - 腾讯云
  • https://geojson.cn/data/atlas/china

image

  • https://www.naturalearthdata.com/

  • Python中的GeoPandas和GeoDataFrame - jianshu

  • DataV

  • https://datav.aliyun.com/portal
  • http://datav.aliyun.com/portal/school/atlas/area_selector

Y 推荐文献

  • [Python/数据分析] Pandas:数据分析库 - 博客园/千千寰宇

X 参考文献

http://www.hskmm.com/?act=detail&tid=26834

相关文章:

  • 实验任务1——8
  • 一款专门为 WPF 打造的开源 Office 风格用户界面控件库
  • dockercontainerd代理设置脚本
  • 实用指南:vue3+elementplus表格表头加图标及文字提示
  • 2025国庆集训总结
  • tampermonkey油猴脚本, 动画疯评分显示增强脚本
  • 9.29课后整理 - GENGAR
  • 深入解析:【QT】`QTextCursor::insertText()`中插入彩色文本
  • Java方法专题 - 动手动脑问题与实验总结
  • 2025年中盘点
  • 学习问题日记-3
  • 差分约束乘法改加减
  • 01-方法-课后作业
  • 应用程序io接口
  • 边缘数据库近期想法(2)
  • 方法-课后作业1
  • io软件的层次结构
  • 2025年- H57-Lc165--994.腐烂的橘子(图论,广搜)--Java版 - 教程
  • 3,信号与槽机制 - 教程
  • 课后思考及作业:方法
  • 2025国庆Day7
  • 月嫂面试题
  • 把握一个Makefile的脉络
  • 笔记 基础算法
  • P10068 [CCO 2023] Line Town
  • AI元人文:共识锚定与智慧剪枝——构建人机共生认知经济体的完善理论体系与实践路径
  • 出题系统
  • io控制方式
  • Java课后作业
  • 我 是 人 机