descartes-1.1.0/0000755000076500000240000000000013037434332013541 5ustar seanstaff00000000000000descartes-1.1.0/descartes/0000755000076500000240000000000013037434332015516 5ustar seanstaff00000000000000descartes-1.1.0/descartes/__init__.py0000644000076500000240000000014012661655717017640 0ustar seanstaff00000000000000"""Turn geometric objects into matplotlib patches""" from descartes.patch import PolygonPatch descartes-1.1.0/descartes/patch.py0000644000076500000240000000545413037434201017172 0ustar seanstaff00000000000000"""Paths and patches""" from matplotlib.patches import PathPatch from matplotlib.path import Path from numpy import asarray, concatenate, ones class Polygon(object): # Adapt Shapely or GeoJSON/geo_interface polygons to a common interface def __init__(self, context): if isinstance(context, dict): self.context = context['coordinates'] else: self.context = context @property def exterior(self): return (getattr(self.context, 'exterior', None) or self.context[0]) @property def interiors(self): value = getattr(self.context, 'interiors', None) if value is None: value = self.context[1:] return value def PolygonPath(polygon): """Constructs a compound matplotlib path from a Shapely or GeoJSON-like geometric object""" def coding(ob): # The codes will be all "LINETO" commands, except for "MOVETO"s at the # beginning of each subpath n = len(getattr(ob, 'coords', None) or ob) vals = ones(n, dtype=Path.code_type) * Path.LINETO vals[0] = Path.MOVETO return vals if hasattr(polygon, 'geom_type'): # Shapely ptype = polygon.geom_type if ptype == 'Polygon': polygon = [Polygon(polygon)] elif ptype == 'MultiPolygon': polygon = [Polygon(p) for p in polygon] else: raise ValueError( "A polygon or multi-polygon representation is required") else: # GeoJSON polygon = getattr(polygon, '__geo_interface__', polygon) ptype = polygon["type"] if ptype == 'Polygon': polygon = [Polygon(polygon)] elif ptype == 'MultiPolygon': polygon = [Polygon(p) for p in polygon['coordinates']] else: raise ValueError( "A polygon or multi-polygon representation is required") vertices = concatenate([ concatenate([asarray(t.exterior)[:, :2]] + [asarray(r)[:, :2] for r in t.interiors]) for t in polygon]) codes = concatenate([ concatenate([coding(t.exterior)] + [coding(r) for r in t.interiors]) for t in polygon]) return Path(vertices, codes) def PolygonPatch(polygon, **kwargs): """Constructs a matplotlib patch from a geometric object The `polygon` may be a Shapely or GeoJSON-like object with or without holes. The `kwargs` are those supported by the matplotlib.patches.Polygon class constructor. Returns an instance of matplotlib.patches.PathPatch. Example (using Shapely Point and a matplotlib axes): >>> b = Point(0, 0).buffer(1.0) >>> patch = PolygonPatch(b, fc='blue', ec='blue', alpha=0.5) >>> axis.add_patch(patch) """ return PathPatch(PolygonPath(polygon), **kwargs) descartes-1.1.0/descartes/tests.py0000644000076500000240000000612613037433421017235 0ustar seanstaff00000000000000from shapely.geometry import Point, MultiPoint import unittest from descartes.patch import PolygonPatch class PolygonTestCase(unittest.TestCase): polygon = Point(0, 0).buffer(10.0).difference( MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)) def test_patch(self): patch = PolygonPatch(self.polygon) self.failUnlessEqual( str(type(patch)), "") path = patch.get_path() self.failUnless(len(path.vertices) == len(path.codes) == 198) class JSONPolygonTestCase(unittest.TestCase): polygon = Point(0, 0).buffer(10.0).difference( MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)) def test_patch(self): geo = self.polygon.__geo_interface__ patch = PolygonPatch(geo) self.failUnlessEqual( str(type(patch)), "") path = patch.get_path() self.failUnless(len(path.vertices) == len(path.codes) == 198) class GeoInterfacePolygonTestCase(unittest.TestCase): class GeoThing: __geo_interface__ = None thing = GeoThing() thing.__geo_interface__ = Point(0, 0).buffer(10.0).difference( MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).__geo_interface__ def test_patch(self): patch = PolygonPatch(self.thing) self.failUnlessEqual( str(type(patch)), "") path = patch.get_path() self.failUnless(len(path.vertices) == len(path.codes) == 198) class MultiPolygonTestCase(unittest.TestCase): polygon = Point(0, 0).buffer(10.0) .difference( MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).union( MultiPoint([(-10, 10), (10, -10)]).buffer(2.0)) def test_patch(self): patch = PolygonPatch(self.polygon) self.failUnlessEqual( str(type(patch)), "") path = patch.get_path() self.failUnless(len(path.vertices) == len(path.codes) == 330) class JSONMultiPolygonTestCase(unittest.TestCase): polygon = Point(0, 0).buffer(10.0).difference( MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).union( MultiPoint([(-10, 10), (10, -10)]).buffer(2.0)) def test_patch(self): geo = self.polygon.__geo_interface__ patch = PolygonPatch(geo) self.failUnlessEqual( str(type(patch)), "") path = patch.get_path() self.failUnless(len(path.vertices) == len(path.codes) == 330) class GeoInterfaceMultiPolygonTestCase(unittest.TestCase): class GeoThing: __geo_interface__ = None thing = GeoThing() thing.__geo_interface__ = Point(0, 0).buffer(10.0).difference( MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).union( MultiPoint([(-10, 10), (10, -10)]).buffer(2.0)).__geo_interface__ def test_patch(self): patch = PolygonPatch(self.thing) self.failUnlessEqual( str(type(patch)), "") path = patch.get_path() self.failUnless(len(path.vertices) == len(path.codes) == 330) descartes-1.1.0/descartes.egg-info/0000755000076500000240000000000013037434332017210 5ustar seanstaff00000000000000descartes-1.1.0/descartes.egg-info/dependency_links.txt0000644000076500000240000000000113037434332023256 0ustar seanstaff00000000000000 descartes-1.1.0/descartes.egg-info/not-zip-safe0000644000076500000240000000000112661655761021453 0ustar seanstaff00000000000000 descartes-1.1.0/descartes.egg-info/PKG-INFO0000644000076500000240000000550113037434332020306 0ustar seanstaff00000000000000Metadata-Version: 1.1 Name: descartes Version: 1.1.0 Summary: Use geometric objects as matplotlib paths and patches Home-page: http://bitbucket.org/sgillies/descartes/ Author: Sean Gillies Author-email: sean.gillies@gmail.com License: BSD Description: Descartes ========= Use Shapely_ or GeoJSON-like geometric objects as matplotlib paths and patches .. image:: http://farm4.static.flickr.com/3662/4555372019_9bbed1f956_o_d.png :width: 800 :height: 320 Requires: matplotlib, numpy, and optionally Shapely 1.2+. Example:: 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() See also: examples/patches.py. Descartes is not associated with the identically named and apparently defunct project at http://descartes.sourceforge.net/. .. _Shapely: http://gispython.org/lab/wiki/Shapely Keywords: matplotlib gis geojson geometry Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Scientific/Engineering :: GIS descartes-1.1.0/descartes.egg-info/requires.txt0000644000076500000240000000001313037434332021602 0ustar seanstaff00000000000000matplotlib descartes-1.1.0/descartes.egg-info/SOURCES.txt0000644000076500000240000000043513037434332021076 0ustar seanstaff00000000000000README.txt setup.cfg setup.py descartes/__init__.py descartes/patch.py descartes/tests.py descartes.egg-info/PKG-INFO descartes.egg-info/SOURCES.txt descartes.egg-info/dependency_links.txt descartes.egg-info/not-zip-safe descartes.egg-info/requires.txt descartes.egg-info/top_level.txtdescartes-1.1.0/descartes.egg-info/top_level.txt0000644000076500000240000000001213037434332021733 0ustar seanstaff00000000000000descartes descartes-1.1.0/PKG-INFO0000644000076500000240000000550113037434332014637 0ustar seanstaff00000000000000Metadata-Version: 1.1 Name: descartes Version: 1.1.0 Summary: Use geometric objects as matplotlib paths and patches Home-page: http://bitbucket.org/sgillies/descartes/ Author: Sean Gillies Author-email: sean.gillies@gmail.com License: BSD Description: Descartes ========= Use Shapely_ or GeoJSON-like geometric objects as matplotlib paths and patches .. image:: http://farm4.static.flickr.com/3662/4555372019_9bbed1f956_o_d.png :width: 800 :height: 320 Requires: matplotlib, numpy, and optionally Shapely 1.2+. Example:: 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() See also: examples/patches.py. Descartes is not associated with the identically named and apparently defunct project at http://descartes.sourceforge.net/. .. _Shapely: http://gispython.org/lab/wiki/Shapely Keywords: matplotlib gis geojson geometry Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Scientific/Engineering :: GIS descartes-1.1.0/README.txt0000644000076500000240000000311212661655717015252 0ustar seanstaff00000000000000Descartes ========= Use Shapely_ or GeoJSON-like geometric objects as matplotlib paths and patches .. image:: http://farm4.static.flickr.com/3662/4555372019_9bbed1f956_o_d.png :width: 800 :height: 320 Requires: matplotlib, numpy, and optionally Shapely 1.2+. Example:: 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() See also: examples/patches.py. Descartes is not associated with the identically named and apparently defunct project at http://descartes.sourceforge.net/. .. _Shapely: http://gispython.org/lab/wiki/Shapely descartes-1.1.0/setup.cfg0000644000076500000240000000007313037434332015362 0ustar seanstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 descartes-1.1.0/setup.py0000644000076500000240000000226113037432655015262 0ustar seanstaff00000000000000import os import sys import warnings from setuptools import setup, find_packages version = '1.1.0' description = open('README.txt', 'r').read() setup(name='descartes', version=version, description="Use geometric objects as matplotlib paths and patches", long_description=description, classifiers=['Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', 'Topic :: Scientific/Engineering :: GIS'], keywords='matplotlib gis geojson geometry', author='Sean Gillies', author_email='sean.gillies@gmail.com', url='http://bitbucket.org/sgillies/descartes/', license='BSD', packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), include_package_data=True, install_requires=['matplotlib'], zip_safe=False)