Descartes

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

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

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

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

最新稳定版本是0.7(2005年7月10日)。

适配和脚本功能尚未实现。

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

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

数据输入

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

使用几何对象作为matplotlib路径和补丁。

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

Descartes需要:matplotlib,numpy和可选择的Shapely 1.2+。

下面是导入库的例子:

In [1]:
from matplotlib import pyplot
from shapely.geometry import LineString
from descartes import PolygonPatch

导入库:

In [2]:
BLUE = '#6699cc'
GRAY = '#999999'

分别给BLUE、GRAY赋颜色值。

In [3]:
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)。

In [4]:
            
line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])

fig = pyplot.figure(1, figsize=(10, 4), dpi=180)

创建一幅图。

In [5]:
ax = fig.add_subplot(121)

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

In [6]:
# plot_l 5555555ine(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)
In [7]:
# GeoJSON-like data works as well

polygon = eroded.__geo_interface__
# >>> geo['type']
# 'Polygon'
# >>> geo['coordinates'][0][:2]
# ((0.50502525316941682, 0.78786796564403572), (0.5247963548222736, 0.8096820147509064))
patch2b = PolygonPatch(polygon, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2)
ax.add_patch(patch2b)

pyplot.show()

展示结果。

In [8]:
from matplotlib import pyplot
from shapely.geometry import *

from descartes import PolygonPatch


fig = pyplot.figure(num=1, figsize=(10, 4), dpi=180)

创建一个matplotlib图

In [25]:
polygon = Point(0, 0).buffer(10.0).difference(
    MultiPoint([(-5, 0), (5, 0)]).buffer(3.0))

polygon
Out[25]:

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

In [29]:
# 1

ax = fig.add_subplot(221)

创建子图

In [11]:
patch = PolygonPatch(polygon, facecolor='#cccccc', edgecolor='#999999')
ax.add_patch(patch)
Out[11]:
<matplotlib.patches.PathPatch at 0x7fbe8d3fd240>

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

In [12]:
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)

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

In [13]:
# 2

ax = fig.add_subplot(222)

创建子图

In [14]:
geo = polygon.__geo_interface__
patch = PolygonPatch(geo, facecolor='#cccccc', edgecolor='#999999')
ax.add_patch(patch)
Out[14]:
<matplotlib.patches.PathPatch at 0x7fbe8dce2c18>

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

In [15]:
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)

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

In [16]:
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方法:

In [17]:
# 3

ax = fig.add_subplot(223)

创建子图

In [18]:
patch = PolygonPatch(multipolygon, facecolor='#cccccc', edgecolor='#999999')
ax.add_patch(patch)
Out[18]:
<matplotlib.patches.PathPatch at 0x7fbe8dc35e80>

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

In [19]:
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)

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

In [20]:
# 4
# Create a subplot
ax = fig.add_subplot(224)

创建子图

In [21]:
geo = multipolygon.__geo_interface__
patch = PolygonPatch(geo, facecolor='#cccccc', edgecolor='#999999')
ax.add_patch(patch)
Out[21]:
<matplotlib.patches.PathPatch at 0x7fbe8dc016a0>

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

In [22]:
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)

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

In [23]:
%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()

整合输出。

In [24]:
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__
# >>> geo['type']
# 'Polygon'
# >>> geo['coordinates'][0][:2]
# ((0.50502525316941682, 0.78786796564403572), (0.5247963548222736, 0.8096820147509064))
patch2b = PolygonPatch(polygon, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2)
ax.add_patch(patch2b)

pyplot.show()
In [ ]: