Source code for nngt.geometry.plot

#!/usr/bin/env python
#-*- coding:utf-8 -*-
# This file is part of the PyNCulture project, which aims at providing tools to
# easily generate complex neuronal cultures.
# Copyright (C) 2017 SENeC Initiative
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <>.
# These tools are inspired by Sean Gillies' `descartes` library, that you can
# find here: They are released under
# a BSD license.

""" Plotting functions for shapely objects """

import numpy as np

from matplotlib.patches import PathPatch
from matplotlib.path import Path

[docs]def plot_shape(shape, axis=None, m='', mc="#999999", fc="#8888ff", ec="#444444", alpha=0.5, **kwargs): ''' Plot a shape (set the `axis` aspect to 1 to respect the proportions). Parameters ---------- shape : :class:`Shape` Shape to plot. axis : :class:`matplotlib.axes.Axes` instance, optional (default: None) Axis on which the shape should be plotted. By default, a new figure is created. m : str, optional (default: invisible) Marker to plot the shape's vertices, matplotlib syntax. mc : str, optional (default: "#999999") Color of the markers. fc : str, optional (default: "#8888ff") Color of the shape's interior. ec : str, optional (default: "#444444") Color of the shape's edges. alpha : float, optional (default: 0.5) Opacity of the shape's interior. kwargs: keywords arguments for :class:`matplotlib.patches.PathPatch` ''' if axis is None: import matplotlib.pyplot as plt fig, axis = plt.subplots() _plot_coords(axis, shape.exterior, m, mc, ec) for path in shape.interiors: _plot_coords(axis, path.coords, m, mc, ec) patch = _make_patch(shape, color=fc, alpha=alpha, zorder=0, **kwargs) axis.add_patch(patch) axis.set_aspect(1)
def _make_patch(shape, **kwargs): ''' Construct a matplotlib patch from a geometric object Parameters ---------- shape: :class:`NetGrowth.geometry.Shape` may be a Shapely or GeoJSON-like object with or without holes. kwargs: keywords arguments for :class:`matplotlib.patches.PathPatch` Returns ------- an instance of :class:`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) Modified from `descartes` by Sean Gillies (BSD license). ''' vertices = np.concatenate( [np.asarray(shape.exterior.coords)[:, :2]] + [np.asarray(h.coords)[:, :2] for h in shape.interiors]) instructions = np.concatenate( [_path_instructions(shape.exterior)] + [_path_instructions(h) for h in shape.interiors]) path = Path(vertices, instructions) return PathPatch(path, **kwargs) def _path_instructions(ob): ''' Give instructions to build path from vertices. ''' # The codes will be all "LINETO" commands, except for "MOVETO"s at the # beginning of each subpath n = len(ob.coords) vals = np.ones(n, dtype=Path.code_type) * Path.LINETO vals[0] = Path.MOVETO return vals def _plot_coords(ax, ob, m, mc, ec): x, y = ob.xy ax.plot(x, y, m, ls='-', c=ec, markerfacecolor=mc, zorder=1)