data-science-ipython-notebooks/matplotlib/04.12-Three-Dimensional-Plotting.ipynb

601 lines
647 KiB
Python
Raw Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!--BOOK_INFORMATION-->\n",
"<img align=\"left\" style=\"padding-right:10px;\" src=\"figures/PDSH-cover-small.png\">\n",
"*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n",
"\n",
"*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n",
"\n",
"*No changes were made to the contents of this notebook from the original.*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!--NAVIGATION-->\n",
"< [Customizing Matplotlib: Configurations and Stylesheets](04.11-Settings-and-Stylesheets.ipynb) | [Contents](Index.ipynb) | [Geographic Data with Basemap](04.13-Geographic-Data-With-Basemap.ipynb) >"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Three-Dimensional Plotting in Matplotlib"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Matplotlib was initially designed with only two-dimensional plotting in mind.\n",
"Around the time of the 1.0 release, some three-dimensional plotting utilities were built on top of Matplotlib's two-dimensional display, and the result is a convenient (if somewhat limited) set of tools for three-dimensional data visualization.\n",
"three-dimensional plots are enabled by importing the ``mplot3d`` toolkit, included with the main Matplotlib installation:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from mpl_toolkits import mplot3d"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once this submodule is imported, a three-dimensional axes can be created by passing the keyword ``projection='3d'`` to any of the normal axes creation routines:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nRAPaGwicvOtuJE6I+Iq
"text/plain": [
"<matplotlib.figure.Figure at 0x10bfc8780>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"ax = plt.axes(projection='3d')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With this three-dimensional axes enabled, we can now plot a variety of three-dimensional plot types. \n",
"Three-dimensional plotting is one of the functionalities that benefits immensely from viewing figures interactively rather than statically in the notebook; recall that to use interactive figures, you can use ``%matplotlib notebook`` rather than ``%matplotlib inline`` when running this code."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Three-dimensional Points and Lines\n",
"\n",
"The most basic three-dimensional plot is a line or collection of scatter plot created from sets of (x, y, z) triples.\n",
"In analogy with the more common two-dimensional plots discussed earlier, these can be created using the ``ax.plot3D`` and ``ax.scatter3D`` functions.\n",
"The call signature for these is nearly identical to that of their two-dimensional counterparts, so you can refer to [Simple Line Plots](04.01-Simple-Line-Plots.ipynb) and [Simple Scatter Plots](04.02-Simple-Scatter-Plots.ipynb) for more information on controlling the output.\n",
"Here we'll plot a trigonometric spiral, along with some points drawn randomly near the line:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAV0AAADtCAYAAAAcNaZ2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXl8VdW597/7zEPmBEKAEOZ5UsABcUCccKooOEvrUO/t\nqFf7tlbfe1vf21otVWur1tpa56H0tioiDqCCICogCAiEQaYEyJyck5z5nL3fP3LXZmdnn+RMCQTP\n7/PJR8yw9lr77P1bz3qG3yMpikIWWWSRRRa9A9OxnkAWWWSRxTcJWdLNIosssuhFZEk3iyyyyKIX\nkSXdLLLIIoteRJZ0s8giiyx6EVnSzSKLLLLoRVi6+Xk2nyyLLLLIInlI8X6QtXSzyCKLLHoRWdLN\nIosssuhFZEk3iyyyyKIXkSXdLLLIIoteRJZ0s8giiyx6EVnSzSKLLLLoRWRJN4ssssiiF5El3Syy\nyCKLXkSWdLPIIossehFZ0s0iiyyy6EVkSTeLLLLIoheRJd0sssgii15ElnSzSBuyLBONRsn228si\ni+7RncpYFlkYQlEUFEUhEokQDoeJRqNIUruwktlsxmq1YjabMZlMmEwm9WdZZPFNR5Z0s0gKWrL1\n+XyYTCYsFguSJGEymQiFQkSjUWKxWIe/M5lMmM1m9StLxll8UyF1cyTMnhezADqSrSzLAPj9fmRZ\nJhaLoSiKSqCSJGG1WlVi1Y+hRZaMszhBEfcBzpJuFl1CURTVZyvLMpIkIcsyoVCIYDCI2WzG6XSq\nlm04HFYJWJZl9d+CTAWxaklV+3sCWTLOoo8jS7pZJId4ZBsMBgmHw9hsNqCdHK1WK9FoVHUvSJKk\n/lyMo/9SFEUlUu2XIFVhFRuRsSBki8WSJeMsjlfEfSCzPt0sOkBRFGKxmJqNoLVsw+Ewdrud/Px8\nTCYTgUCgEymKMQQkSVKtVf3vaElYuC2MyFiSpA5kHAwGicVi2O12dTzhWxZWsdls7vB3WWRxvCBL\nulkAxmSrKAp+v59IJNKBbLuC+LvukA4Zi/H1ZKx1bQjoXRRZMs7iWCNLut9wdEe2DocDl8vVLdlm\nComQsZirsLS7soz1gT7xXy0Za/3MWTLOoqeRJd1vKATZ+nw+1T8qyzKBQIBoNIrD4cDtdndLQr1V\nEKEn41gshsPhSNpNITYPo6wLIEvGWfQ4sqT7DYOiKGoerTiS22w2gsGgSrY5OTkJkczxQESZ9hkL\nMob2TAwRrBPX0Afvjod7kEXfQpZ0vyEQZBuNRoF2sorFYsRiMQKBAE6nM2Gy7QvoioxjsVgHV4XI\nO9amtJlMJmRZ7vDvWCxGOBzuMF6WjLNIFlnSPcGhJ1tAJVpBKg6Ho0MmQCauebxCkiQslo6PvUhN\nE0Qci8WIRCKq31hLxFpiFX+jJ2PhxsiScRZGyJLuCQojso1GowSDQWRZxul0YrPZaGtrS5kIjDIV\n+iKpCDLUBwt9Pp+6GWnJWOQtx8szzpJxFl0hS7onGOKRbSAQAMDhcGCz2TqU7KZjmYrrRSIRLBZL\nr1m5vXEdQYZGLgojyzhVMo7FYlitVkORoCwZn3jIku4JAvEyxyNbp9OJ1WrN2EusJfdYLIYkSYRC\nIdU/GggE4labpYveIiKjwg9xfSPLOFUyDgaDqt9Yfx2jUujeSt/LomeQJd0+DhEM0qp6RSIRgsEg\n0D3ZJmvpCtEbbY5sTk4OkUgEk8lEOBxWLbdkiOdEQKpkLDYwLbEK6DdScR29i0IUfWRx/CNLun0U\ngmyFFoLb7VbJ0GQy9YhlK8aHdjIXKWfaawjiSTRYJYhHb8mdSEfr7sjY7/er2STdbVACejIWG6CW\njI3EhbI49siSbh+DNudUIBaL4fV6MZlMuN1uVd82EXRn6RqRrSBzffpUV+N1RTyJ5tOeaASi3Vi0\nfnZBxiK1TaS1JaLYZlRdqCXjrGLbsUeWdPsAjLRsoT15X5BhTk4OVqs1o9eMR7aZRCrFDWIO4XD4\nhPRz9sQGFYvFVItaPCfi97Jk3LvIku5xjHhkK7RsLRYLTqeTUCiUMcJNhmzTzXzoCl2RcSQSUfNo\nw+HwN8JfDOlX3ymKopKrgJHPWFuBlyXjzCNLusch9Fq2Alqyzc3NxWKxEI1GCYVCKV9LEGe6lm1v\nvZBachU5tKlmDRwPyMSmlSgZi01Kf0IwuiciDVCLLBlnBlnSPY5gJByuKAqhUEi1ZvPy8jq8XJnI\nsxU+Yeg5N0JPIhMpXMda8rEnrqsnY1mW1VzgVN0UWTJOH1nSPQ4QT14xGAzGJdtMXDMcDqtWstvt\nTppse9K9kAkkQsbivgstXv1xXBD0iUQgmRAJ6o6Mo9EoVqtV9RdnyfgosqR7DKH1T2qrlgTZ2my2\nbsk2lTxbEYCTpPa2OoqiqO11MoHjmYihIxlrU9v0pAPtLp2uSOdEIpBMknEkElHbOOnTCr/plnGW\ndI8BtJatsDZzcnLw+/2q1GIiXRqSvaYgW21qmWiZng70ebp9FXrSiUQiuFwugG5JJ1XyiFf11hNI\n9VrdkbE+tU1A7zvWxw++qWScJd1ehJEbAdojyB6PJ+GWOFokkmdrRLZa7YV019TW1tbJWo/FYifM\nCxOPdLRE3JeCd5mC0X3RFnyYTKZOMYp496U7MtYXfPTl+5kl3V5APJ+taIkDpG3Z6q2Y7sg2XUSj\nUfx+P7IsY7fbVbEbodErdBhOZAIyyg9ONpOiN9EbVrV2fK3LKh2RIPEs6+evzzE+1sHQRJEl3R6E\nqKnX9+jS9h9zOBy0tbWl/ALqH7BkyTZZn7AoPRbNKkXbnFAopD70sVgMl8v1jSz9TSaTQhAJoIre\nnAj3wojcM5FhEo+Mg8EgNpsNk8nE5s2b2bNnD7feemtvLjkpZEm3B6BV4IL2By5e/zGtUE261+xJ\ny1YIn4vNwu12I8uyWgocr3giE5VVvW0R9gTi3QuRZy3SuBIJUvVVMjZCJshYW+p86NAhGhsbj9Fq\nEkOWdDMII7IVZBWv/1gm8myBDtoLyVSndXd9I7LV+oON/ra79SQaJY9XbSZeyBMBgnT0n1lPbEy9\nFbTLxHWSIWNolxK9+uqrMZlMuFwuBg4cyIQJE5gwYULSmTm33norS5cupbS0lC1btqjf/+Mf/8iT\nTz6JxWLhkksu4cEHH0xtbd08vCfGk93DMCJbcQwXx2+73W74ICqKQnNzM0VFRUlfU1i2siyTk5OT\nUtqXqELLy8vr8H092Tocjk7zl2UZj8dDQUGBGvwQFr3b7U56LkbQv2TiRRMvtpZ0Mu3Ta2trS6gj\ncjoQ/m+RJdEd9IQj/p2I77w31gPJrykdKIqCz+fD5XKxZ88eXnjhBWpqagDYtm0bL774IieddFJS\nY65Zs4acnBwWLlyoku7KlSt54IEHWLZsGRaLhYaGBkpKSroaJu5Nzlq6aUCWZTVgJHZkbf+xZDrr\nJmodiAo14QN0u91qG/VMQE+2LpfrmB7vjSwekWrncDi6LXBI9Vh+vFrS2lOCsI4TPYpD++fb09q7\nvZkGJ2AymRg9ejQul4tbbrmFCy+8MOWxZs2axYEDBzp8709/+hP33HOPmtfdDeF2iSzppgDti+7z\n+dQIqr7/WCIPXqIPpxHZipcuHReFNsVLaPOmkrrW29CSSVcFDunm1PY0efTWUVzbVv54LINOFfr7\n19raSkFBQcavs2vXLj7++GPuvfdenE4nixYtYvr06SmNlSXdJCByDrXBL0GGkiR16j+WKATxxXM/\nxCPbTECQk9frTZps0/VH9wS68heL43gyYuF9GVoyNpvNarGHIGNtUUOmTwnHquDD6/WSn5+f8etE\no1Gam5v57LPPWL9+PVdffTV79+5Naaws6SYAI7IV/ceEiEg6vjIj8tKSrdls7pJsUyE/4XsVL1tB\nQcEJQzZGkKTku1lAx6qqvmgJCmjJKVNZJfHux7HciD0eD4WFhRkft7y8nCuvvBKAGTNmYDKZaGxs\npLi4OOmxsqQbB9oKGW1
"text/plain": [
"<matplotlib.figure.Figure at 0x10e2fd898>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ax = plt.axes(projection='3d')\n",
"\n",
"# Data for a three-dimensional line\n",
"zline = np.linspace(0, 15, 1000)\n",
"xline = np.sin(zline)\n",
"yline = np.cos(zline)\n",
"ax.plot3D(xline, yline, zline, 'gray')\n",
"\n",
"# Data for three-dimensional scattered points\n",
"zdata = 15 * np.random.random(100)\n",
"xdata = np.sin(zdata) + 0.1 * np.random.randn(100)\n",
"ydata = np.cos(zdata) + 0.1 * np.random.randn(100)\n",
"ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that by default, the scatter points have their transparency adjusted to give a sense of depth on the page.\n",
"While the three-dimensional effect is sometimes difficult to see within a static image, an interactive view can lead to some nice intuition about the layout of the points."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Three-dimensional Contour Plots\n",
"\n",
"Analogous to the contour plots we explored in [Density and Contour Plots](04.04-Density-and-Contour-Plots.ipynb), ``mplot3d`` contains tools to create three-dimensional relief plots using the same inputs.\n",
"Like two-dimensional ``ax.contour`` plots, ``ax.contour3D`` requires all the input data to be in the form of two-dimensional regular grids, with the Z data evaluated at each point.\n",
"Here we'll show a three-dimensional contour diagram of a three-dimensional sinusoidal function:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def f(x, y):\n",
" return np.sin(np.sqrt(x ** 2 + y ** 2))\n",
"\n",
"x = np.linspace(-6, 6, 30)\n",
"y = np.linspace(-6, 6, 30)\n",
"\n",
"X, Y = np.meshgrid(x, y)\n",
"Z = f(X, Y)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nZ6nqleSExsbGFhKD5OS
"text/plain": [
"<matplotlib.figure.Figure at 0x10e6a7fd0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"ax = plt.axes(projection='3d')\n",
"ax.contour3D(X, Y, Z, 50, cmap='binary')\n",
"ax.set_xlabel('x')\n",
"ax.set_ylabel('y')\n",
"ax.set_zlabel('z');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sometimes the default viewing angle is not optimal, in which case we can use the ``view_init`` method to set the elevation and azimuthal angles. In the following example, we'll use an elevation of 60 degrees (that is, 60 degrees above the x-y plane) and an azimuth of 35 degrees (that is, rotated 35 degrees counter-clockwise about the z-axis):"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAV0AAADtCAYAAAAcNaZ2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXl0m+eZ3X9YCAIgdhAkuO+LSErUHm+RF8WKnTiOM5lk\nbE+WsdNJXc+kTWd60jiTdrLVTTJ23Z7WbRrPZDyxx+M46jhOmji2Y8eSY2vfRVEUKe4gQRLEvhB7\n/3DfNyBNiqQoydt3z8EhtZAAPgD3e7773Oc+qnw+jwIFChQouDJQv90PQIECBQreT1BIV4ECBQqu\nIBTSVaBAgYIrCIV0FShQoOAKQiFdBQoUKLiC0L7dD0DB+wOTk5MqjUZTaTAYtMCo2WxWbDMK3pdQ\nLWMZUz4YCtaMfD5PIpEglUqh0+lQq9VotVo0Gg0qlertfngKFFwOLPnGVipdBZcVuVyOUChEPp+n\nqKgItfpNRSsSiaDRaNDr9Wg0GtRqtULACt4XUEhXwWVDOp0mHo8zNzeH0WhEpVJJYs3n8+TzebLZ\nLNlsFpVKhUajkQSsQMF7FQrpKrjkyOfzJJNJEonEshWsINh8Pk8mkyGTyUj5Qal+FbwXoZCugkuK\nXC5HPB4nnU5fULNVqVQU9hNEFSwq4FQqBTBP+1UIWMF7AQrpKrhkyGazxGIxstnsPMItJNPlsPBn\nRPWrUqmU5puC9wQU0lWwZojKNJFISHJcDgsr3aX+T+H/S6fTsoJWmm8K3q1QSFfBmiDsYMlk8oJV\n6HIEm81mSaVSGAyGt/zbwupXab4peDdD8ekquGhks1ni8TjZbHbJqnNubo7h4WE8Hg/nz59nZGSE\n0dFRJiYmmJmZIRwOo9Vq8fv9/Pmf/znf/e53V3z/hZKF0nxT8A7Dkm9ChXQVXBRSqRTxeBwAjUaz\n6P+Zmpqio6MDq9WK3+9Hq9VSVFQkybGmpobbbruNu+++m7q6OoqKii7qsYj3sPiqNN8UvAOgkK6C\nSwNhB5ubm0OlUl3wsl5UonNzc0QiEX74wx/yD//wD6TTaR599FG6u7tpamq65I+vkIQF0Svkq+AK\nQyFdBWuHsIMJL+1KiWxubg6NRkNRURHRaBS73U4qlSKdTmMymS74s8lkEr/fTyAQIBgMks1mqaqq\norGx8YI/l8/niUajFBUVodPp0Gg0aLVapfpVcKWgjAErWBsymQyxWIx8Pr8m3dRsNjMxMSF13WAw\niNfrxev14vP5CAQCBAIBZmdnCQQCpFIpHA4Hdrsdq9WKRqPhzjvv5Itf/OIF70c8PvFYFzbfBAEr\nUHCloVS6Ci6IhXaw5VwC4XCY0dFRxsbGGBkZYWxsjKGhIcbGxpiYmCAQCFBaWkp5eTkul4uqqirc\nbjcVFRWUlpbicDgkyTocDkwm00WTYyQSobi4GJ1ON+/5KM03BVcAirygYPVYiR3M4/Hw/e9/nxMn\nTjA4OEg6naampoba2lpqamqoq6vD7XZTV1dHQ0MDlZWVaLVaUqkUoVCIeDyO1+vF7/cTDAYJBoNS\nSggEAlJaiEajkjALb7t3715SF16MdAufm/haaD1T5AcFlwgK6SpYHbLZLKFQCOCCl+J+v5+f/vSn\ndHd309LSgsPhkH7amZkZxsbGOH/+vJQTxsbG8Hg8eL1eEokE5eXllJeXy+rWZrPJm/g7u92O2WyW\nhFjo262vr6e4uHjRx3Yh0i3Ewuq3kIAVKLhIKKSrYOUQdrBUKiW7/0shn88zPj7OiRMnOHHiBKdO\nnWJ4eJjx8XEMBgM1NTVUV1dTU1NDY2MjjY2N1NTU4HQ60ev1WK1W4M0mXSQSkdVu4S0ajcoAnWQy\nOe/7ubk58vk8DzzwAOvWrZv32FZKuoXPpfCr0nxTsAYojTQFy0PYu+bm5pbVOTOZDH/0R3/EiRMn\n0Ol0dHd3093dzWc/+1mampqorq6WzoRIJCKrW4/Hw/79++XAhGiYRSIRjEbjvErXarVis9kwmUzo\n9Xr0ej1msxm9Xk9xcbH8qlarcblca37+y02+Kc03BZcCSqWrAFg8HSyZTKJSqZasFPfs2UNbWxtu\nt5tsNsvo6Cjnzp2Tt7GxMUZHR/H5fJSXl1NbW0t1dTX19fXU19fjcDhobGzEbrdjsVhQq9UEg0H8\nfj9+v5/Z2VnC4TCJRIJYLEY8HicWi837Pp1Oy4aY0+nkoYceko9vtZXuUlCabwouAoq8oGBpiLDx\nhXawVCpFPp9/i2YaCAQ4ePAgZ86ckQQ7ODhIaWkpra2ttLa20tLSQm1tLbW1tTidTvx+PxMTE/j9\nfqnrTk5OSoIVjTSTyYTT6ZQuBqvVitFopKSk5C1fS0pK0Gq1ZLNZcrkcWq2WD3/4w/JxXirSFVCa\nbwpWAYV0FbwVy9nBliLd5557jn/6p3+iq6tLkmxTUxPhcJjz588zODjI4OAg58+fZ2xsjMnJSfR6\nPVVVVVRXV1NVVUVFRQU2m0020RwOBzqdjlgsJl0LwWCQeDxOPB4nkUjI72OxGIlEQsog4tJfkOAt\nt9zCJz7xiUtOuguPnYieVKlUcu2QQr4K/j8U0lUwH/l8XjbLliKLdDpNNptFr9fP+/twOMyJEyc4\nevQoZ8+eZXBwkKGhIcxmM01NTTQ1NdHQ0EBDQwNut1tmLwQCAaamppiYmJA3v9/P9PQ00WgUi8Ui\nCbi0tBSbzYbRaMRgMGAwGGR1K74vLi4ml8uRy+Vk7m42m6WxsZGOjg7C4TB6vf6ykK6AyJ8Qx0hp\nvin4/1BIV8HvIcLGc7ncBbXJTCZDOp2eF7f4gx/8gEceeYSuri42bdpEZ2enbJwFAgFJwP39/QwO\nDjI8PEwqlaKiooLKykqqq6uprKykoqICs9lMY2MjNpuNTCZDIBBgZmaGqakpOY2WSqWkW0HcRKVb\n+PjFTfxZo9HwX/7Lf8Fms110kM5KEI/HUalUGAyGedqv0nx730MhXQVvVrdCv4Wl08EEFiPdSCQC\nQF9fH8ePH+f48eOcOXOGyclJKioqaGhooKamhoaGBtra2mhsbCQWizE0NITf75cjv+Lm9/uJRCI4\nHA6cTqecRLPZbFIaMBgMmM1mzGYzRqNRVr9qtZp8Pk8ul5s3MJHL5chms6xfv56SkpLLSrqxWExu\nNS6E0nx730Mh3fc7Vho2XohsNksymcRoNALw1FNP8ZOf/ISBgQFaWlrYuHEjGzdupLOzk9LSUkZG\nRujv72d0dJTR0VGGhoYYHR3FbrdTVVVFTU0NlZWVVFVVUV5ejl6vp6GhgVwux+zsLDMzM9JCJhwK\norIV1a3w6QrpQ9yEtCCaakVFRRQXF/PAAw+wa9euy3ZclyJdAaX59r6FQrrvZ6x0WeRiP5dIJCgp\nKQHg2LFj5HI56uvrGRwc5NSpU5w+fZpTp07h8/nkAITQdBsbGykvL8fr9XLu3DmmpqaYmppienqa\n6elppqamiEQi2O12XC4XLpcLp9OJzWaTVa1er8dgMGA0GikuLpargERqmU6nm7fWHZArgyKRCLW1\ntZSVlV2Go/omRJLZUlNxhVAm395XUEj3/Yql7GArQSHpvvrqq7z44oucOnWK8fFxWltb6erqoqur\ni/b2dkpKSvB4PIyMjDA0NMTQ0BDDw8P4/X6ZxdDY2EhVVRWVlZWUlpaiVquxWq0Eg0F8Ph8zMzPM\nzMzIKbRYLEY0Gp13i8VislrXarXStSAm54RkMjc3JyvjnTt38vDDD1+W43sxDgll8u19AYV0328Q\nYeOJRAK1Wn1RO8Ty+TyxWAyTycSvf/1rgsEgnZ2d6HQ6hoaG6O3tpbe3l4GBAebm5mhpaaGxsZH6\n+noaGhqorq4ml8vh8XgYHBxkZmYGj8cjCTYYDGKz2XC5XJSWlsqvIl3MZDJRUlLylmpWpVLNcywI\n+5gYlBBe3mw2i8VikW6H6urqS32Y12xLU5pv71kopPt+wsXKCQshSHdsbIyXXnqJI0eO0Nvbi8Ph\nkE2y9vZ26uvriUaj0rE
"text/plain": [
"<matplotlib.figure.Figure at 0x10e6a7fd0>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ax.view_init(60, 35)\n",
"fig"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Again, note that this type of rotation can be accomplished interactively by clicking and dragging when using one of Matplotlib's interactive backends."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Wireframes and Surface Plots\n",
"\n",
"Two other types of three-dimensional plots that work on gridded data are wireframes and surface plots.\n",
"These take a grid of values and project it onto the specified three-dimensional surface, and can make the resulting three-dimensional forms quite easy to visualize.\n",
"Here's an example of using a wireframe:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nMzMzel/0+xblMzbMviv
"text/plain": [
"<matplotlib.figure.Figure at 0x10e6a7da0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"ax = plt.axes(projection='3d')\n",
"ax.plot_wireframe(X, Y, Z, color='black')\n",
"ax.set_title('wireframe');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A surface plot is like a wireframe plot, but each face of the wireframe is a filled polygon.\n",
"Adding a colormap to the filled polygons can aid perception of the topology of the surface being visualized:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nFf2ik3Sl3IGnbQCOOEP
"text/plain": [
"<matplotlib.figure.Figure at 0x10ecb7860>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ax = plt.axes(projection='3d')\n",
"ax.plot_surface(X, Y, Z, rstride=1, cstride=1,\n",
" cmap='viridis', edgecolor='none')\n",
"ax.set_title('surface');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that though the grid of values for a surface plot needs to be two-dimensional, it need not be rectilinear.\n",
"Here is an example of creating a partial polar grid, which when used with the ``surface3D`` plot can give us a slice into the function we're visualizing:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nQuEIiIwBI3CF1SdCGxe
"text/plain": [
"<matplotlib.figure.Figure at 0x10eae2128>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"r = np.linspace(0, 6, 20)\n",
"theta = np.linspace(-0.9 * np.pi, 0.8 * np.pi, 40)\n",
"r, theta = np.meshgrid(r, theta)\n",
"\n",
"X = r * np.sin(theta)\n",
"Y = r * np.cos(theta)\n",
"Z = f(X, Y)\n",
"\n",
"ax = plt.axes(projection='3d')\n",
"ax.plot_surface(X, Y, Z, rstride=1, cstride=1,\n",
" cmap='viridis', edgecolor='none');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Surface Triangulations\n",
"\n",
"For some applications, the evenly sampled grids required by the above routines is overly restrictive and inconvenient.\n",
"In these situations, the triangulation-based plots can be very useful.\n",
"What if rather than an even draw from a Cartesian or a polar grid, we instead have a set of random draws?"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"theta = 2 * np.pi * np.random.random(1000)\n",
"r = 6 * np.random.random(1000)\n",
"x = np.ravel(r * np.sin(theta))\n",
"y = np.ravel(r * np.cos(theta))\n",
"z = f(x, y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We could create a scatter plot of the points to get an idea of the surface we're sampling from:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nlOGL7hH96ZnkW/6IxWJ
"text/plain": [
"<matplotlib.figure.Figure at 0x10e7947b8>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ax = plt.axes(projection='3d')\n",
"ax.scatter(x, y, z, c=z, cmap='viridis', linewidth=0.5);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This leaves a lot to be desired.\n",
"The function that will help us in this case is ``ax.plot_trisurf``, which creates a surface by first finding a set of triangles formed between adjacent points (remember that x, y, and z here are one-dimensional arrays):"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\n+tSn9jRPRbpjbGccXla
"text/plain": [
"<matplotlib.figure.Figure at 0x10ef33e80>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ax = plt.axes(projection='3d')\n",
"ax.plot_trisurf(x, y, z,\n",
" cmap='viridis', edgecolor='none');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The result is certainly not as clean as when it is plotted with a grid, but the flexibility of such a triangulation allows for some really interesting three-dimensional plots.\n",
"For example, it is actually possible to plot a three-dimensional Möbius strip using this, as we'll see next."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Example: Visualizing a Möbius strip\n",
"\n",
"A Möbius strip is similar to a strip of paper glued into a loop with a half-twist.\n",
"Topologically, it's quite interesting because despite appearances it has only a single side!\n",
"Here we will visualize such an object using Matplotlib's three-dimensional tools.\n",
"The key to creating the Möbius strip is to think about it's parametrization: it's a two-dimensional strip, so we need two intrinsic dimensions. Let's call them $\\theta$, which ranges from $0$ to $2\\pi$ around the loop, and $w$ which ranges from -1 to 1 across the width of the strip:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"theta = np.linspace(0, 2 * np.pi, 30)\n",
"w = np.linspace(-0.25, 0.25, 8)\n",
"w, theta = np.meshgrid(w, theta)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now from this parametrization, we must determine the *(x, y, z)* positions of the embedded strip.\n",
"\n",
"Thinking about it, we might realize that there are two rotations happening: one is the position of the loop about its center (what we've called $\\theta$), while the other is the twisting of the strip about its axis (we'll call this $\\phi$). For a Möbius strip, we must have the strip makes half a twist during a full loop, or $\\Delta\\phi = \\Delta\\theta/2$."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"phi = 0.5 * theta"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we use our recollection of trigonometry to derive the three-dimensional embedding.\n",
"We'll define $r$, the distance of each point from the center, and use this to find the embedded $(x, y, z)$ coordinates:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# radius in x-y plane\n",
"r = 1 + w * np.cos(phi)\n",
"\n",
"x = np.ravel(r * np.cos(theta))\n",
"y = np.ravel(r * np.sin(theta))\n",
"z = np.ravel(w * np.sin(phi))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, to plot the object, we must make sure the triangulation is correct. The best way to do this is to define the triangulation *within the underlying parametrization*, and then let Matplotlib project this triangulation into the three-dimensional space of the Möbius strip.\n",
"This can be accomplished as follows:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\n1h/b6+6Fa4ntbrGXz0+
"text/plain": [
"<matplotlib.figure.Figure at 0x10e69c358>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# triangulate in the underlying parametrization\n",
"from matplotlib.tri import Triangulation\n",
"tri = Triangulation(np.ravel(w), np.ravel(theta))\n",
"\n",
"ax = plt.axes(projection='3d')\n",
"ax.plot_trisurf(x, y, z, triangles=tri.triangles,\n",
" cmap='viridis', linewidths=0.2);\n",
"\n",
"ax.set_xlim(-1, 1); ax.set_ylim(-1, 1); ax.set_zlim(-1, 1);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Combining all of these techniques, it is possible to create and display a wide variety of three-dimensional objects and patterns in Matplotlib."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!--NAVIGATION-->\n",
"< [Customizing Matplotlib: Configurations and Stylesheets](04.11-Settings-and-Stylesheets.ipynb) | [Contents](Index.ipynb) | [Geographic Data with Basemap](04.13-Geographic-Data-With-Basemap.ipynb) >"
]
}
],
"metadata": {
"anaconda-cloud": {},
"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.4.3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}