Python-geopandas 中国地图绘制-程序员宅基地

技术标签: css  可视化  csv  js  数据可视化  

公众号后台回复“图书“,了解更多号主新书内容

 作者:宁海涛

 来源:DataCharm

上一期的地图可视化推文教程R-ggplot2 标准中国地图制作中,我们详细介绍了使用R-ggplot2 包完美绘制中国标准地图,本期推文我们则试着使用Python-geopandas包绘制空间地图,主要的知识点如下:

  • geopandas 绘制中国地图

  • matplotlib add_axes()添加南海小地图

  • 绘图文件分享

geopandas 读取中国地图文件

geopandas提供了非常方便的read_file()方法用于读取geojson文件,我们直接进行默认投影(WGS84)的绘制,代码如下:

file = r"中国省级地图GS(2019)1719号.geojson"
nine = r"九段线GS(2019)1719号.geojson"
china_main = gpd.read_file(file)
china_nine = gpd.read_file(nine)
fig, ax = plt.subplots(figsize=(12, 8),dpi=80)
ax = china_main.plot(ax=ax)
ax = china_nine.plot(ax=ax)

可视化结果如下:

我们进行投影转换(epsg=2343)和进行一些简单的设置,代码如下:

fig, ax = plt.subplots(figsize=(12, 8),dpi=80)
ax = china_main.geometry.to_crs(epsg=2343).plot(fc="white",ec="black",ax=ax)
ax = china_nine.geometry.to_crs(epsg=2343).plot(ec="black",ax=ax)

这里注意to_crs(epsg=2343) 就可以进行投影转换了。

绘图数据操作

接下来,我们将我们要绘制的数据读取、转换并绘制在地图上,数据预览如下:

我们使用如下代码将其转换成具有地理信息的geopandas 格式数据:

scattergdf = gpd.GeoDataFrame(
    scatter, geometry=gpd.points_from_xy(scatter.lon, scatter.lat),
    crs="EPSG:4326")
scattergdf.head()

结果如下:

接下来再将其转换成 epsg=2343 投影下的数据:

scattergdf_2343 = scattergdf.to_crs(epsg=2343, inplace=True)

以上就完成的数据的处理操作了

地图可视化绘制

直接给出绘图代码,然后再进行解释。主要代码如下:

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)

for 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([])
  • add_axes() 添加南海小地图

#添加南海小地图    
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)

这部分还是为了更好的定制化图例,希望大家可以掌握。

最终,我们的可视化效果如下:

关注 DataCharm 公众号,后台回复:地图文件 ,即可获取免费下载链接。

注:该数据只限于练习交流,请勿用于科研、出版使用

总结

本期推文使用了Python-geopandas进行了中国地图的绘制,讲解了数据标记,投影转换等内容。但需指出的是:

  1. geopandas 的安装较为麻烦,建议使用 conda install --channel conda-forge geopandas 进行安装。

  2. Python 绘制空间可视化还是存在部分问题(无法较容易的添加如比例尺、指北针等空间绘图元素),也在进一步完善过程中。

◆ ◆ ◆  ◆ ◆

麟哥新书已经在京东上架了,我写了本书:《拿下Offer-数据分析师求职面试指南》,目前当当正在举行双12活动,大家可以用相原价5折的价格购买,还是非常划算的:


数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。

管理员二维码:

猜你喜欢

 卧槽!原来爬取B站弹幕这么简单

 厉害了!麟哥新书登顶京东销量排行榜!

 笑死人不偿命的知乎沙雕问题排行榜

 用Python扒出B站那些“惊为天人”的阿婆主!

 你相信逛B站也能学编程吗

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_38753213/article/details/110848615

智能推荐

python简易爬虫v1.0-程序员宅基地

文章浏览阅读1.8k次,点赞4次,收藏6次。python简易爬虫v1.0作者:William Ma (the_CoderWM)进阶python的首秀,大部分童鞋肯定是做个简单的爬虫吧,众所周知,爬虫需要各种各样的第三方库,例如scrapy, bs4, requests, urllib3等等。此处,我们先从最简单的爬虫开始。首先,我们需要安装两个第三方库:requests和bs4。在cmd中输入以下代码:pip install requestspip install bs4等安装成功后,就可以进入pycharm来写爬虫了。爬

安装flask后vim出现:error detected while processing /home/zww/.vim/ftplugin/python/pyflakes.vim:line 28_freetorn.vim-程序员宅基地

文章浏览阅读2.6k次。解决方法:解决方法可以去github重新下载一个pyflakes.vim。执行如下命令git clone --recursive git://github.com/kevinw/pyflakes-vim.git然后进入git克降目录,./pyflakes-vim/ftplugin,通过如下命令将python目录下的所有文件复制到~/.vim/ftplugin目录下即可。cp -R ...._freetorn.vim

HIT CSAPP大作业:程序人生—Hello‘s P2P-程序员宅基地

文章浏览阅读210次,点赞7次,收藏3次。本文简述了hello.c源程序的预处理、编译、汇编、链接和运行的主要过程,以及hello程序的进程管理、存储管理与I/O管理,通过hello.c这一程序周期的描述,对程序的编译、加载、运行有了初步的了解。_hit csapp

18个顶级人工智能平台-程序员宅基地

文章浏览阅读1w次,点赞2次,收藏27次。来源:机器人小妹  很多时候企业拥有重复,乏味且困难的工作流程,这些流程往往会减慢生产速度并增加运营成本。为了降低生产成本,企业别无选择,只能自动化某些功能以降低生产成本。  通过数字化..._人工智能平台

electron热加载_electron-reloader-程序员宅基地

文章浏览阅读2.2k次。热加载能够在每次保存修改的代码后自动刷新 electron 应用界面,而不必每次去手动操作重新运行,这极大的提升了开发效率。安装 electron 热加载插件热加载虽然很方便,但是不是每个 electron 项目必须的,所以想要舒服的开发 electron 就只能给 electron 项目单独的安装热加载插件[electron-reloader]:// 在项目的根目录下安装 electron-reloader,国内建议使用 cnpm 代替 npmnpm install electron-relo._electron-reloader

android 11.0 去掉recovery模式UI页面的选项_android recovery 删除 部分菜单-程序员宅基地

文章浏览阅读942次。在11.0 进行定制化开发,会根据需要去掉recovery模式的一些选项 就是在device.cpp去掉一些选项就可以了。_android recovery 删除 部分菜单

随便推点

echart省会流向图(物流运输、地图)_java+echart地图+物流跟踪-程序员宅基地

文章浏览阅读2.2k次,点赞2次,收藏6次。继续上次的echart博客,由于省会流向图是从echart画廊中直接取来的。所以直接上代码<!DOCTYPE html><html><head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /&_java+echart地图+物流跟踪

Ceph源码解析:读写流程_ceph 发送数据到其他副本的源码-程序员宅基地

文章浏览阅读1.4k次。一、OSD模块简介1.1 消息封装:在OSD上发送和接收信息。cluster_messenger -与其它OSDs和monitors沟通client_messenger -与客户端沟通1.2 消息调度:Dispatcher类,主要负责消息分类1.3 工作队列:1.3.1 OpWQ: 处理ops(从客户端)和sub ops(从其他的OSD)。运行在op_tp线程池。1...._ceph 发送数据到其他副本的源码

进程调度(一)——FIFO算法_进程调度fifo算法代码-程序员宅基地

文章浏览阅读7.9k次,点赞3次,收藏22次。一 定义这是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO 算法并不能保证这些页面不被淘汰。这里,我_进程调度fifo算法代码

mysql rownum写法_mysql应用之类似oracle rownum写法-程序员宅基地

文章浏览阅读133次。rownum是oracle才有的写法,rownum在oracle中可以用于取第一条数据,或者批量写数据时限定批量写的数量等mysql取第一条数据写法SELECT * FROM t order by id LIMIT 1;oracle取第一条数据写法SELECT * FROM t where rownum =1 order by id;ok,上面是mysql和oracle取第一条数据的写法对比,不过..._mysql 替换@rownum的写法

eclipse安装教程_ecjelm-程序员宅基地

文章浏览阅读790次,点赞3次,收藏4次。官网下载下载链接:http://www.eclipse.org/downloads/点击Download下载完成后双击运行我选择第2个,看自己需要(我选择企业级应用,如果只是单纯学习java选第一个就行)进入下一步后选择jre和安装路径修改jvm/jre的时候也可以选择本地的(点后面的文件夹进去),但是我们没有11版本的,所以还是用他的吧选择接受安装中安装过程中如果有其他界面弹出就点accept就行..._ecjelm

Linux常用网络命令_ifconfig 删除vlan-程序员宅基地

文章浏览阅读245次。原文链接:https://linux.cn/article-7801-1.htmlifconfigping &lt;IP地址&gt;:发送ICMP echo消息到某个主机traceroute &lt;IP地址&gt;:用于跟踪IP包的路由路由:netstat -r: 打印路由表route add :添加静态路由路径routed:控制动态路由的BSD守护程序。运行RIP路由协议gat..._ifconfig 删除vlan