目录
超长文预警!
一、Geopandas
1.1 读取、创建地理信息数据
1.2 处理地理信息数据(工具箱!如空间连接等)
1.3 绘制专题地图
1.4 数据导出
二、OSMnx
2.1 下载并保存行政边界、道路网
2.2 道路网络优化
2.3 网络分析数据可视化
三、NetworkX
3.1 社会关系网络(SNA)
3.2 城市网络(UNA)
超长文预警!
作为一名城市规划+地理学相关专业的学生,今天给大家分享三个关于地理信息系统处理相关的库,这三个库可以帮助我们更好的处理地理信息数据以及绘制相关的专题地图。Geopandas(数据处理)
OSMnx(数据下载与分析)
Networkx(网络化)
读完本文你将学会这些东西:如何在Python中绘制一张好看的地图
如何用Python下载道路网、行政边界,并保存为shp文件
如何用Python进行空间分析(如进行数据裁剪、融合、空间连接等)
如何用Python进行网络分析
学习绘制下面这种图
如果你还不会使用Python,但却对我进行的这些工作非常感兴趣,强烈安利领取下面这个免费的课程进行免费学习,通过这个课程快速入门Python的基础知识。可以很放心的说,你只要会了基础操作,下面我推荐给大家的库你都可以自由的模仿操作。
快点击卡片领取吧!
絮絮叨了这么多,以下是正文:
一、Geopandas
Geopandas与大名鼎鼎的pandas库有异曲同工之妙,甚至我们可以说geopandas就是地理信息领域的pandas。准确说,geopandas是将地理信息记录在数据表中,并可以通过一系列的绘图库进行显示,和Arcmap中的属性表非常类似。The goal of GeoPandas is to make working with geospatial data in python easier. It combines the capabilities of pandas and shapely, providing geospatial operations in pandas and a high-level interface to multiple geometries to shapely. GeoPandas enables you to easily do operations in python that would otherwise require a spatial database such as PostGIS.
GeoPandas的目标是使在python中处理地理空间数据更加容易。它结合了Pandas和shapely的功能,在Pandas中提供地理空间操作,并为多个shapely的形状提供了高级界面。 GeoPandas使您能够轻松地在python中进行操作,而这些操作可能需要空间数据库,例如PostGIS。
Geopandas也可以绘制非常多好看的图,比如说我下面这张图:
目前,Geopandas主要支持以下一些功能:
1.1 读取、创建地理信息数据
Geopandas读取地理数据非常的方便,它只需要几行代码就可以将shp文件转换为GeoDataFrame:
park = gpd.read_file("/Users/creative/OneDrive - stu.hit.edu.cn/课程资料/2020 毕业论文/Arcgis_Analysis/Data/Shp/研究公园信息.shp")
park.head(1)
GeoDataFrame和pandas的DataFrame非常类似,只不过多了最后一个关于geometry的地理信息字段,用来进行地理信息的描述
如果你是excel或者csv等格式的文本文件,需要转换为GeoDataFrame,就需要结合pandas进行操作,原理类似于Arcgis里的添加XY数据,代码上也非常简单:
df = pd.read_excel(data_path)
gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.lng, df.lat)) #选择XY坐标为地理坐标
gdf.crs = 'EPSG:4326' #指定坐标系
注:EPSG是各类投影的一个国际通用编码,具体可以自行进行查询(WGS1984为4326)
1.2 处理地理信息数据(工具箱!如空间连接等)
Geopandas也可以和GiS软件一样进行一些简单的空间处理操作,比如说裁剪、融合、空间连接等(这里放上官网的图),代码上也是非常的简单!
"""取交集"""
country_cores = geopandas.overlay(countries, capitals, how='intersection')
country_cores.plot(alpha=0.5, edgecolor='k', cmap='tab10');
"""裁剪"""
country_peripheries = geopandas.overlay(countries, capitals, how='difference')
country_peripheries.plot(alpha=0.5, edgecolor='k', cmap='tab10');
空间连接没有相关的图,不过原理上是和gis软件里类型的,这里放上代码:
cities_with_country = geopandas.sjoin(cities, countries, how="inner", op='intersects')
括号里第一二个参数为要进行连接的两个文件,how是数据保存的方式(保存第一个文件数据、保存第二个文件数据、保存交集数据三个选项),op是选项(有相交、在内部、包含三种选择)
1.3 绘制专题地图
这一部分节省篇幅,大家可以看一下我的这篇文章,介绍得也非常详细:Python 如何画出漂亮的地图?www.zhihu.com
1.4 数据导出
Geopandas支持将数据导出为shp、geojson等格式的文件,操作也非常的简单,只需要几行代码即可
geopandas_data.to_file('./result/shopping.shp') #保存成shapfile
从这里你也可以发现其实Geopandas对于Python新手来说非常的友好,想要入门Python的话快领个课程进行学习吧,点击下方卡片就可以领取:
二、OSMnx
OSMnx是加州大学城市与区域规划系Geoff Boeing开发的街道网络分析库,它集成了对OpenStreetMap数据的下载、分析街道网络、可视化网络分析结果等多个功能,是一款不被人发掘的强大地理信息处理库。
OSMnx的优势可以快速下载城市的行政边界(包括国家、省、市、县等在Openstreetmap中具有数据的地方均可下载)
可以快速下载城市的道路网络,并可以按照不同的街道类型进行分类下载
可以简化网络数据,将数据处理乘UNA的分析样式
可以将下载的数据直接利用matlibplot可视化或者保存为shp或者svg文件
可以对下载的网络进行分析与可视化
包括对街道长度、节点密度、边密度、中介中心度、连通度、方向熵等等
可以可视化分析结果
2.1 下载并保存行政边界、道路网
OSMnx可以快速下载到世界上大多数地区的省市县级别的行政边界图(国内边境地图慎重!),而且只需要两行代码就可以完成操作
"""单个位置边界下载"""
city = ox.geocode_to_gdf('长沙市')
ax = ox.project_gdf(city).plot()
"""多个位置边界下载"""
places = ox.geocode_to_gdf(["长沙市" ,"常德市" ,"益阳市"])
places = ox.project_gdf(places)
ax = places.plot()
同时,基于OpenStreetmap的OSMnx也可以快速下载到某个区域或者城市的道路网(也包括车行路、人行路等),它也支持按行政边界、框选范围、缓冲区:
"""基于行政边界下载路网"""
G = ox.graph_from_place('南山区, 深圳市', network_type='drive')
G_projected = ox.project_graph(G)
ox.plot_graph(G_projected)
"""基于框选范围下载路网"""
G = ox.graph_from_bbox(22.5229, 22.5178, 113.9265, 113.9360, network_type='drive')
G_projected = ox.project_graph(G)
ox.plot_graph(G_projected)
"""基于点缓冲区下载路网"""
G = ox.graph_from_point((22.517685,113.935941), dist=1000, network_type='all')
ox.plot_graph(G)
OSMnx也和geopandas进行了很好的联动,也只需要很简单的几行代码就可以完成数据转存为GeoDataFrame的格式,你也可以利用这种方式将其导出为shp格式的文件
"""将保存点和边两个文件"""
nodes, edges = ox.graph_to_gdfs(G)
edges.head(1)
2.2 道路网络优化
为了方便进行网络分析,OSMnx也提供了对道路节点进行优化,可以最大限度的减少道路上的多余交点,方便进行网络分析,具体效果见图示:
2.3 网络分析数据可视化
OSMnx也支持对俩点之间在道路网上的通行时间与距离的计算与可视化(类似于Arcgis的网络分析工具)
Geoff Boeing本人还用这个工具进行了步行可达性的测算
这个图颜值,简直绝了!尽管我也进行了模仿,以下是买家秀:
如果你也想模仿,可以参考大佬的原文于Github地址:
原文:https://geoffboeing.com/2016/07/visualize-urban-accessibility-walkability/geoffboeing.com
Github:https://github.com/gboeing/urban-data-science/tree/master/20-Accessibility-Walkabilitygithub.com
想了解更多关于OSMnx的信息,可以去阅读Geoff Boeing大佬发表在Computers, Environment and Urban Systems的论文:OSMnx: New methods for acquiring, constructing, analyzing, and visualizing complex street networkswww.sciencedirect.com
三、NetworkX
同样作为一款网络分析的库,NetworkX比OSMnx更进一步,它基于图论的方法可以创建,操纵和研究复杂网络的结构,动力学和功能。NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks.
NetworkX是进行城市网络分析的重要Python库,NetworkX支持创建简单无向图、有向图和多重图;内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富,简单易用。
目前在我们专业领域主要可以用来做两个方面的工作:
3.1 社会关系网络(SNA)
NetworkX非常适合用来创建基于人物关系的社交网络图,同时,也可以利用网络来分析中间性等指标。下图是利用基于NetworkX绘制的仲夏夜之梦的人物关系图表:
Network graph of characters in A Midsummer Night’s Dream人物关系图谱
具体代码可以参考这篇文章:https://towardsdatascience.com/tutorial-network-visualization-basics-with-networkx-and-plotly-and-a-little-nlp-57c9bbb55bb9towardsdatascience.com
3.2 城市网络(UNA)
城市网络和社交网络相比,多了一个地理属性。多数情况下,我们可以使用basemap或者geopandas与NetworkX一起协同完成这个工作。下图是基于basemap和NetworkX绘制的航线图:
这里放上主要部分的代码:
"""叠加basemap"""
fig = plt.figure(figsize=(9,8),dpi=300)
ax = fig.add_subplot(1,1,1)
m = Basemap(
projection='merc',
llcrnrlon=90,
llcrnrlat=5,
urcrnrlon=120,
urcrnrlat=30,
lat_ts=0,
resolution='l',
suppress_ticks=True)
"""绘制关系网络"""
nx.draw_networkx_nodes(G = graph, pos = pos, nodelist = [x for x in graph.nodes() if counts['total_flight'][x] >= 100],
node_color = 'r', alpha = 0.8,
node_size = [counts['total_flight'][x]*4 for x in graph.nodes() if counts['total_flight'][x] >= 100])
nx.draw_networkx_labels(G = graph, pos = pos, font_size=10,
labels = {x:x for x in graph.nodes() if counts['total_flight'][x] >= 100})
nx.draw_networkx_nodes(G = graph, pos = pos, nodelist = [x for x in graph.nodes() if counts['total_flight'][x] < 100],
node_color = '#c0d0e1', alpha = 0.9,
node_size = [counts['total_flight'][x]*4 for x in graph.nodes() if counts['total_flight'][x] < 100])
nx.draw_networkx_edges(G = graph, pos = pos, edge_color = '#013a55', width = routes_yga['counts']*0.75,
alpha=0.2, arrows = False)
m.drawcountries(linewidth = 1)
m.drawstates(linewidth = 0.2)
m.drawcoastlines(linewidth=1)
m.fillcontinents(alpha = 0.3)
line1 = mlines.Line2D(range(1), range(1), color="white", marker='o', markerfacecolor="red")
line2 = mlines.Line2D(range(1), range(1), color="white", marker='o',markerfacecolor="#c0d0e1")
line3 = mlines.Line2D(range(1), range(1), color="#013a55", marker='',markerfacecolor="#013a55")
plt.legend((line2, line3), ( 'airports', 'routes'),
loc=4, fontsize = 'medium')
以上,如果大家希望我有更多的教程更新的话,麻烦给我多点点赞和喜欢吧!
这是我最大的创作动力!
更多Python于地理信息系统结合的知识可以点击下面的链接查看: