{ "cells": [ { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Introduction to Scientific Computing\n", "### Lecture 10: 3D Plots\n", "#### J.R. Gladden, Spring 2018, Univ. of Mississippi" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Adding a 3rd dimension to your plots adds more information. Matplotlib supplies some solid 3D tools through the *Mplot3D* tool kit. Many standard 3D plotting tools are available:\n", "- Mesh and surface plots\n", "- 3D scatter plots\n", "- 3D line (curve) plots\n", "- 3D Contour plots\n", "- 3D Quiver plots\n", "- and more!\n", "\n", "Here's how you do the imports:\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib qt4" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from mpl_toolkits.mplot3d import Axes3D # This is the key import for 3D plots\n", "from matplotlib import cm #large set of colormaps for the surface\n" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Now we need to create a figure object and an axis object to apply." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "plt.close('all')\n", "fig = plt.figure(1)\n", "#create a set of 3D axes in the figure\n", "ax=fig.add_subplot(1,1,1, projection='3d')" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Let's first try a *mesh plot* of the function $f(x,y) = \\sin(x) \\cos(y)$. We first need to create a meshgrid (like we did with quiver plots." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "x = np.linspace(-5,5,30)\n", "y = np.linspace(-5,5,30)\n", "X,Y = np.meshgrid(x,y)\n", "\n", "Z=np.sin(X)*np.cos(Y)\n" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Now we can create the plot. Note " ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "#plt.close('all')\n", "surf = ax.plot_surface(X,Y,Z, rstride = 1, cstride = 1, lw=0.2, cmap = cm.coolwarm)\n", "fig.colorbar(surf)\n", "ax.set_xlabel('X')\n", "ax.set_ylabel('Y')\n", "ax.set_zlabel('Z')\n", "ax.set_title('My First 3D Plot')\n", "plt.show()\n" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "This is an example of a **line plot** in 3D space. This parametrically plots a helix. An interesting twist on this is computing a trajectory of a system in time and updating the line so that it creates an animation. We'll do something like this later..." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "# Create a named figure window\n", "fig2 = plt.figure(2)\n", "\n", "#create a set of 3D axes in the figure\n", "ax2=fig2.add_subplot(1,1,1, projection='3d')\n", "\n", "# Function to plot - no meshgrid here\n", "# Parametrically define a helix with axis in Z direction \n", "z = np.linspace(0,10,300)\n", "theta = np.linspace(0,10*np.pi,300)\n", "x=np.sin(theta)\n", "y=np.cos(theta)\n", "\n", "ax2.plot(x,y,z, 'g-',lw=2)\n", "\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Lastly, let's do a **3D quiver plot** that shows a vector field in 3D. This example extends the Electric filed plot for 2 charges into 3D." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "from mpl_toolkits.mplot3d import axes3d\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "plt.close('all')\n", "d=0.8\n", "x1,y1=(-d,0)\n", "x2,y2=(d,0)\n", "q1=+1\n", "q2=-1\n", "ds = 0.3\n", "fig = plt.figure()\n", "ax = fig.gca(projection='3d')\n", "\n", "# Make the 3D grid\n", "x, y, z = np.meshgrid(np.arange(-1, 1, ds),\n", " np.arange(-1, 1, ds),\n", " np.arange(-1, 1, ds))\n", "\n", "\n", "h1=(x-d/2)**2+y**2 + z**2\n", "h2=(x+d/2)**2+y**2 + z**2\n", "\n", "U=q1*(x-d/2)/h1+q2*(x+d/2)/h2\n", "V=q1*y/h1 +q2*y/h2\n", "W=q1*z/h1 + q2*z/h2\n", "\n", "#clip for E field larger than |Eclip| using \"not a number\" from numpy (np.nan)\n", "HighEclip=10\n", "LowEclip=-10\n", "U[U > HighEclip]=np.nan\n", "U[U < LowEclip]=np.nan\n", "V[V > HighEclip]=np.nan\n", "V[V < LowEclip]=np.nan\n", "W[W > HighEclip]=np.nan\n", "W[W < LowEclip]=np.nan\n", "\n", "mags = np.sqrt(U**2+V**2*W**2) ## Note magnitude coloring doesn't work in 3D ...yet!\n", "ax.quiver(x, y, z, U, V, W,color=(0,0,0.9),length=0.2,normalize=True)\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "### Binary Files\n", "So far, all our input/output (and python default) uses ASCII text encoding. This is a good default because EVERY computer system can read ASCII text - it is an industry standard. These files are easily read by other programs. In ASCII, $2^8 = 256$ codes (numbers) represent 256 characters on your keyboard. **However** this is not a very efficient or secure way to store data. Binary files use other ways to encode the data which can be more efficient, but it can be tricky as well as platform dependent. There are many details in dealing with binary files which I will not get into here - we'll just cover basic concepts. Most files you deal with on a daily basis are binary: jpeg, wav, mp4, ..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tools for working with binary files\n", "You can use standard input/output tools to work with binary files." ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": true }, "outputs": [], "source": [ "sometext = \"This is some text I want to save to a file\"\n", "outfile = open(\"ascii_out.txt\",'w')\n", "outfile.write(sometext)\n", "outfile.close()" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#Binary version\n", "binary_text = 'This is some text I want to save to a file'\n", "encoded_text = binary_text.encode('base64') # lots of possible options here\n", "outfile = open(\"binary_out.dat\",'wb')\n", "outfile.write(encoded_text)\n", "outfile.close()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "encoded_text = binary_text.encode" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'VGhpcyBpcyBzb21lIHRleHQgSSB3YW50IHRvIHNhdmUgdG8gYSBmaWxl\\n'" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "encoded_text\n" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'This is some text I want to save to a file'" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "encoded_text.decode('base64')" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#Here's an example of reading in a binary image file (assume this png file is in the working directory)\n", "infile=open('test.png','rb')\n", "contents = infile.readlines()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is also a \"binascii\" module which has convenient tools for converting various binary econdings to and from ASCII." ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import binascii\n" ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'J\\x89\\x9e\\x9a\\x8a\\xde\\xb5\\xecm'" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mytext = \"Some more text\"\n", "enc_text=binascii.a2b_base64(mytext)\n", "enc_text" ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'Somemoretext\\n'" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "binascii.b2a_base64(enc_text)" ] }, { "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.13" } }, "nbformat": 4, "nbformat_minor": 0 }