{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Introduction: IPython Notebook & Object Oriented Matplotlib" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll start with a quick introduction to using matplotlib with the IPython notebook,\n", "and run through some examples of object oriented matplotlib." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "IPython Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The IPython notebook is designed to be used seamlessly with matplotlib.\n", "\n", "When you start the notebook, you can type\n", "\n", " [laptop]% ipython notebook --pylab\n", "\n", "or\n", "\n", " [laptop]% ipython notebook --pylab inline\n", "\n", "The result of the first is to set up the notebook so that matplotlib figures\n", "can be used interactively within the notebook. The result of the second is\n", "that figures are embedded statically within the notebook page." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you start the notebook without either of these annotations, you can enter the\n", "``pylab`` or ``pylab inline`` mode using one of IPython's magic functions. For\n", "example, you can type in a notebook cell:\n", "\n", " In [ ]: %pylab\n", "\n", "or\n", "\n", " In [ ]: %pylab inline\n", "\n", "respectively, to get the same result as above.\n", "\n", "Note that once you've activated one of these backends, you now (MPL: 1.3.0, IPython 1.1.0) can switch this mid-session by just using those commands, but at some point prior to these versions it wasn't possible. In\n", "order to switch the backend in that case, you must restart the kernel, using either the option in the\n", "``Kernel`` menu above, or the shortcut\n", "\n", " Ctrl-m .\n", "\n", "(for a list of available shortcuts, see the help menu: ``Ctrl-m h``)\n", "Once you have restarted the kernel, you can change the pylab mode\n", "and re-run your code.\n", "\n", "Take a moment and see the effect of creating a simple plot using either\n", "pylab mode or pylab inline mode:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%pylab inline" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from matplotlib import rcParams\n", "print rcParams['backend']" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "x = np.linspace(0, 10, 1000)\n", "plt.plot(x, np.sin(x))" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If your plots show an ugly gray background, you can switch it off like so:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "matplotlib.rcParams['figure.facecolor'] = 'w'" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "x = np.linspace(0, 10, 1000)\n", "plt.plot(x, np.sin(x))" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Object-oriented Matplotlib" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matplotlib was originally designed to have an interface similar to that of matlab.\n", "For this reason, the library maintains pointers to the currently active figure and\n", "axes, and makes simple plots straightforward to create. For example:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import pylab # note that this import is automatic in `%pylab` or `%pylab inline` mode" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "pylab.figure() # this is optional: if you just call plot(), a figure will be created\n", "pylab.plot(x, np.sin(x))\n", "pylab.title('plot 1: sine')\n", "\n", "pylab.figure()\n", "pylab.plot(x, np.cos(x))\n", "pylab.title('plot 2: cosine')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is fine for simple plots, but when you start wanting to do more powerful\n", "things, it can get a little bit tricky. A better way to approach it might\n", "be like this:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import matplotlib.pyplot as plt # Again, in pylab mode this import happens automatically\n", "\n", "fig1 = plt.figure()\n", "ax1 = fig1.add_subplot(1, 1, 1)\n", "ax1.plot(x, np.sin(x))\n", "ax1.set_title('sine')\n", "\n", "fig2 = plt.figure()\n", "ax2 = fig2.add_subplot(1, 1, 1)\n", "ax2.plot(x, np.cos(x))\n", "ax2.set_title('cosine')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this instance, all the typing might seem a bit gratuitous. But as our plot\n", "objects get more and more complicated, explicitly keeping track of the figures\n", "and axes will make our lives increasingly easier.\n", "\n", "Also, because we don't care about which plot is active at any given time, it\n", "gives us the freedom to write code in any order. The following generates\n", "the same plot output as the previous snippet, but makes more clear the\n", "relationship between the two figures:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "fig1 = plt.figure()\n", "fig2 = plt.figure()\n", "\n", "ax1 = fig1.add_subplot(1, 1, 1)\n", "ax2 = fig2.add_subplot(1, 1, 1)\n", "\n", "ax1.plot(x, np.sin(x))\n", "ax2.plot(x, np.cos(x))\n", "\n", "ax1.set_title('sine')\n", "ax2.set_title('cosine')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Other Object Types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One thing that will be important to recognize for this tutorial is that each and every\n", "plot element in matplotlib has an associated object that can be passed around and\n", "manipulated. To see this, we'll use the non-inline pylab mode, so you may have to\n", "type `Ctrl-m .` and restart the kernel:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%pylab" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "x = np.linspace(0, 10, 1000)\n", "\n", "fig, ax = plt.subplots()\n", "lines = ax.plot(x, np.sin(x))\n", "print lines" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we've created the plot, we can adjust the attributes of the `Line2D`\n", "instance. In general, any keyword in the ``plot`` command has an associated\n", "``set_`` command.\n", "\n", "After setting the different parameters, we can call the ``draw()`` method of\n", "the figure canvas to make the plot reflect the changes." ] }, { "cell_type": "code", "collapsed": false, "input": [ "lines[0].set_color('green')\n", "fig.canvas.draw()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "lines[0].set_linewidth(3)\n", "fig.canvas.draw()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other plot elements can be manipulated as well. For example, text:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "txt = plt.text(4, 0.5, \"Hello\")" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "txt.set_size(20)\n", "txt.set_color('blue')\n", "fig.canvas.draw()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also dynamically change the location of the text:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "txt.set_x(7)\n", "txt.set_y(-0.5)\n", "fig.canvas.draw()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, you can even dynamically change the locations of each point\n", "in the line! For example, changing the y data looks like this:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lines[0].set_ydata(np.sin(2 * x))\n", "fig.canvas.draw()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This sort of operation can be used to create simple animations (this does not work for the QT backend on OSX) -- for example:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for i in range(100):\n", " lines[0].set_ydata(np.sin(x + 0.1 * i))\n", " fig.canvas.draw()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Please note that in general, this is not a stable way to create animations in\n", "matplotlib. For this purpose, the ``animation`` submodule should be used.\n", "We'll talk about this a little bit later." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Different plot elements have different setter attributes. IPython can be\n", "a useful tool in figuring these things out: use the tab-completion to\n", "determine what can be set. Many of these values are internal parameters that\n", "you probably will not need, but some of them can give you interesting\n", "results:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "txt.set_" ], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }