diff --git a/data/dessert.png b/data/dessert.png new file mode 100644 index 0000000..cb66995 Binary files /dev/null and b/data/dessert.png differ diff --git a/data/stained_glass_barcelona.png b/data/stained_glass_barcelona.png new file mode 100644 index 0000000..6f1780b Binary files /dev/null and b/data/stained_glass_barcelona.png differ diff --git a/data/stinkbug.png b/data/stinkbug.png new file mode 100644 index 0000000..6d6c4d0 Binary files /dev/null and b/data/stinkbug.png differ diff --git a/image_tutorial.ipynb b/image_tutorial.ipynb new file mode 100644 index 0000000..91914b5 --- /dev/null +++ b/image_tutorial.ipynb @@ -0,0 +1,174 @@ +{ + "metadata": { + "name": "image_tutorial" + }, + "nbformat": 2, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Matplotlib image tutorial", + "", + "This is a copy of the official [matplotlib introductory image tutorial](http://matplotlib.sourceforge.net/users/image_tutorial.html)", + "in the form of a notebook." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "%pylab inline", + "import matplotlib.pyplot as plt", + "import matplotlib.image as mpimg", + "import numpy as np" + ], + "language": "python", + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "img = mpimg.imread('data/stinkbug.png')" + ], + "language": "python", + "outputs": [], + "prompt_number": 2 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "plt.imshow(img)" + ], + "language": "python", + "outputs": [], + "prompt_number": 3 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "lum_img = img[:,:,0]", + "fig, ax = plt.subplots()", + "imgplot = ax.imshow(lum_img)" + ], + "language": "python", + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "imgplot.set_cmap('hot')", + "imgplot.figure" + ], + "language": "python", + "outputs": [], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "imgplot.set_cmap('spectral')", + "imgplot.figure" + ], + "language": "python", + "outputs": [], + "prompt_number": 6 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "imgplot.set_cmap('spectral')", + "fig.colorbar(imgplot)", + "fig" + ], + "language": "python", + "outputs": [], + "prompt_number": 7 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "plt.hist(lum_img.flatten(), 256, range=(0.0,1.0), fc='k', ec='k');" + ], + "language": "python", + "outputs": [], + "prompt_number": 8 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,4))", + "", + "imgplot1 = ax1.imshow(lum_img)", + "ax1.set_title('Before')", + "fig.colorbar(imgplot1, ax=ax1, ticks=[0.1,0.3,0.5,0.7], orientation ='horizontal')", + "", + "imgplot2 = ax2.imshow(lum_img)", + "imgplot2.set_clim(0.0,0.7)", + "ax2.set_title('After')", + "fig.colorbar(imgplot2, ax=ax2, ticks=[0.1,0.3,0.5,0.7], orientation='horizontal');" + ], + "language": "python", + "outputs": [], + "prompt_number": 9 + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "import Image", + "img = Image.open('data/stinkbug.png') # Open image as PIL image object", + "rsize = img.resize((img.size[0]/10, img.size[1]/10)) # Use PIL to resize", + "rsizeArr = np.asarray(rsize) # Get array back" + ], + "language": "python", + "outputs": [], + "prompt_number": 10 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "imgplot = plt.imshow(rsizeArr, interpolation='bilinear')" + ], + "language": "python", + "outputs": [], + "prompt_number": 11 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "imgplot.set_interpolation('nearest')", + "imgplot.figure" + ], + "language": "python", + "outputs": [], + "prompt_number": 12 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "imgplot.set_interpolation('bicubic')", + "imgplot.figure" + ], + "language": "python", + "outputs": [], + "prompt_number": 13 + } + ] + } + ] +} \ No newline at end of file diff --git a/mapping_seismic_stations.ipynb b/mapping_seismic_stations.ipynb new file mode 100644 index 0000000..ce11a8d --- /dev/null +++ b/mapping_seismic_stations.ipynb @@ -0,0 +1,186 @@ +{ + "metadata": { + "name": "mapping_seismic_stations" + }, + "nbformat": 2, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Mapping seismic stations in the Himalayas with Numpy and Matplotlib", + "## Or reading datasets with custom dtypes and plotting Earth-based data with basemap" + ] + }, + { + "cell_type": "markdown", + "source": [ + "In this exercise, we consider loading measurement files with the format:", + "", + "
", + "# Station Lat Long Elev ", + "BIRA\t26.4840\t87.2670\t0.0120", + "BUNG\t27.8771\t85.8909\t1.1910", + "etc...", + "", + "", + "These are seismic measurement stations in the Himalaya, with the elevation indicated in km. Data with a structure such as this is common in many disciplines, and because we have a combination of text and numerical fields, we can't directly load it into a regular numpy array.", + "", + "But we can use numpy's ability to [define custom data types (dtypes)](http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html) to compactly describe our data in a single array, which we can then manipulate.", + "", + "If you have the basemap matplotlib toolkit installed, at the end of this example we will show a real Earth map and overlay the station locations on top of that.", + "", + "We start by configuring pylab support and loading the required modules." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "%pylab inline" + ], + "language": "python", + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "import numpy as np", + "import matplotlib.pyplot as plt" + ], + "language": "python", + "outputs": [], + "prompt_number": 2 + }, + { + "cell_type": "markdown", + "source": [ + "Now, we need to describe this dataset. There are several ways of declaring a dtype, in this simple case we show two equivalent ones. See the [numpy reference docs](http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html) for more details:" + ] + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "# Data descriptor to make a proper array.", + "dt = [('station','S4'), ('lat',np.float32), ('lon',np.float32), ('elev',np.float32) ]", + "", + "# This is an alternate and fully equivalent form:", + "dt = dict(names = ('station','lat','lon','elev'),", + " formats = ('S4',np.float32,np.float32,np.float32) )" + ], + "language": "python", + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "source": [ + "Now, we load the data using this dtype we've constructed, and view it as a recarray for convenient named-field access:" + ] + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "data_fname = os.path.join('data', 'stations.txt')", + "tab = np.loadtxt(data_fname, dt).view(np.recarray)" + ], + "language": "python", + "outputs": [], + "prompt_number": 3 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "ptitle = 'Seismic stations in the Himalaya'", + "print ptitle", + "print 'Stations:', tab.station", + "print 'Elevations (km):', tab.elev", + "print 'First station:', tab[0]", + "print 'Mean latitude:', tab.lat.mean()" + ], + "language": "python", + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "f1, ax = plt.subplots(figsize = (8,5))", + "", + "# Make the size of the circles proportional to the elevation", + "sizes = 40*(tab.elev+1)", + "s = ax.scatter(tab.lon, tab.lat, s=sizes, c=tab.elev)", + "", + "# The colorbar must be associated with the return value of scatter()", + "f1.colorbar(s)", + "ax.set_title(ptitle)", + "# Now add text labels for all the stations. ", + "", + "# Note: when accessing single elements of the recarray, the named field", + "# syntax doesn't work and we must access the fields via ['name']", + "for record in tab:", + " ax.text(record['lon']+0.1, record['lat']+0.1, record['station'], weight='bold')" + ], + "language": "python", + "outputs": [], + "prompt_number": 23 + }, + { + "cell_type": "markdown", + "source": [ + "If we find the matplotlib basemap toolkit, we can show an even better plot by", + "overlaying the stations on top of a map of Earth at that location. But we", + "check this import so the code runs even without basemap." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "try:", + " from mpl_toolkits.basemap import Basemap", + "except ImportError:", + " pass", + "else:", + " # Draw the stations on a real map of the Earth.", + " # Find boundaries ", + " lon0 = 0.995*tab.lon.min()", + " lon1 = 1.01*tab.lon.max()", + " lat0 = 0.995*tab.lat.min()", + " lat1 = 1.01*tab.lat.max()", + " # Geographic grid to draw", + " parallels = np.linspace(lat0, lat1, 5)", + " meridians = np.linspace(lon0, lon1, 5)", + "", + " # Resolution of the basemap to load ('f' is *very* expensive)", + " resolution = 'i' # intermediate resolution for map info", + "", + " f2, ax2 = plt.subplots(figsize=(10,6))", + " m = Basemap(lon0, lat0, lon1, lat1, resolution=resolution, ax=ax2)", + " m.drawcountries(color=(1,1,0)) # country boundaries yellow", + " m.drawrivers(color=(0,1,1)) # rivers in cyan", + " m.bluemarble() # NASA bluemarble image", + " m.drawparallels(parallels, labels=[1,0,0,0], fmt='%.2f')", + " m.drawmeridians(meridians, labels=[0,0,0,1], fmt='%.2f')", + " s = m.scatter(tab.lon, tab.lat, s=sizes, c=tab.elev, zorder=10, alpha=0.6)", + " f2.colorbar(s)", + " ax2.set_title(ptitle)", + " for record in tab:", + " ax2.text( record['lon']+0.05, record['lat']+0.05, record['station'], ", + " weight='bold', color='yellow', zorder=10)" + ], + "language": "python", + "outputs": [], + "prompt_number": 29 + } + ] + } + ] +} \ No newline at end of file diff --git a/mapping_seismic_stations_interactive.ipynb b/mapping_seismic_stations_interactive.ipynb new file mode 100644 index 0000000..d0ad6ba --- /dev/null +++ b/mapping_seismic_stations_interactive.ipynb @@ -0,0 +1,138 @@ +{ + "metadata": { + "name": "mapping_seismic_stations_interactive" + }, + "nbformat": 2, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Mapping seismic stations in the Himalayas with Numpy and Matplotlib", + "## Part II - Interactive event handling" + ] + }, + { + "cell_type": "markdown", + "source": [ + "Here, we extend the plot above by adding an event handler that prints the location (four-letter string) of the station you click on.", + "", + "We use a threshold for distance, and discriminate between a click below threshold (considered to be 'on') vs a miss, in which case we indicate what the closest station is, its coordinates and the distance to it from the click.", + "", + "In order to get interactive plot windows that support event handling, we must restart the kernel and activate pylab but *not* in `inline` mode." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "%pylab" + ], + "language": "python", + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "import sys", + "import numpy as np", + "import matplotlib.pyplot as plt" + ], + "language": "python", + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "source": [ + "We quickly reload the data using the same approach as in the previous exercise" + ] + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "# Data descriptor to make a proper array.", + "dt = [('station','S4'), ('lat',np.float32), ('lon',np.float32), ('elev',np.float32) ]", + "data_fname = os.path.join('data', 'stations.txt')", + "tab = np.loadtxt(data_fname, dt).view(np.recarray)" + ], + "language": "python", + "outputs": [], + "prompt_number": 2 + }, + { + "cell_type": "markdown", + "source": [ + "We start by defining our `StationPicker` object that will do the job:" + ] + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "class StationPicker(object):", + " def __init__(self, figure, stations, eps=0.10, axis=None):", + " self.figure = figure", + " self.stations = stations", + " self.cid = figure.canvas.mpl_connect('button_press_event', self)", + " if axis is None:", + " axis = figure.axes[0]", + " self.axis = axis", + " self.eps = eps", + "", + " def __call__(self, event):", + " #print 'click', event # dbg", + " if event.inaxes != self.axis:", + " return", + " self.figure.canvas.draw()", + " # Compute the distance from the click to all stations", + " lats = self.stations['lat']", + " longs = self.stations['lon']", + " click_lat, click_long = event.xdata, event.ydata", + " lat_d = lats - click_lat", + " lon_d = longs - click_long", + " dist = np.sqrt(lat_d**2 + lon_d**2)", + " nearest_i = dist.argmin()", + " near_dist = dist[nearest_i]", + " nearest = self.stations[nearest_i]", + " #print 'Nearest distance:', near_dist # dbg", + " if near_dist < self.eps:", + " print \"HIT! You clicked on\", nearest['station']", + " else:", + " print \"No hit, nearest is:\", nearest['station']", + " print \"It is at:\", nearest['lat'], nearest['lon']", + " print \"Distance to it:\", near_dist", + " sys.stdout.flush()" + ], + "language": "python", + "outputs": [], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "fig, ax = plt.subplots()", + "ax.scatter(tab['lat'], tab['lon'], 40*(tab['elev']+1), c=tab['elev'] )", + "# We can now make a picker with that binds the figure and the data", + "StationPicker(fig, tab)" + ], + "language": "python", + "outputs": [], + "prompt_number": 13 + }, + { + "cell_type": "code", + "collapsed": true, + "input": [], + "language": "python", + "outputs": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/matplotlib_beyond_basics.ipynb b/matplotlib_beyond_basics.ipynb new file mode 100644 index 0000000..2d24ab7 --- /dev/null +++ b/matplotlib_beyond_basics.ipynb @@ -0,0 +1,1154 @@ +{ + "metadata": { + "name": "matplotlib_beyond_basics" + }, + "nbformat": 2, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "source": [ + " Matplotlib: Beyond the basics", + "===============================", + "", + "Status and plan for today", + "=========================", + "", + "By now you know the basics of:", + "", + "- Numpy array creation and manipulation.", + "- Display of data in numpy arrays, sufficient for interactive exploratory work.", + "", + "Hopefully after this week you will:", + "", + "- Know how to polish those figures to the point where they can go to a journal.", + "- Understand matplotlib's internal model enough to:", + " - know where to look for knobs to fine-tune", + " - better understand the help and examples online", + " - use it as a development platform for complex visualization", + "", + "" + ] + }, + { + "cell_type": "markdown", + "source": [ + "Matplotlib's main APIs: ``pyplot`` and object-oriented", + "======================================================", + "", + "Matplotlib is a library that can be thought of as having two main ways of being", + "used:", + "", + "- via ``pyplot`` calls, as a high-level, matlab-like library that automatically", + " manages details like figure creation.", + "", + "- via its internal object-oriented structure, that offers full control over all", + " aspects of the figure, at the cost of slightly more verbose calls for the", + " common case.", + "", + "The pyplot api:", + "", + "- Easiest to use.", + "- Sufficient for simple and moderately complex plots.", + "- Does not offer complete control over all details.", + "", + "Before we look at our first simple example, we must activate pylab support in the notebook, leave only one option below uncommented and execute the cell:" + ] + }, + { + "cell_type": "code", + "collapsed": true, + "input": [ + "#%pylab # use this for floating figures", + "%pylab inline # use this for inlined figures" + ], + "language": "python", + "outputs": [] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "x = np.linspace(0, 2*np.pi)", + "y = np.sin(x)", + "plt.plot(x,y, label='sin(x)')", + "plt.legend()", + "plt.title('Harmonic')", + "plt.xlabel('x')", + "plt.ylabel('y')", + "", + "# Add one line to that plot", + "z = np.cos(x)", + "plt.plot(x, z, label='cos(x)')", + "", + "# Make a second figure with a simple plot", + "plt.figure()", + "plt.plot(x, np.sin(2*x), label='sin(2x)')", + "plt.legend()" + ], + "language": "python", + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "markdown", + "source": [ + "Here is how to create the same two plots, using explicit management of the figure and axis objects:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "f, ax = plt.subplots() # we manually make a figure and axis", + "ax.plot(x,y, label='sin(x)') # it's the axis who plots", + "ax.legend()", + "ax.set_title('Harmonic') # we set the title on the axis", + "ax.set_xlabel('x') # same with labels", + "ax.set_ylabel('y')", + "", + "# Make a second figure with a simple plot. We can name the figure with a", + "# different variable name as well as its axes, and then control each", + "f1, ax1 = plt.subplots()", + "ax1.plot(x, np.sin(2*x), label='sin(2x)')", + "ax1.legend()", + "", + "# Since we now have variables for each axis, we can add back to the first", + "# figure even after making the second", + "ax.plot(x, z, label='cos(x)')" + ], + "language": "python", + "outputs": [], + "prompt_number": 2 + }, + { + "cell_type": "markdown", + "source": [ + "It\u2019s important to understand the existence of these objects, even if you use mostly the top-level pyplot calls most of the time. Many things can be accomplished in MPL with mostly pyplot and a little bit of tweaking of the underlying objects. We\u2019ll revisit the object-oriented API later.", + "", + "Important commands to know about, and which matplotlib uses internally a lot:", + "", + " gcf() # get current figure", + " gca() # get current axis" + ] + }, + { + "cell_type": "markdown", + "source": [ + "Making subplots", + "===============", + "", + "The simplest command is:", + "", + " f, ax = plt.subplots()", + "", + "which is equivalent to:", + "", + " f = plt.figure()", + " ax = f.add_subplot(111)", + "", + "By passing arguments to `subplots`, you can easily create a regular plot grid:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "x = np.linspace(0, 2*np.pi, 400)", + "y = np.sin(x**2)", + "", + "# Just a figure and one subplot", + "f, ax = plt.subplots()", + "ax.plot(x, y)", + "ax.set_title('Simple plot')", + "", + "# Two subplots, unpack the output array immediately", + "f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)", + "ax1.plot(x, y)", + "ax2.scatter(x, y)", + "", + "# Put a figure-level title", + "f.suptitle('Sharing Y axis')" + ], + "language": "python", + "outputs": [], + "prompt_number": 3 + }, + { + "cell_type": "markdown", + "source": [ + "And finally, an arbitrarily complex grid can be made with ``subplot2grid``:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "f = plt.figure()", + "ax1 = plt.subplot2grid((3,3), (0,0), colspan=3)", + "ax2 = plt.subplot2grid((3,3), (1,0), colspan=2)", + "ax3 = plt.subplot2grid((3,3), (1, 2), rowspan=2)", + "ax4 = plt.subplot2grid((3,3), (2, 0))", + "ax5 = plt.subplot2grid((3,3), (2, 1))", + "", + "# Let's turn off visibility of all tick labels here", + "for ax in f.axes:", + " for t in ax.get_xticklabels()+ax.get_yticklabels():", + " t.set_visible(False)", + "", + "# And add a figure-level title at the top", + "f.suptitle('Subplot2grid')" + ], + "language": "python", + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "source": [ + "Manipulating properties across matplotlib", + "=========================================", + "", + "In matplotlib, most properties for lines, colors, etc, can be set directly in", + "the call:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "plt.plot([1,2,3], linestyle='--', color='r')" + ], + "language": "python", + "outputs": [], + "prompt_number": 5 + }, + { + "cell_type": "markdown", + "source": [ + "But for finer control you can get a hold of the returned line object (more on", + "these objects later)::", + "", + " In [1]: line, = plot([1,2,3])", + "", + "These line objects have a lot of properties you can control, a full list is", + "seen here by tab-completing in IPython::", + "", + " In [2]: line.set", + " line.set line.set_drawstyle line.set_mec", + " line.set_aa line.set_figure line.set_mew", + " line.set_agg_filter line.set_fillstyle line.set_mfc", + " line.set_alpha line.set_gid line.set_mfcalt", + " line.set_animated line.set_label line.set_ms", + " line.set_antialiased line.set_linestyle line.set_picker", + " line.set_axes line.set_linewidth line.set_pickradius", + " line.set_c line.set_lod line.set_rasterized", + " line.set_clip_box line.set_ls line.set_snap", + " line.set_clip_on line.set_lw line.set_solid_capstyle", + " line.set_clip_path line.set_marker line.set_solid_joinstyle", + " line.set_color line.set_markeredgecolor line.set_transform", + " line.set_contains line.set_markeredgewidth line.set_url", + " line.set_dash_capstyle line.set_markerfacecolor line.set_visible", + " line.set_dashes line.set_markerfacecoloralt line.set_xdata", + " line.set_dash_joinstyle line.set_markersize line.set_ydata", + " line.set_data line.set_markevery line.set_zorder", + " ", + "", + "But the ``setp`` call (short for set property) can be very useful, especially", + "while working interactively because it contains introspection support, so you", + "can learn about the valid calls as you work::", + "", + " In [7]: line, = plot([1,2,3])", + "", + " In [8]: setp(line, 'linestyle')", + " linestyle: [ ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'None'`` | ``' '`` | ``''`` ] and any drawstyle in combination with a linestyle, e.g. ``'steps--'``. ", + "", + " In [9]: setp(line)", + " agg_filter: unknown", + " alpha: float (0.0 transparent through 1.0 opaque) ", + " animated: [True | False] ", + " antialiased or aa: [True | False]", + " ...", + " ... much more output elided", + " ...", + "", + "In the first form, it shows you the valid values for the 'linestyle' property,", + "and in the second it shows you all the acceptable properties you can set on the", + "line object. This makes it very easy to discover how to customize your figures", + "to get the visual results you need.", + "", + "Furthermore, setp can manipulate multiple objects at a time:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "x = linspace(0, 2*pi)", + "y1 = sin(x)", + "y2 = sin(2*x)", + "lines = plt.plot(x, y1, x, y2)", + "", + "# We will set the width and color of all lines in the figure at once:", + "plt.setp(lines, linewidth=2, color='r')" + ], + "language": "python", + "outputs": [], + "prompt_number": 6 + }, + { + "cell_type": "markdown", + "source": [ + "Finally, if you know what properties you want to set on a specific object, a", + "plain ``set`` call is typically the simplest form:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "line, = plt.plot([1,2,3])", + "line.set(lw=2, c='red',ls='--')" + ], + "language": "python", + "outputs": [], + "prompt_number": 7 + }, + { + "cell_type": "markdown", + "source": [ + "Understanding what matplotlib returns: lines, axes and figures", + "==============================================================", + "", + "Lines", + "-----", + "", + "In a simple plot:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "plt.plot([1,2,3])" + ], + "language": "python", + "outputs": [], + "prompt_number": 8 + }, + { + "cell_type": "markdown", + "source": [ + "The return value of the plot call is a list of lines, which can be manipulated", + "further. If you capture the line object (in this case it's a single line so we", + "use a one-element tuple):" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "line, = plt.plot([1,2,3])", + "line.set_color('r')" + ], + "language": "python", + "outputs": [], + "prompt_number": 11 + }, + { + "cell_type": "markdown", + "source": [ + "One line property that is particularly useful to be aware of is ``set_data``:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# Create a plot and hold the line object", + "line, = plt.plot([1,2,3], label='my data')", + "plt.grid()", + "plt.title('My title')", + "", + "# ... later, we may want to modify the x/y data but keeping the rest of the", + "# figure intact, with our new data:", + "x = np.linspace(0, 1)", + "y = x**2", + "", + "# This can be done by operating on the data object itself", + "line.set_data(x, y)", + "", + "# Now we must set the axis limits manually. Note that we can also use xlim", + "# and ylim to set the x/y limits separately.", + "plt.axis([0,1,0,1])", + "", + "# Note, alternatively this can be done with:", + "ax = plt.gca() # get currently active axis object", + "ax.relim()", + "ax.autoscale_view()", + "", + "# as well as requesting matplotlib to draw", + "plt.draw()" + ], + "language": "python", + "outputs": [], + "prompt_number": 12 + }, + { + "cell_type": "markdown", + "source": [ + "The next important component, axes", + "----------------------------------", + " ", + "The ``axis`` call above was used to set the x/y limits of the axis. And in", + "previous examples we called ``.plot`` directly on axis objects. Axes are the", + "main object that contains a lot of the user-facing functionality of matplotlib::", + "", + " In [15]: f = plt.figure()", + "", + " In [16]: ax = f.add_subplot(111)", + "", + " In [17]: ax.", + " Display all 299 possibilities? (y or n)", + " ax.acorr ax.hitlist", + " ax.add_artist ax.hlines", + " ax.add_callback ax.hold", + " ax.add_collection ax.ignore_existing_data_limits", + " ax.add_line ax.images", + " ax.add_patch ax.imshow", + " ", + " ... etc.", + "", + "Many of the commands in ``plt.