Skip to content

Instantly share code, notes, and snippets.

@pelson
Last active August 31, 2018 09:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pelson/5048998e98a0fbe46df30d38cf0676a6 to your computer and use it in GitHub Desktop.
Save pelson/5048998e98a0fbe46df30d38cf0676a6 to your computer and use it in GitHub Desktop.
A notebook to answer a StackOverflow question (https://stackoverflow.com/questions/51801109) relating to animating the rotation of a projecton using cartopy
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A notebook to answer a [StackOverflow question](https://stackoverflow.com/questions/51801109/animate-a-point-between-two-points-along-with-rotating-earth) relating to animating the rotation of a projecton using cartopy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib notebook"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import cartopy.crs as ccrs\n",
"import cartopy.feature as cfeature\n",
"import matplotlib.animation as animation\n",
"import matplotlib.image as mimage\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib.transforms as mtransforms\n",
"import numpy as np\n",
"import shapely.geometry as sgeom\n",
"\n",
"\n",
"plt.figure(figsize=(6, 6))\n",
"\n",
"line = sgeom.LineString([[0, 15], [-140, -40], [120, -20],\n",
" [0, -20], [-140, 15], [90, 45],\n",
" [0, 15]])\n",
"\n",
"\n",
"class HighResPC(ccrs.PlateCarree):\n",
" @property\n",
" def threshold(self):\n",
" return super(HighResPC, self).threshold / 100\n",
"\n",
"\n",
"projected_line = HighResPC().project_geometry(line, ccrs.Geodetic())\n",
"\n",
"\n",
"verts = np.concatenate([np.array(l.coords) for l in projected_line])\n",
"\n",
"\n",
"def setup_axes(ax, x, y):\n",
" ax.set_global()\n",
"\n",
" ax.add_feature(cfeature.LAND)\n",
" ax.add_feature(cfeature.OCEAN)\n",
" \n",
" # Add the projected line to the map.\n",
" ax.add_geometries(\n",
" [projected_line], HighResPC(),\n",
" edgecolor='blue', facecolor='none')\n",
"\n",
" # Image from http://madmen.wikia.com/wiki/File:Superman.gif.\n",
" superman = plt.imread('superman.png')\n",
" \n",
" # Scale the actual image down a little.\n",
" img_size = np.array(superman.shape) / 2\n",
" \n",
" x, y = ax.projection.transform_point(x, y, ccrs.PlateCarree())\n",
" # Convert the projected coordinates into pixels.\n",
" x_pix, y_pix = ax.transData.transform((x, y))\n",
" \n",
" # Make the extent handle the appropriate image size.\n",
" extent = [x_pix - 0.5 * img_size[1], y_pix - 0.5 * img_size[0],\n",
" x_pix + 0.5 * img_size[1], y_pix + 0.5 * img_size[0]]\n",
" \n",
" bbox = mtransforms.Bbox.from_extents(extent)\n",
" img = mimage.BboxImage(bbox, zorder=10)\n",
" img.set_data(superman)\n",
" ax.add_artist(img)\n",
" \n",
" return img\n",
"\n",
" \n",
"def animate_superman(i):\n",
" i = i % verts.shape[0]\n",
" \n",
" ax = plt.gca()\n",
" ax.remove()\n",
" \n",
" ax = plt.axes([0, 0, 1, 1], projection=ccrs.Orthographic(\n",
" central_latitude=verts[i, 1], central_longitude=verts[i, 0]))\n",
" ax.coastlines()\n",
"\n",
" img = setup_axes(ax, verts[i, 0], verts[i, 1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ani = animation.FuncAnimation(\n",
" plt.gcf(), animate_superman,\n",
" frames=verts.shape[0],\n",
" interval=125, repeat=False)\n",
"\n",
"ani.save('superman.gif', writer='imagemagick', dpi=plt.gcf().dpi)\n",
"\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment