polylabel 1.0.2

A Rust implementation of the Polylabel algorithm
Documentation
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/sth/dev/rust-polylabel/venv/lib/python2.7/site-packages/matplotlib/__init__.py:913: UserWarning: axes.color_cycle is deprecated and replaced with axes.prop_cycle; please use the latter.\n",
      "  warnings.warn(self.msg_depr % (key, alt_key))\n"
     ]
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "from matplotlib.collections import PatchCollection\n",
    "from shapely.geometry import LineString, Polygon, Point, box, shape\n",
    "from shapely.algorithms.polylabel import polylabel\n",
    "from descartes import PolygonPatch\n",
    "\n",
    "import ast\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "initial_polygon = Polygon([\n",
    "    (0.0, 0.0),\n",
    "    (4.0, 0.0),\n",
    "    (4.0, 1.0),\n",
    "    (1.0, 1.0),\n",
    "    (1.0, 4.0),\n",
    "    (0.0, 4.0),\n",
    "    (0.0, 0.0)\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# eval 😱 – but it's safe\n",
    "with open('nodes.txt', 'r') as f:\n",
    "    quad_polygons = [box(*tup) for tup in map(ast.literal_eval, f)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "save_args = {\n",
    "    \"format\": \"png\",\n",
    "    \"bbox_inches\": 'tight',\n",
    "    \"pad_inches\": 0,\n",
    "    \"alpha\": True,\n",
    "    \"transparent\": True,\n",
    "    \"dpi\": 300\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nAFAIJgCAQjABABSCCQCgEEwAAIVgAgAoBBMAQCGYAAAKwQQAUAgmAIBCMAEAFIIJAKAQTAAAhWAC\nACgEEwBAIZgAAArBBABQCCYAgEIwAQAUggkAoBBMAACFYAIAKAQTAEAhmAAACsEEAFAIJgCAQjAB\nABSCCQCgEEwAAIVgAgAoBBMAQCGYAAAKwQQAUAgmAIBCMAEAFIIJAKAQTAAAhWACACgEEwBAIZgA\nAArBBABQCCYAgEIwAQAUx+cecBg+l+w8NcbO3DuW5elk69kkzyTbF8bYiOj9dLL9ZJLnk+2nxrg2\n955l2cRj/RvJ9vkkLyTb3+95vdY8rzfmWK/F83hM0zT3hgMZY+ycTt6+nOQDSd6ce9ASLZJ8KcnD\nSXZn3rIsDyR5OcljSd6aecsybeKxfjjJ/03y7dl77JtiE4+15/XmHOuzSV5K8nzyyJPTdHHuPQex\nssGUJBljMSVXx9w7AIDqU8mDPz5NK3mOY7WDKcmnxjj7zcnW3DuW7Z4kN+YesWT3JfmLuUfMYBOP\n9U6Sr849YgabeKw9rzfHF5N3Ppq8Na1oeKx8MAEAHLVNeLMZAMBdEUwAAIVgAgAoBBMAQCGYAAAK\nwQQAUAgmAIBCMAEAFIIJAKAQTAAAhWACACgEEwBAIZgAAArBBABQCCYAgEIwAQAUggkAoBBMAACF\nYAIAKAQTAEAhmAAACsEEAFAIJgCAQjABABSCCQCgEEwAAIVgAgAoBBMAQCGYAAAKwQQAUAgmAIBC\nMAEAFIIJAKAQTAAAhWACACgEEwBAIZgAAArBBABQCCYAgEIwAQAUggkAoBBMAACFYAIAKAQTAEAh\nmAAAir8ENgmTpp6+1dwAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x107caac50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure(1, figsize=(5., 5.), dpi=300)\n",
    "ax = fig.add_subplot(121)\n",
    "ax.set_aspect('equal')\n",
    "ax.get_xaxis().set_visible(False)\n",
    "ax.get_yaxis().set_visible(False)\n",
    "ax.axis('off')\n",
    "ax.set_xlim(-0.15, 4.15)\n",
    "ax.set_ylim(-0.15, 4.15)\n",
    "\n",
    "# add initial polygon\n",
    "ax.add_patch(PolygonPatch(initial_polygon, fc='None', ec='#000000', lw=0.5, alpha=1.0, zorder=2))\n",
    "# add centroid as dot patch\n",
    "ax.add_patch(PolygonPatch(Point(1.3571, 1.3571).buffer(.025), lw=0.25, fc='#ffa500', ec='#000000', zorder=4))\n",
    "plt.savefig(\"data/polylabel_000.png\", **save_args)\n",
    "\n",
    "# build patches as needed\n",
    "ppatches = (PolygonPatch(poly, fc='None', ec='#ff0000', alpha=1.0, zorder=3, lw=0.25) for poly in quad_polygons)\n",
    "\n",
    "# consume consume\n",
    "for i in xrange(1, len(quad_polygons) + 1):\n",
    "    ax.add_patch(ppatches.next())\n",
    "    plt.savefig(\"data/polylabel_{:03d}.png\".format(i), **save_args)\n",
    "\n",
    "# add pole of inaccessibility as patch\n",
    "ax.add_patch(PolygonPatch(Point(0.5625, 0.5625).buffer(.025), lw=0.25, fc='#00b3b3', ec='#000000', zorder=4))\n",
    "\n",
    "# save final plot\n",
    "plt.savefig(\"data/polylabel_{:03d}.png\".format(i + 1), **save_args)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "convert -background white -alpha remove -layers OptimizePlus -set delay 20 -colors 512 -loop 0 -scale 100% data/*.png output.gif\n",
    "convert output.gif \\( +clone -set delay 300 \\) +swap +delete  output.gif"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}