目录

上一个主题

9.2. GeoJSON

下一个主题

9.4. GeoPandas的用法

关注公众号


常见问题

  1. Windows下的安装说明
  2. Jupyter免费在线实验环境
  3. 勘误与补充


>>> from helper import info; info()
页面更新时间: 2020-02-21 18:14:53
操作系统/OS: Linux-4.19.0-8-amd64-x86_64-with-debian-10.3 ;Python: 3.7.3

9.3. Descartes

Descartes 是一个图像,数据和函数的绘图仪。 函数参数可以手动调整(或自动拟合,不过尚未实现)给定的xy数据。 高级脚本功能(尚未实现)由底层Python编程语言提供。

  • Descartes与平台无关; 它在Linux下及非自由操作系统下运行。

  • Descartes是开源软件; 它是免费分发的,受GNU公共许可证保护。

  • 所依赖的scipy 库 经历了重大的重组; 不再支持scipy.plt模块。

  • 程序的使用是相当直观的; 用户手册目前仅包含几个关于特殊主题的注释,例如数学公式和输入数据格式。

该程序可以在任何PC上运行。 唯一的要求是使用SciPy和wxPython模块完成Python安装。上述均可以在网上免费获得。

9.3.1. 数据输入

可以从CSV文件输入x-y数据。 虽然CSV最初是逗号分隔,但是descartes也允许使用分号,制表符和空格作为分隔符。 CSV文件的第一行可能包含用双引号括起来的x和y坐标的名字。

使用Shapely或GeoJSON类几何对象可作为matplotlib的路径和补丁。

Descartes 的安装与运行需要 Matplotlib,NumPy和可选择的Shapely 1.2+ 。

下面是导入库的例子:

>>> from matplotlib import pyplot
>>> from shapely.geometry import LineString
>>> from descartes import PolygonPatch

导入库:

>>> BLUE = '#6699cc'
>>> GRAY = '#999999'

分别给BLUE、GRAY赋颜色值。

>>>
>>> def plot_line(ax, ob):
>>>     x, y = ob.xy
>>>     ax.plot(x, y, color=GRAY, linewidth=3, solid_capstyle='round', zorder=1)

定义函数plot_line(变量1,变量2)。

>>>
>>> line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
>>>
>>> fig = pyplot.figure(1, figsize=(10, 4), dpi=180)
<Figure size 1800x720 with 0 Axes>

创建一幅图。

>>> ax = fig.add_subplot(121)

将图像分割成1行2列,将图像画在从左到右从上到下的第1块

>>>
>>>
>>> dilated = line.buffer(0.5)
>>> patch1 = PolygonPatch(dilated, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2)
>>> ax.add_patch(patch1)
>>>
>>>
>>> ax = fig.add_subplot(122)
>>>
>>> patch2a = PolygonPatch(dilated, fc=GRAY, ec=GRAY, alpha=0.5, zorder=1)
>>> ax.add_patch(patch2a)
>>>
>>> eroded = dilated.buffer(-0.3)
>>>
>>> # GeoJSON-like data works as well
>>>
>>> polygon = eroded.__geo_interface__
>>> patch2b = PolygonPatch(polygon, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2)
>>> ax.add_patch(patch2b)
>>>
>>> pyplot.show()

展示结果。

>>> from matplotlib import pyplot
>>> from shapely.geometry import *
>>>
>>> from descartes import PolygonPatch
>>>
>>>
>>> fig = pyplot.figure(num=1, figsize=(10, 4), dpi=180)
<Figure size 1800x720 with 0 Axes>

创建一个matplotlib图

>>>
>>> polygon = Point(0, 0).buffer(10.0).difference(
>>>     MultiPoint([(-5, 0), (5, 0)]).buffer(3.0))
>>>
>>> polygon
_images/others-descartes_17_0.svg

使用缓冲区和差分方法创建一个有2个孔的多边形

>>> ax = fig.add_subplot(221)

创建子图

>>>
>>> patch = PolygonPatch(polygon, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
>>>
<matplotlib.patches.PathPatch at 0x7fa130727278>

将多边形变成补丁,将其添加到子图中:

>>>
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)
>>>

在多边形边界周围绘制图形,渲染并保存:

>>> ax = fig.add_subplot(222)

创建子图

>>> geo = polygon.__geo_interface__
>>> patch = PolygonPatch(geo, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
<matplotlib.patches.PathPatch at 0x7fa1301f4cf8>

将赋值为1的多边形的GeoJSON-ish dict格式转换为补丁:

>>>
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)
>>>
>>>

在多边形边界周围绘制图形,渲染并保存:

>>>
>>> multipolygon = Point(0, 0).buffer(10.0).difference(
>>>     MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).union(
>>>     MultiPoint([(-10, 10), (10, -10)]).buffer(2.0))
>>>

使用缓冲区创建一个具有2个孔和2个卫星多边形的多边形,difference和union方法:

>>> ax = fig.add_subplot(223)

创建子图

>>>
>>> patch = PolygonPatch(multipolygon, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
>>>
<matplotlib.patches.PathPatch at 0x7fa1301934e0>

将多边形变成补丁并将其添加到子图中

>>>
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)
>>>

在多边形边界周围绘制图形,渲染并保存

>>> ax = fig.add_subplot(224)
>>>

创建子图

>>>
>>> geo = multipolygon.__geo_interface__
>>> patch = PolygonPatch(geo, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
>>>
<matplotlib.patches.PathPatch at 0x7fa1301b0e10>

将赋值为1的多边形的GeoJSON-ish dict格式转换为补丁

>>>
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)

在多边形边界周围绘制图形,渲染和保存

>>> %matplotlib inline
>>> from matplotlib import pyplot
>>> from shapely.geometry import *
>>>
>>> from descartes import PolygonPatch
>>>
>>> # Create a matplotlib figure
>>> fig = pyplot.figure(num=1, figsize=(10, 4), dpi=180)
>>>
>>> # Create a polygon with 2 holes using buffer and difference methods
>>> polygon = Point(0, 0).buffer(10.0).difference(
>>>     MultiPoint([(-5, 0), (5, 0)]).buffer(3.0))
>>>
>>> # 1
>>> # Create a subplot
>>> ax = fig.add_subplot(221)
>>>
>>> # Make the polygon into a patch and add it to the subplot
>>> patch = PolygonPatch(polygon, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
>>>
>>> # Fit the figure around the polygon's bounds, render, and save
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)
>>>
>>> # 2
>>> # Create a subplot
>>> ax = fig.add_subplot(222)
>>>
>>> # Turn the GeoJSON-ish dict form of the polygon from #1 into a patch
>>> geo = polygon.__geo_interface__
>>> patch = PolygonPatch(geo, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
>>>
>>> # Fit the figure around the polygon's bounds, render, and save
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)
>>>
>>>
>>> # Create a multi-polygon with 2 holes and 2 satelite polygons using buffer,
>>> #   difference and union methods
>>> multipolygon = Point(0, 0).buffer(10.0).difference(
>>>     MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).union(
>>>     MultiPoint([(-10, 10), (10, -10)]).buffer(2.0))
>>>
>>> # 3
>>> # Create a subplot
>>> ax = fig.add_subplot(223)
>>>
>>> # Make the polygon into a patch and add it to the subplot
>>> patch = PolygonPatch(multipolygon, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
>>>
>>> # Fit the figure around the polygon's bounds, render, and save
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)
>>>
>>> # 4
>>> # Create a subplot
>>> ax = fig.add_subplot(224)
>>>
>>> # Turn the GeoJSON-ish dict form of the polygon from #1 into a patch
>>> geo = multipolygon.__geo_interface__
>>> patch = PolygonPatch(geo, facecolor='#cccccc', edgecolor='#999999')
>>> ax.add_patch(patch)
>>>
>>> # Fit the figure around the polygon's bounds, render, and save
>>> minx, miny, maxx, maxy = polygon.bounds
>>> w, h = maxx - minx, maxy - miny
>>> ax.set_xlim(minx - 0.2*w, maxx + 0.2*w)
>>> ax.set_ylim(miny - 0.2*h, maxy + 0.2*h)
>>> ax.set_aspect(1)
>>>
>>>
>>> # fig.savefig('patches.png')
>>> pyplot.show()
_images/others-descartes_45_0.png

整合输出。

>>> from matplotlib import pyplot
>>> from shapely.geometry import LineString
>>> from descartes import PolygonPatch
>>>
>>> BLUE = '#6699cc'
>>> GRAY = '#999999'
>>>
>>> def plot_line(ax, ob):
>>>     x, y = ob.xy
>>>     ax.plot(x, y, color=GRAY, linewidth=3, solid_capstyle='round', zorder=1)
>>>
>>> line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
>>>
>>> fig = pyplot.figure(1, figsize=(10, 4), dpi=180)
>>>
>>> # 1
>>> ax = fig.add_subplot(121)
>>>
>>> plot_line(ax, line)
>>>
>>> dilated = line.buffer(0.5)
>>> patch1 = PolygonPatch(dilated, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2)
>>> ax.add_patch(patch1)
>>>
>>> #2
>>> ax = fig.add_subplot(122)
>>>
>>> patch2a = PolygonPatch(dilated, fc=GRAY, ec=GRAY, alpha=0.5, zorder=1)
>>> ax.add_patch(patch2a)
>>>
>>> eroded = dilated.buffer(-0.3)
>>>
>>> # GeoJSON-like data works as well
>>>
>>> polygon = eroded.__geo_interface__
>>>
>>> patch2b = PolygonPatch(polygon, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2)
>>> ax.add_patch(patch2b)
>>>
>>> pyplot.show()
_images/others-descartes_47_0.png