器→工具, 工具软件

Python地理数据可视化工具GeoPandas

钱魏Way · · 4,754 次浏览

GeoPandas简介

GeoPandas是一个开源项目,它的目的是使得在Python下更方便的处理地理空间数据。GeoPandas扩展了pandas的数据类型,允许其在几何类型上进行空间操作。几何操作由shapely执行。GeoPandas进一步依赖于fiona进行文件存取和descartesmatplotlib进行绘图。

GeoPandas沿用了pandas的数据类型,所以GeoPandas中也有两种数据类型:

  • GeoSeries
  • GeoDataFrame

它们分别是Pandas中Series和DataFrame的子类,继承了Pandas数据结构的大部分方法。

GeoSeries

GeoSeries是包含集合图形的序列,每个元素可以是单个形状或多个形状。Geopandas 有三种基本的几何对象:

  • 点:Points/Multi-Points
  • 线:Lines/Multi-Lines
  • 面:Polygons/Multi-Polygons

GeoSeries 中的所有条目不必具有相同的几何类型,如果是不同类型,部分操作可能会失败。

Geoseries 类实现了Shapely 对象的几乎所有属性和方法。在使用GeoSeries时,它将应用于序列中所有几何图形的每一个元素。二元操作可以在两个GeoSeries对象之间进行,这种情况下二元操作将应用于每一个元素。这两个序列将按匹配的索引进行对于操作。二元操作也可以应用于单个几何,此时二元操作将对该几何序列的每个元素进行。在以上两种情况下,操作将会返回Series或者GeoSeries对象。

Attributes 属性

  • area:返回一个Series,它包含GeoSeries中每个几何的面积。
  • bounds:返回一个DataFrame,它包含每个几何的边界,用列值minx, miny, maxx, maxy来表示。
  • total_bounds:返回一个元组,包含整个series边界的minx,miny,maxx,maxy值。包含在序列中的几何体的边界。
  • geom_type:返回一个字符串的Series,字符串指定每个对象的几何类型。
  • is_valid:返回一个布尔型的Series,如果几何体是有效的,该值就为True。

Basic Methods 基本方法

  • distance(): 返回一个Series,它包含与其他GeoSeries对象(每个元素)或几何对象的最小距离。
  • centroid: 返回表示几何重心点的一个GeoSeries。
  • representative_point(): 返回所有点的一个GeoSeries(经简易计算),这些点必须保证在每个几何的内部。这个点不等于重心点。
  • to_crs(): 转换GeoSeries中的几何图形到不同的坐标参考系统。当前GeoSeries的crs属性必须被设置。crs属性需要被指定以用于输出,或是用字典形式或是用EPSG编码方式。
  • plot(): 进行GeoSeries中几何图形的绘制。

Relationship Tests 关系测试

  • geom_almost_equals(): 返回一个布尔型的Series对象,如果在指定的小数位精度下,每个对象所有点与其他对象大致相等,该值就为True。
  • contains(): 返回一个布尔型的Series,如果每个对象的内部包含其他对象的内部和边界,并且它们的边界不相接,该值为True。
  • intersects(): 返回一个布尔型的Series,如果每个对象的边界和内部以其它任何形式与其他对象相交,该值为True。

GeoDataFrame

GeoDataFrame是一个列表数据结构,它包含一个叫做包含geometry的列,这个geometry包含一个GeoSeries。

GeoPandas的安装

GeoPandas在Linux下安装相对简单,只需执行:pip install geopandas

但在Windows下安装通常会遇到如下错误:

(venv) D:\CodeHub\Baidu-Area>pip install geopandas
Looking in indexes: http://mirrors.aliyun.com/pypi/simple/
Collecting geopandas
  Downloading http://mirrors.aliyun.com/pypi/packages/83/c5/3cf9cdc39a6f2552922f79915f36b45a95b71fd343cfc51170a5b6ddb6e8/geopandas-0.7.0-py2.py3-none-any.whl (928k
B)
    100% |████████████████████████████████| 931kB 870kB/s
Collecting pyproj>=2.2.0 (from geopandas)
  Downloading http://mirrors.aliyun.com/pypi/packages/56/57/462b634a5ab562201f4f208b3cd077b80e8e04359509ec294e22f7dd006c/pyproj-2.6.0-cp37-cp37m-win_amd64.whl (24.
1MB)
    100% |████████████████████████████████| 24.1MB 479kB/s
Collecting shapely (from geopandas)
  Downloading http://mirrors.aliyun.com/pypi/packages/ea/55/61a5d274a210585b5d0c3dac81a82952a4baa7903e3642228d7a465fc340/Shapely-1.7.0-cp37-cp37m-win_amd64.whl (1.
0MB)
    100% |████████████████████████████████| 1.0MB 3.0MB/s
Collecting fiona (from geopandas)
  Downloading http://mirrors.aliyun.com/pypi/packages/6d/42/f4a7cac53b28fa70e9a93d0e89a24d33e14826dad6644b699362ad84dde0/Fiona-1.8.13.post1.tar.gz (1.2MB)
    100% |████████████████████████████████| 1.2MB 2.3MB/s
    Complete output from command python setup.py egg_info:
    A GDAL API version must be specified. Provide a path to gdal-config using a GDAL_CONFIG environment variable or use a GDAL_VERSION environment variable.

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\QWD312~1.TCE\AppData\Local\Temp\pip-install-tls06urt\fiona\

主要内容按装依赖库安装GDAL和fiona时报错。

解决方案一:如果使用的是anaconda,可通过conda install geopandas

解决方案二:下载编译好的GDAL和fiona包进行安装,下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/

GeoPandas的使用

显示世界地图:

import geopandas
import matplotlib.pyplot as plt

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world.plot()
plt.show()

GeoPandas的read_file方法几乎可以读取任何基于矢量的空间数据格式,包括 ESRI shapefile、GeoJSON 文件等。geopandas.datasets.get_path(‘naturalearth_lowres’)则是从GeoPandas自带的数据集中获取世界地图的shapefile文件。数据样式如下:

这个数据列中,不仅有几何列geometry,还有其它属性列比如:pop_est(人口)、continent(大洲)、name(地区名称)、iso_a3(国别/地区三字码)、gdp_md_est()等

另外也可以将GeoDataFrame导出为ESRI shapefile、GeoJson、GeoPackage等地理空间文件类型:

world.to_file("countries.shp")
world.to_file("countries.geojson", driver='GeoJSON')
world.to_file("package.gpkg", layer='countries', driver="GPKG")

显示每个国家的中心点:

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world['centroid_column'] = world.centroid
# 将新增列设置为几何列
world = world.set_geometry('centroid_column') 
world.plot()
plt.show()

world.centroid返回一个GeoSeries,里面包含每个地区的中心点空间数据。.set_geometry函数则是将新增列设置为几何列,这样就会按照新的几何列显示地图。

按人口数量显示不同深度的颜色:

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
fig, ax = plt.subplots(1, 1)
world.plot(column= 'pop_est', ax=ax, legend=True)
plt.show()

column设置需要显示不同的列。legend=True设置是否显示颜色标尺。另外还可以设置显示颜色的色系: https://matplotlib.org/tutorials/colors/colormaps.html

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
fig, ax = plt.subplots(1, 1)
world.plot(column= 'pop_est', ax=ax, cmap='YlGn')
plt.show()

GeoPandas区域添加文字标签

当使用GeoPandas绘制区域数据时,有时期望给每天区域添加文字标签。GeoPandas本身不提供此功能。主要问题是无法确定文字标签应该添加到哪里。幸运的是GeoPandas提供了2个方法可以帮助我们来的文字标签的位置:

  • Centroid:返回每个多边形的中心点
  • representative point():返回多边形内的一个点,它保证在多边形的边界内,但不一定在中心

示例代码:

import geopandas as gpd
import adjustText as aT  # https://github.com/Phlya/adjustText
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['KaiTi']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

china = gpd.read_file("100000_full.json")
china["center"] = china["geometry"].centroid
# china["rep"] = china["geometry"].representative_point()
china_points = china.copy()
china_points.set_geometry("center", inplace=True)
# china_points.set_geometry("rep", inplace = True)

ax = china.plot(figsize=(15, 12), color="whitesmoke", edgecolor="lightgrey", linewidth=0.5)
texts = []

for x, y, label in zip(china_points.geometry.x, china_points.geometry.y, china_points["name"]):
    texts.append(plt.text(x, y, label, fontsize=8))

aT.adjust_text(texts, force_points=0.3, force_text=0.8, expand_points=(1, 1), expand_text=(1, 1),
               arrowprops=dict(arrowstyle="-", color='grey', lw=0.5))

参考链接:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注