{ "metadata": { "name": "10-introducing-bird-counting-FULL" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Bird counting\n", "\n", "...as a simple introduction to Python and automating analyses." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Suppose we have a spreadsheet of bird sightings by day and location, and we want to analyze and summarize the data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by making up some data of the form we want to analyze. In a real situation, this data would generally be taken from the real data -- but, since this is an entirely fictional example, here we're going to just construct some test data.\n", "\n", "The most important thing about this test data is that it should be *small* but *realistic*. We'll talk about \"realistic\" later -- for now, *small* is the key thing, because it lets you think about what your code *should* be doing." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%file birds.txt\n", "robin,kentucky,may 23\n", "robin,west virginia,may 24\n", "seagull,maine,may 24\n", "chickadee,kentucky,june 1\n", "seagull,maine,june 1" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Overwriting birds.txt\n" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by parsing the file 'birds.txt' that we created above.\n", "\n", "\"Parsing\" means \"reading in data that's in some format\". Here, we're looking at a file that is in a spreadsheet format, with each record separated by commas -- a \"comma separated value\" format file. Python has a built-in library, 'csv', that can read a wide variety of columnar formats.\n", "\n", "@@docs for csv" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Let's start by reading in each line of the file, one by one.\n", "fp = file('birds.txt', 'rb')\n", "for line in fp:\n", " print line" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "robin,kentucky,may 23\n", "\n", "robin,west virginia,may 24\n", "\n", "seagull,maine,may 24\n", "\n", "chickadee,kentucky,june 1\n", "\n", "seagull,maine,june 1\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that each line has an extra carriage return or newline after it, because 'print' adds it. You can disable that by putting a ',' after 'line' in the print statement, which tells 'print' not to do that. (Try it out!)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are a variety of ways to load this file into Python so that we can work with it. One way would be to use Python string functions to break each line up by commas, but this will not always work on complicated csv files. So instead let's use the csv\n", "module." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import csv\n", "fp = file('birds.txt', 'rb')\n", "reader = csv.reader(fp)\n", "for bird, state, day in reader:\n", " print bird, '/', state, '/', day\n", " " ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "robin / kentucky / may 23\n", "robin / west virginia / may 24\n", "seagull / maine / may 24\n", "chickadee / kentucky / june 1\n", "seagull / maine / june 1\n" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next problem here is that we are not actually doing anything with this data other than printing it out!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Storing things in lists and asking questions of the lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's suppose we want to ask some questions -- like, \"how many chickadees did we see\"? That's pretty easy to do with the above code --" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import csv\n", "fp = file('birds.txt', 'rb')\n", "reader = csv.reader(fp)\n", "\n", "n = 0\n", "for bird, state, day in reader:\n", " if bird == 'chickadee':\n", " n += 1\n", "\n", "print 'we saw', n, 'chickadees'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 1 chickadees\n" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are two different problems with this approach, though.\n", "\n", "First, every time you want to count the number of times you see a particular bird, you have to do all the file parsing and for loop stuff enough. While inefficient, the inefficiency isn't that bad -- the real problem is that you're virtually guaranteed to screw up if you copy and paste the code multiple times. (The computing principle underlying all of this is \"Don't Repeat Yourself\", or \"DRY\".) So what we really want to do is *store* the results of reading in the file *once*, and then use those results again and again.\n", "\n", "The second problem is that every time we want to count a new bird, we need to replace 'chickadee' in multiple places. We'll fix that in a moment." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# define an empty list\n", "birdlist = []\n", "\n", "fp = file('birds.txt', 'rb')\n", "reader = csv.reader(fp)\n", "\n", "n = 0\n", "for bird, state, day in reader:\n", " birdlist.append(bird)\n", "\n", "print 'we saw', birdlist.count('chickadee'), 'chickadees'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 1 chickadees\n" ] } ], "prompt_number": 6 }, { "cell_type": "code", "collapsed": false, "input": [ "print 'we saw', birdlist.count('robin'), 'robins'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 2 robins\n" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "OK, so here we're using a list to keep track of all of the birds and then we're just using a feature of lists in Python to ask for the counts of whatever bird we're interested in. Good stuff.\n", "\n", "What next? Let's solve the next problem, which is that we kind of want to wrap all of this up nicely so that we can reuse the code generically -- without specifying either the specific filename in advance, or which bird we want to count." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# to do this, define functions\n", "def read_birdlist(filename):\n", " birdlist = []\n", "\n", " fp = file('birds.txt', 'rb')\n", " reader = csv.reader(fp)\n", "\n", " n = 0\n", " for bird, state, day in reader:\n", " birdlist.append(bird)\n", " \n", " return birdlist\n", "\n", "def print_birdcount(birdlist, bird):\n", " print 'we saw', birdlist.count(bird), 'of bird type', bird\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "birdlist = read_birdlist('birds.txt')\n", "print_birdcount(birdlist, 'robin')\n", "print_birdcount(birdlist, 'chickadee')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 2 of bird type robin\n", "we saw 1 of bird type chickadee\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "A few things to note -- the functions are basically copy-paste from working code, just substituting variables in where we want to be generic. Also, we're naming the functions in nice understandable ways. And once you have them written, you can just leave 'em alone and use them again and again." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Making life more difficult for ourselves - expanding \"birdlist\".\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that 'birdlist', above, doesn't contain all of the information in the 'birds.txt' file -- it just has the first column. Let's fix that." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def read_birdlist2(filename):\n", " birdlist = []\n", "\n", " fp = file(filename, 'rb')\n", " reader = csv.reader(fp)\n", "\n", " n = 0\n", " for bird, state, day in reader:\n", " birdlist.append((bird, state, day))\n", " \n", " return birdlist" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "birdlist2 = read_birdlist2('birds.txt')\n", "print birdlist2" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[('robin', 'kentucky', 'may 23'), ('robin', 'west virginia', 'may 24'), ('seagull', 'maine', 'may 24'), ('chickadee', 'kentucky', 'june 1'), ('seagull', 'maine', 'june 1')]\n" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here what we are doing is storing multiple values in something called a 'tuple', which is basically just a comma-seperated set of values, in a list. This list is essentially identical to what we're reading out of the file; you can iterate over it like so:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for bird, state, day in birdlist2:\n", " print bird, state, day" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "robin kentucky may 23\n", "robin west virginia may 24\n", "seagull maine may 24\n", "chickadee kentucky june 1\n", "seagull maine june 1\n" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our new problem, however, is that we cannot just use 'birdlist2.count(bird)' any more, because birdlist2 contains far more than birds -- it also contains the other information. So what do we do?\n", "\n", "We rewrite print_birdcount appropriately, is what!" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def print_birdcount2(birdlist2, bird_to_count):\n", " n = 0\n", " for bird, state, day in birdlist2:\n", " if bird == bird_to_count:\n", " n += 1\n", " \n", " print 'we saw', n, 'of bird type', bird_to_count\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "print_birdcount2(birdlist2, 'robin')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 2 of bird type robin\n" ] } ], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also write generic functions to sort things out by state, etc, by filtering the list on various rules. Let's grab all the birds seen in kentucky:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def get_entries_by_state(birdlist2, query_state):\n", " newlist = []\n", " for bird, state, day in birdlist2:\n", " if state == query_state:\n", " newlist.append((bird, state, day))\n", " return newlist" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "get_entries_by_state(birdlist2, 'kentucky')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 16, "text": [ "[('robin', 'kentucky', 'may 23'), ('chickadee', 'kentucky', 'june 1')]" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "...and, since we're getting the birds out in the same form as we're loading them in -- as lists of 3-tuples (bird, state, day), we can now apply 'print_birdcount2' as we wish:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "kentucky_birds = get_entries_by_state(birdlist2, 'kentucky')\n", "print_birdcount2(kentucky_birds, 'chickadee')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 1 of bird type chickadee\n" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "You might well ask yourself, why on earth are we doing all of this to count a list of six bird entries!? Because now we can count *much* bigger lists, entirely automatically!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A bigger data set\n", "\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "bigbirdlist = read_birdlist2('long-birds.csv')\n", "print len(bigbirdlist)\n", "print bigbirdlist[:10]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "10000\n", "[('heron', 'michigan', 'april 24'), ('shoebill', 'kentucky', 'july 02'), ('vulture', 'new york', 'september 01'), ('flamingo', 'missouri', 'may 28'), ('common teal', 'maine', 'august 06'), ('heron', 'maine', 'august 19'), ('albatross', 'new york', 'july 13'), ('albatross', 'missouri', 'june 20'), ('heron', 'kansas', 'july 07'), ('little grebe', 'maine', 'may 24')]\n" ] } ], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "...and all of the functions etc above will work on this." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using sets and dictionaries\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So far we've been counting specific birds. What if we just want to get the count for *all* birds rather than just one at a time??\n", "\n", "We can do this easily like so:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "birdlist2 = read_birdlist2('birds.txt')\n", "for bird, state, day in birdlist2:\n", " print_birdcount2(birdlist2, bird)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 2 of bird type robin\n", "we saw 2 of bird type robin\n", "we saw 2 of bird type seagull\n", "we saw 1 of bird type chickadee\n", "we saw 2 of bird type seagull\n" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": {}, "source": [ "But you probably see the hitch -- each bird count is printed as many times as it's in the list! So, now what?\n", "\n", "We can get a *unique* list of birds by using a set, a type of Python data structure that collapses lists down into sets that contain at most one of anything:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "bird_types = set()\n", "for bird, state, day in birdlist2:\n", " bird_types.add(bird)\n", " \n", "print bird_types" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "set(['chickadee', 'seagull', 'robin'])\n" ] } ], "prompt_number": 20 }, { "cell_type": "code", "collapsed": false, "input": [ "# now we can just look at the unique set of birds\n", "for bird_type in bird_types:\n", " print_birdcount2(birdlist2, bird_type)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "we saw 1 of bird type chickadee\n", "we saw 2 of bird type seagull\n", "we saw 2 of bird type robin\n" ] } ], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": {}, "source": [ "This all does get a little unwieldy, though, when we're talking about thousands, hundreds of thousands, or millions of records. In that case we might just want to count *all* of the birds once, and then save the results. Is there a way to do that?\n", "\n", "The standard way in Python to store this kind of association -- really, *any* kind of association -- is to use a dictonary, which is just a way of looking up *values* by looking at their *keys*. To see this in action, here's a simple example:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "d = {}\n", "d['robin'] = 1\n", "d['seagull'] = 2" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 22 }, { "cell_type": "markdown", "metadata": {}, "source": [ "This now gives us the ability to retrieve the number of birds from 'd' by asking for the value associated with that birdname:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print d['robin']" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1\n" ] } ], "prompt_number": 23 }, { "cell_type": "markdown", "metadata": {}, "source": [ "But how do we *construct* such a dictionary? The simplest way (not necessarily the most efficient, but that's ok) is to just use our bits and bobs of code above, and copy paste." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def make_birddict(birdlist2):\n", " # first, get the unique set of birds\n", " bird_types = set()\n", " for bird, state, day in birdlist2:\n", " bird_types.add(bird)\n", " \n", " # then, copy the code from print_birdcount2:\n", " d = {}\n", " \n", " for bird_type in bird_types:\n", " n = 0\n", " for bird, state, day in birdlist2:\n", " if bird == bird_type:\n", " n += 1 \n", " \n", " d[bird_type] = n\n", " \n", " return d" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "# tada!\n", "print make_birddict(birdlist2)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'chickadee': 1, 'seagull': 2, 'robin': 2}\n" ] } ], "prompt_number": 25 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above code is *really* inefficient, though. You may notice that it reads through all of the entries in birdlist2 once for each bird_type. Is there a better way to do it?\n", "\n", "Yes -- you can *update* the values in the dictionary as you go." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def make_birddict2(birdlist2):\n", " # first, get the unique set of birds\n", " bird_types = set()\n", " for bird, state, day in birdlist2:\n", " bird_types.add(bird)\n", " \n", " # then, set the count for each bird to 0\n", " d = {}\n", " for bird in bird_types:\n", " d[bird] = 0\n", " \n", " # now, go through all of the entries in birdlist2 and, for each one, increment the count in the dictionary\n", " for bird, state, day in birdlist2:\n", " d[bird] = d[bird] + 1\n", "\n", " return d" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 26 }, { "cell_type": "code", "collapsed": false, "input": [ "make_birddict2(birdlist2)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 27, "text": [ "{'chickadee': 1, 'robin': 2, 'seagull': 2}" ] } ], "prompt_number": 27 }, { "cell_type": "markdown", "metadata": {}, "source": [ "A good rule of thumb in Python is that any time you have nested loops, you might be able to use a dictionary to do the same thing, but more efficiently." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Parsing dates\n", "\n", "It's all well and good to look at strings like we are, but what if we want to graph things by day collected? We can't just use the dates as they are, because they're not numbers that you can graph by. What we have to do is convert them into a format that Python can compare. How?\n", "\n", "We can use the function datetime.strptime, docs here: http://docs.python.org/3.3/library/datetime.html?highlight=strptime#strftime-and-strptime-behavior" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from datetime import datetime\n", "\n", "# strptime will convert strings into dates given the appropriate formatting string (see docs above)\n", "print datetime.strptime('may 21', '%B %d')\n", "\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1900-05-21 00:00:00\n" ] } ], "prompt_number": 28 }, { "cell_type": "code", "collapsed": false, "input": [ "# we should fix that year...\n", "print datetime.strptime('may 21' + ' 2013', '%B %d %Y')\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2013-05-21 00:00:00\n" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "# ok -- and now we need to convert back to a straight up number.\n", "# If all the dates are 2013, we can just ask for day of year...\n", "date = datetime.strptime('may 21' + ' 2013', '%B %d %Y')\n", "\n", "day_of_year = date.strftime('%j')\n", "print day_of_year" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "141\n" ] } ], "prompt_number": 30 }, { "cell_type": "code", "collapsed": false, "input": [ "# hmm, does that actually work!?\n", "for bird, state, day in birdlist2:\n", " date = datetime.strptime(day + ' 2013', '%B %d %Y')\n", " day_of_year = date.strftime('%j')\n", " print day, date, day_of_year " ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "may 23 2013-05-23 00:00:00 143\n", "may 24 2013-05-24 00:00:00 144\n", "may 24 2013-05-24 00:00:00 144\n", "june 1 2013-06-01 00:00:00 152\n", "june 1 2013-06-01 00:00:00 152\n" ] } ], "prompt_number": 31 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hey, that looks OK -- let's transform the list into something we want to plot, birds by day:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "birdcount_by_day = {}\n", "\n", "for bird, state, day in birdlist2:\n", " birdcount_by_day[day] = 0\n", " \n", "for bird, state, day in birdlist2:\n", " birdcount_by_day[day] = birdcount_by_day[day] + 1\n", "\n", "print birdcount_by_day\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'may 24': 2, 'may 23': 1, 'june 1': 2}\n" ] } ], "prompt_number": 32 }, { "cell_type": "code", "collapsed": false, "input": [ "plotme_x = []\n", "plotme_y = []\n", "\n", "for day in birdcount_by_day: # note, iterating over dictionaries gives you keys\n", " date = datetime.strptime(day + ' 2013', '%B %d %Y')\n", " day_of_year = date.strftime('%j')\n", " \n", " # trick: we need to convert day_of_year into an integer\n", " day_of_year = int(day_of_year)\n", " \n", " # retrieve birdcount\n", " count = birdcount_by_day[day]\n", " \n", " # now add day_of_year and birdcount\n", " plotme_x.append(day_of_year)\n", " plotme_y.append(count)\n", "\n", "print plotme_x\n", "print plotme_y" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[144, 143, 152]\n", "[2, 1, 2]\n" ] } ], "prompt_number": 33 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Doing some minimal graphing" ] }, { "cell_type": "code", "collapsed": false, "input": [ "plot(plotme_x, plotme_y, 'ro')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 34, "text": [ "[]" ] }, { "output_type": "display_data", "png": "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\nqL5nP9Sm2267Ta2traqvr9fGjRu1fPlydXZ2xnRTIBBQbW2tduzYodraWu3cuVMHDhyI6aYPHDly\nRBMnTozqn8CGs6uqqkqXLl3S2bNn5fP5tGHDBvl8vphuKisrU0pKij75yU/qgQce0Gc/+9mo/Om5\nP6tXr5bP59Mrr7yipKQkPfjggwOeO1phHc6m0TTYruPHj+sHP/iBfve73w16ragEvqmpSc3NzcrN\nzVVaWpra2tqUn5+v8+fP9zpv1qxZSk9P12uvvRaNGUPa1N7errq6On3/+99XWlqaNm3apMrKSv3m\nN7+J2abz589r/PjxwT+6zZkzR+np6Tp58mTMNrW3tys1NVXz58/XjTfeqAkTJmjx4sU6evRozDZd\n/f305JNPavny5VHfMpRd7e3teuGFF/TVr35VY8eO1S233KLCwsKo3A4Z6qbz589r7Nix2rhxo+rr\n67Vr1y51dHTo9ttvj/omSbr11lvlcDjkcDh03333BW/DxPLv0gy0KdZC7Wpra9PSpUv1+OOPKy0t\nbfCLhfkaQVCoFwU//OJhIBAwxhjT3NxsUlNTzdtvvx2pGSPadLWBXuAY7U1vvPFG8MXnpqYmk5yc\nbC5cuBDTTRcuXDBz5swx3d3dJhAImC9+8Yu93g0Ri03GGNPT02OSk5ONz+eLypaR7Nq0aZMpLS01\nxhjT1dVlsrKyTGNjY0w3dXd3m66uLmPM++/I+NznPheVPf1tOnPmTPDzjRs3mpKSEmPMf15kvXLl\ninn99dfN9OnTo/LC73A2fWD79u1Rf5F1OLsuXLhgXC6X2blz55CvHZHAFxcXm6SkJDN+/HiTkpJi\n/vCHP/Q6fvU32eOPP26ys7NNXl6e+dSnPhV8C1CkDbYpLS1t1AM/nE1PP/108Odpzpw55tlnn435\nJmPef1tidna2ycnJMQ899NA1sen55583c+fOjcqWke66fPmy+cY3vmFycnJMVlZW1N6ZNZxNPp/P\nzJw502RmZpo77rjDtLS0RHVTXFycSUlJMdu2bTP33HOPcTqdxuVymTvvvNOcO3cueP6jjz5q0tPT\nzcyZM011dfU1sekTn/iEufHGG018fLxJTU01r776asx3/exnPzOTJk3q9bbgN954I+T1HcbwD8UA\ngI0+sv9HJwCwHYEHAEsReACwFIEHAEsReACwFIEHAEv9L+Q5ZDYT6gtkAAAAAElFTkSuQmCC\n" } ], "prompt_number": 34 }, { "cell_type": "code", "collapsed": false, "input": [ "plot(plotme_x, plotme_y, 'ro')\n", "axis(ymin=0, xmin=140, xmax=160)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 35, "text": [ "(140, 160, 0, 2.2000000000000002)" ] }, { "output_type": "display_data", "png": "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\n4CHWv/D8ENT4Yq3lvffeq1AopK6uLr3zzjt67rnndPXq1VRN9bZRWVmpnp4effXVV1q2bJleeeWV\ncceyNyc23nqyP6fmt99+0y+//KL29na9/fbbevbZZ8cdO9H+TErgL1y4oN7eXvl8Pi1fvlx9fX1a\nu3atBgYGeN38JI23lpcvX9acOXMi/70rKipSdna2gsFgimc88y1dulQul0sul0svvPBC5L+57M2p\nGW892Z9T4/V69dRTT0mS1q9fr1mzZmlwcHBK+zMpgS8oKNDAwIB6enrU09Mjr9erc+fOye12q7S0\nVMeOHdPw8LB6enoUDAb1wAMPJGMaJoy3lkuXLtXg4KDC4bAk6YcfflAwGNR9992X4hnPfD/++GPk\n808++STyCgb25tSMt57sz6nZvHmzTp06JUk6f/68hoeHddddd01tfybiO8FlZWXOsmXLnDlz5jhe\nr9f58MMPo44vX7488soPx3GcvXv3OtnZ2c7999/vtLa2JmIKZkxmLT/++GNn1apVzpo1a5yioiLn\n008/TcWUZ7Q/1zM9Pd3xer3OBx984Dz//PNOQUGBs3r1aufJJ590fvrpp8h49mZsk1lP9ufExvp6\nHx4edrZu3erk5+c7RUVFzhdffBEZP9n96XIcvv0NABbxjk4AYBSBBwCjCDwAGEXgAcAoAg8ARhF4\nADDq/wCHglQYguKVFwAAAABJRU5ErkJggg==\n" } ], "prompt_number": 35 }, { "cell_type": "code", "collapsed": false, "input": [ "# if we plot with lines, we see that because the points aren't sorted, we don't get what we expect.\n", "plot(plotme_x, plotme_y, 'r-')\n", "axis(ymin=0, xmin=140, xmax=160)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 36, "text": [ "(140, 160, 0, 2.2000000000000002)" ] }, { "output_type": "display_data", "png": "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\nQmCC\n" } ], "prompt_number": 36 }, { "cell_type": "code", "collapsed": false, "input": [ "# how do we fix this? one way is to zip the two lists together, sort them, and pull them back out...\n", "plotme_all = zip(plotme_x, plotme_y)\n", "plotme_all.sort()\n", "\n", "plotme_x = []\n", "plotme_y = []\n", "for (x, y) in plotme_all:\n", " plotme_x.append(x)\n", " plotme_y.append(y)\n", "\n", "print plotme_x" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[143, 144, 152]\n" ] } ], "prompt_number": 37 }, { "cell_type": "code", "collapsed": false, "input": [ "# tada...\n", "plot(plotme_x, plotme_y, 'r-')\n", "axis(ymin=0, xmin=140, xmax=160)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 38, "text": [ "(140, 160, 0, 2.2000000000000002)" ] }, { "output_type": "display_data", "png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAD5CAYAAAAtBi5vAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEYFJREFUeJzt3X9o1fUex/HXsc1o6nWaedRzdpm5ldPN45na+kc8QSEO\nWlIRGobogrEQi4IbQtAGZtfSohREoeRKkIIRGzFHhB2tvHOEC8J525ltec6s41220ivdrdP3/uHt\n0Nx29uP8+H7PZ88HSDs73529+/L16fGzj+e4LMuyBAAwzhS7BwAApAeBBwBDEXgAMBSBBwBDEXgA\nMFROJr6Jy+XKxLcBAOMks9ExY8/gLcviV4p+vfzyy7bPYMovziXn08m/ksUSDQAYisADgKEIfBYK\nBAJ2j2AMzmVqcT6dxWWlYqFntG/icqVkPQkAJpNk28kzeAAwFIEHAEMReAAwFIEHAEMReAAwFIEH\nAEMReAAwFIEHAEMReAAwFIEHAEMReAAwVMLAh8NhPfDAA1q6dKlKS0v19ttvD3vc9u3bVVxcLJ/P\np7a2trQMCgAYn4Tv6JSbm6s333xTy5cv1/Xr17VixQo99NBDKikpiR/T1NSkzs5OhUIhnT17VrW1\ntWppaUn74ACAxBI+g583b56WL18uSZo+fbpKSkp0+fLlQcc0NjZq8+bNkqSKigr19fUpGo2maVwA\nwFiN+T1Zu7u71dbWpoqKikGf7+npUUFBQfy21+tVJBKR2+0edFxdXV3840AgMHlfN/of/5A++8zu\nKeBEL70kFRbaPQVsFAwGFQwGU/Z4Ywr89evX9fjjj+utt97S9OnTh9x/6+sVD/cm238O/KS2Z4/0\nxBPS/Pl2TwKnmTbN7glgs1uf/NbX1yf1eKMGfmBgQI899pg2bdqk9evXD7nf4/EoHA7Hb0ciEXk8\nnqSGMtZvv0mdndILL0h5eXZPA8BwCdfgLctSdXW1lixZoueee27YY6qqqnTkyBFJUktLi/Lz84cs\nz+D/Ll6UFiwg7gAyIuEz+C+++ELvvfeeli1bJr/fL0natWuXLl26JEmqqalRZWWlmpqaVFRUpGnT\npunw4cPpnzpbnT8vLV1q9xQAJgnekzWTdu6Url+X/v53uycBkAV4T9Zs0t4uLVli9xQAJgkCn0kE\nHkAGsUSTKbGYNGOG9O9/sx0OwJiwRJMtvv1WcruJO4CMIfCZwvIMgAwj8JlC4AFkGIHPFPbAA8gw\nAp8pPIMHkGHsosmEP3bQRKM3/wsAY8Aummzw3XfSnDnEHUBGEfhMYP0dgA0IfCaw/g7ABgQ+Ewg8\nABsQ+Ewg8ABswC6adPv9d+kvf5F6eqSZM+2eBkAWYReN0126JOXnE3cAGUfg043lGQA2IfDpRuAB\n2ITApxt74AHYhMCnG8/gAdiEXTTpZFk3d9B89500e7bd0wDIMuyicbJIRJo+nbgDsAWBT6f2dtbf\nAdiGwKfT+fOsvwOwDYFPJ37ACsBGBD6dCDwAG7GLJl0sS5o1S7p4UbrzTrunAZCF2EXjVJcvS7ff\nTtwB2IbApwvLMwBsRuDThcADsBmBTxf2wAOwGYFPF/bAA7AZgU8Hy2KJBoDtCHw6RKPSlCnSXXfZ\nPQmASYzAp8Mfz95dLrsnATCJEfh04E0+ADgAgU8H1t8BOACBTwcCD8ABCHw6EHgADkDgU+3KFSkW\nk+bNs3sSAJMcgU81dtAAcAgCn2oszwBwiISB37p1q9xut8rKyoa9PxgMaubMmfL7/fL7/dq5c2da\nhswqBB6AQyQM/JYtW9Tc3JzwAdasWaO2tja1tbXppZdeSulwWYk98AAcImHgV69erVmzZiV8gEn3\nTk2j4Rk8AIfISeaLXS6Xzpw5I5/PJ4/Hoz179mjJCHGrq6uLfxwIBBQIBJL51s7U2yv9+qu0YIHd\nkwDIQsFgUMFgMGWPN+p7snZ3d+vhhx/W119/PeS+a9eu6bbbblNeXp5OnDihZ599Vh0dHUO/yWR5\nT9bPPpP+9jfpn/+0exIABrD1PVlnzJihvLw8SdK6des0MDCgq1evJvOQ2Y31dwAOklTgo9Fo/E+X\n1tZWWZal2bNnp2SwrMT6OwAHSbgGv3HjRp06dUq9vb0qKChQfX29BgYGJEk1NTU6fvy4Dhw4oJyc\nHOXl5eno0aMZGdqx2tulykq7pwAASWNYg0/JN5ksa/ALFkgtLdJf/2r3JAAMYOsaPP7kp5+k69el\nggK7JwEASQQ+ddrbpZISXoMGgGMQ+FThB6wAHIbApwqBB+AwBD5V2AMPwGEIfKrwDB6AwxD4VPj5\nZ6mvj+2RAByFwKfChQvS4sXSFE4nAOegSKnA+jsAByLwqcD6OwAHIvCpQOABOBCBTwUCD8CBeLGx\nZF27Js2bJ/3yi3TbbXZPA8AgvNiY3S5ckO69l7gDcBwCnyyWZwA4FIFPFoEH4FAEPlnsgQfgUAQ+\nWTyDB+BQ7KJJxn/+I82Zc3MnTU7Ct7cFgHFjF42d/vUv6Z57iDsARyLwyTh/nuUZAI5F4JPR3s4P\nWAE4FoFPBj9gBeBgBD4ZBB6Ag7GLZqJu3JDuvPPma9Dk5to9DQADsYvGLt98IxUVEXcAjkXgJ4rl\nGQAOR+AnisADcDgCP1HsgQfgcAR+otgDD8Dh2EUzEb/+KuXn39xBM3Wq3dMAMBS7aOzQ0SHdfTdx\nB+BoBH4iWH8HkAUI/ESw/g4gCxD4iWCLJIAsQOAngsADyALsohmv//5XmjlT+vln6fbb7Z4GgMHY\nRZNpoZBUWEjcATgegR8vlmcAZAkCP14EHkCWIPDjReABZImEgd+6davcbrfKyspGPGb79u0qLi6W\nz+dTW1tbygd0nPPn2QMPICskDPyWLVvU3Nw84v1NTU3q7OxUKBTSoUOHVFtbm/IBHWVgQLp4Ubrn\nHrsnAYBRJQz86tWrNWvWrBHvb2xs1ObNmyVJFRUV6uvrUzQaTe2ETtLZKRUUSHfcYfckADCqnGS+\nuKenRwUFBfHbXq9XkUhEbrd7yLF1dXXxjwOBgAKBQDLf2h6svwNIo2AwqGAwmLLHSyrwkoZswne5\nXMMe9+fAZ61ffpHuv9/uKQAY6tYnv/X19Uk9XlKB93g8CofD8duRSEQejyepgRxtyxa7JwCAMUtq\nm2RVVZWOHDkiSWppaVF+fv6wyzMAgMxL+Ax+48aNOnXqlHp7e1VQUKD6+noNDAxIkmpqalRZWamm\npiYVFRVp2rRpOnz4cEaGBgCMjhcbAwCH4sXGAADDIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCG\nIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAA\nYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgC\nDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYKhRA9/c3KzFixeruLhY\nu3fvHnJ/MBjUzJkz5ff75ff7tXPnzrQMCgAYn5xEd8ZiMW3btk2ffPKJPB6PVq1apaqqKpWUlAw6\nbs2aNWpsbEzroACA8Un4DL61tVVFRUUqLCxUbm6uNmzYoIaGhiHHWZaVtgEBABOT8Bl8T0+PCgoK\n4re9Xq/Onj076BiXy6UzZ87I5/PJ4/Foz549WrJkyZDHqquri38cCAQUCASSmxwADBMMBhUMBlP2\neAkD73K5Rn2A8vJyhcNh5eXl6cSJE1q/fr06OjqGHPfnwAMAhrr1yW99fX1Sj5dwicbj8SgcDsdv\nh8Nheb3eQcfMmDFDeXl5kqR169ZpYGBAV69eTWooAEDyEgZ+5cqVCoVC6u7uVn9/v44dO6aqqqpB\nx0Sj0fgafGtrqyzL0uzZs9M3MQBgTBIu0eTk5Gj//v1au3atYrGYqqurVVJSooMHD0qSampqdPz4\ncR04cEA5OTnKy8vT0aNHMzI4ACAxl5WBLTAul4udNgAwTsm2k3/JCgCGIvAAYCgCDwCGIvAAYCgC\nDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCG\nIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAA\nYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvAAYCgCDwCGIvBZKBgM\n2j2CMTiXqcX5dJZRA9/c3KzFixeruLhYu3fvHvaY7du3q7i4WD6fT21tbSkfEoPxmyh1OJepxfl0\nloSBj8Vi2rZtm5qbm9Xe3q73339fFy5cGHRMU1OTOjs7FQqFdOjQIdXW1qZ1YADA2CQMfGtrq4qK\nilRYWKjc3Fxt2LBBDQ0Ng45pbGzU5s2bJUkVFRXq6+tTNBpN38QAgDHJSXRnT0+PCgoK4re9Xq/O\nnj076jGRSERut3vQcS6XKxXz4v/q6+vtHsEYnMvU4nw6R8LAjzXKlmUl/Lpb7wcApF/CJRqPx6Nw\nOBy/HQ6H5fV6Ex4TiUTk8XhSPCYAYLwSBn7lypUKhULq7u5Wf3+/jh07pqqqqkHHVFVV6ciRI5Kk\nlpYW5efnD1meAQBkXsIlmpycHO3fv19r165VLBZTdXW1SkpKdPDgQUlSTU2NKisr1dTUpKKiIk2b\nNk2HDx/OyOAAgMRG3Qe/bt06ffPNN+rs7NSOHTsk3Qx7TU1N/JgbN27o2rVr+v3331VeXj7o6/fu\n3aspU6bo6tWr8c+9+uqrKi4u1uLFi/Xxxx+n6v/FCFu3bpXb7VZZWdmQ+249l93d3brjjjvk9/vl\n9/v1zDPPZHpcxxvufNbV1cnr9cbP24kTJ+L3cW0mNpbz2dzcLInrcyxG+v2+b98+lZSUqLS0VC++\n+GL88+O+Pq0UOH36tHXu3DmrtLR00OcvXbpkrV271iosLLR+/PFHy7Is6/z585bP57P6+/utrq4u\na9GiRVYsFkvFGEYYz7ns6uoachwGG+581tXVWXv37h1yLNfm6MZzPrk+Rzfc+Tx58qT14IMPWv39\n/ZZlWdaVK1csy5rY9ZmSlypYvXq1Zs2aNeTzzz//vF577bVBn2toaNDGjRuVm5urwsJCFRUVqbW1\nNRVjGGE85xKjG+l8WsPs7OLaHN14zidGN9z5PHDggHbs2KHc3FxJ0l133SVpYtdn2l6LpqGhQV6v\nV8uWLRv0+cuXLw/aieP1etXT05OuMYww0rmUpK6uLvn9fgUCAX3++ec2TJed9u3bJ5/Pp+rqavX1\n9Uni2kzGcOdT4vqciFAopNOnT+v+++9XIBDQl19+KWli12daAn/jxg3t2rVr0D94SPQnPP8IamSJ\nzuWCBQsUDofV1tamN954Q08++aSuXbtm16hZo7a2Vl1dXfrqq680f/58vfDCCyMey7U5upHOJ9fn\nxPz222/66aef1NLSotdff11PPPHEiMeOdn2mJfAXL15Ud3e3fD6fFi5cqEgkohUrVigajbJvfpxG\nOpdXrlzR1KlT43+9Ky8v16JFixQKhWye2Pnmzp0rl8sll8ulp59+Ov7XXK7NiRnpfHJ9TozX69Wj\njz4qSVq1apWmTJmi3t7eCV2faQl8WVmZotGourq61NXVJa/Xq3PnzsntdquqqkpHjx5Vf3+/urq6\nFAqFdN9996VjDCOMdC7nzp2r3t5exWIxSdK3336rUCiku+++2+aJne/777+Pf/zhhx/GdzBwbU7M\nSOeT63Ni1q9fr5MnT0qSOjo61N/frzlz5kzs+kzFT4I3bNhgzZ8/35o6darl9Xqtd999d9D9Cxcu\njO/8sCzLeuWVV6xFixZZ9957r9Xc3JyKEYwxnnP5wQcfWEuXLrWWL19ulZeXWx999JEdIzvaH+cz\nNzfX8nq91jvvvGM99dRTVllZmbVs2TLrkUcesX744Yf48VybiY3nfHJ9jm643+/9/f3Wpk2brNLS\nUqu8vNz69NNP48eP9/p0WRY//gYAE/GOTgBgKAIPAIYi8ABgKAIPAIYi8ABgKAIPAIb6H1K6HkxW\neOb3AAAAAElFTkSuQmCC\n" } ], "prompt_number": 38 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's do this for a BIG bird list next." ] }, { "cell_type": "code", "collapsed": false, "input": [ "bigbirdcount_by_day = {}\n", "\n", "for bird, state, day in bigbirdlist:\n", " bigbirdcount_by_day[day] = 0\n", " \n", "for bird, state, day in bigbirdlist:\n", " bigbirdcount_by_day[day] = bigbirdcount_by_day[day] + 1\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 39 }, { "cell_type": "code", "collapsed": false, "input": [ "plotme = []\n", "\n", "for day in bigbirdcount_by_day: # note, iterating over dictionaries gives you keys\n", " date = datetime.strptime(day + ' 2013', '%B %d %Y')\n", " day_of_year = date.strftime('%j')\n", " \n", " # trick: we need to convert day_of_year into an integer\n", " day_of_year = int(day_of_year)\n", " \n", " # retrieve birdcount\n", " count = bigbirdcount_by_day[day]\n", " \n", " # now add day_of_year and birdcount\n", " plotme.append((day_of_year, count))\n", "\n", " \n", "plotme.sort()\n", "print plotme[:5]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[(2, 1), (14, 1), (25, 1), (31, 1), (32, 1)]\n" ] } ], "prompt_number": 40 }, { "cell_type": "code", "collapsed": false, "input": [ "plotme_x = []\n", "plotme_y = []\n", "for (x, y) in plotme:\n", " plotme_x.append(x)\n", " plotme_y.append(y)\n", "\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 41 }, { "cell_type": "code", "collapsed": false, "input": [ "plot(plotme_x, plotme_y, 'r-')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 42, "text": [ "[]" ] }, { "output_type": "display_data", "png": "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\nrUNKSkpEHs+YmBjs378fJ06cwM6dO/H3v//dox2RcCz17aypqYm44/nyyy8jKysLpaWlXucjjfZ4\nhkXsI338/ZQpUwAAkydPxje/+U289957sNvtcJypid3Y2IisrKyxbOIQ3tqlP8YnTpxAjljZZwzI\nysoa+nCuWrVq6BJzrNvZ39+PpUuXYsWKFViyZAmAyDumoo033HDDUBsj9XgCQHp6Oq688kr861//\nirhjadTOPXv2RNzxfPvtt7FlyxZMnz4dy5cvx44dO7BixYqgHs+wiH0kj7/v6elBZ2cnAKC7uxuv\nvfYaioqKUFFRgerqagBAdXX10JdurPHWroqKCmzcuBEulwt1dXU4evTo0MiisaCxsXHo/v/8z/8M\njdQZy3YqioKVK1eisLAQt91229D2SDqm3toYacezubl5KPro7e3F66+/jtLS0og6lr7a6VCtZBUJ\nx/OBBx5AQ0MD6urqsHHjRlx66aXYsGFDcI9naPqUPdm6datSUFCg5OfnKw888EC4fu2wfPLJJ0px\ncbFSXFyszJ49e6htLS0tysKFC5UZM2Yo5eXlyunTp8PetmuvvVaZMmWKYrValdzcXOWZZ57x2a77\n779fyc/PV84991xl27ZtY9bO9evXKytWrFCKioqUuXPnKt/4xjcUh8Mx5u3ctWuXYrFYlOLiYqWk\npEQpKSlRXnnllYg6pkZt3Lp1a8Qdz/fff18pLS1ViouLlaKiIuUXv/iFoii+vzeR1M5IO55qampq\nhkbjBPN4BrUQGsMwDBOZjI/anQzDMIxPWOwZhmGiABZ7hmGYKIDFnmEYJgpgsWcYhokCWOwZhmGi\ngP8PbSaqZm4oHXwAAAAASUVORK5CYII=\n" } ], "prompt_number": 42 }, { "cell_type": "code", "collapsed": false, "input": [ "birdlist = read_birdlist2('long-birds.csv')\n", "bird_dict = make_birddict2(birdlist)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 43 }, { "cell_type": "code", "collapsed": false, "input": [ "labels=[]\n", "counts=[]\n", "nbirds = len(bird_dict)\n", "for bird,count in bird_dict.iteritems():\n", " labels.append(bird)\n", " counts.append(count)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 52 }, { "cell_type": "code", "collapsed": false, "input": [ "fig = plt.figure()\n", "ax = fig.add_subplot(1,1,1)\n", "\n", "xlocations = numpy.arange(nbirds)\n", "print xlocations\n", "width = 0.6 \n", "bars = ax.bar(xlocations, counts, width=width)\n", "xtickNames = ax.set_xticklabels(labels)\n", "ax.set_xticks(xlocations-0.1)\n", "plt.setp(xtickNames, rotation=45)\n", "plt.show()\n", "ax.set_title(\"Bird counts\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0 1 2 3 4 5 6 7 8 9]\n" ] }, { "output_type": "display_data", "png": "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\nCQkJWh1XffHiRcnNzZUBAwZImzZtxNfXV3ns58yZI0uWLNFaW09T/LmYO3eudOnSRTn7b8WKFWJs\nbCznz5+XTZs2ybfffltmo2XGjh0rTk5O4ujoqBxz2b9/v7z55pvKhy3RP8UrD3iRwvHDvXr1kr59\n+8rmzZslOztbGRa3du1a6datmxw/flxE/jrJ5GUsWLBAGjVqJJ9++qmYm5vLiRMnZNWqVeLl5SU+\nPj7y7rvvlslwt61bt4qVlZV069ZNfv75Z8nLy5OIiAhp27atrFmzRkREK2O9Dxw4IGvXrhURUU7H\nHj16tEyYMEFq1KghixYtEpHCYLWzs5NLly69dJvPq+jA6sKFC6Vt27ZKd01QUJDY2dlJ8+bNdf5c\nFN/ROHfunDg5OUn37t3l7t27yvkV+/btk+rVq8svv/yi01qItOmVd9EcPnxYXFxcJDk5Wbp06SJe\nXl6SnZ0t27Ztk2+//VZcXFyUPfmXOVOzaPkrV65I8+bN5erVqyJS2N/85ptvSnR0tGRkZMj//vc/\nnY31Ll7/3bt3ZciQIXL06FHZsGGDjBgxQmbNmiW5ubmyadMmcXNzk6SkJGX+l9nuzZs3S4MGDWTi\nxIkyZMgQiYmJkQULFkhgYKD4+fmJhYWF+Pv7S8uWLcv0Wi6nT5+Wvn37KtcOKjomULQnf/36dZ2P\nuy/+TeLu3btSUFAg6enpMnLkSOnXr5+yF5+ZmSkXLlzQ2UgqIl3QiLza3zxbvXo1cnNzUadOHUya\nNAlr1qzBW2+9hbt376JGjRrKv6KFce4AcP/+ffj7+yMgIABvvPEG9PX1ERgYiJSUFPz44486HRFR\ntA3btm3DpUuXsGvXLoSHhwMAwsLCEBUVhTp16mDMmDFITU1F7dq1tdb29u3bMXr0aLRo0QI///wz\nsrOzsWHDBsTHxyM9PR2fffYZKlWqVGbjyovMnDkTV65cQefOneHt7Y3FixcjKCgIc+bMgZubm85q\nebSeBQsWYNeuXXBxcUGXLl3QuHFjDB8+HJmZmahTpw5Wr16Nc+fOoVq1ajqtiUibynyY5KOfJ3Xr\n1sW6deswYcIErF27Fm+99RZCQkLw2Wef4eHDhy/9hioK9+vXryMtLU25/OeyZcuUS6NWrVpVuVa0\nrhSFyZEjRzB8+HDk5eXh8OHD+OijjwAAPj4+eOeddxAfH4/4+Hgl3LX1+evp6YnJkycjPDwcISEh\n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\n" }, { "output_type": "pyout", "prompt_number": 58, "text": [ "" ] } ], "prompt_number": 58 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Outputting csv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is all fine and well, you say, but your advisor wants a spreadsheet. Or you want one. Let's say, you want to take all your big bird list and just print out the ones that are from kentucky into a spreadsheet. How would you do that?\n", "\n", "Basically, you want to create a 'csv' file, and, conveniently, the 'csv' module contains routines to help do that! Instead of 'csv.reader', you use 'csv.writer'." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# start by picking out the birds we want to save:\n", "birdlist2 = read_birdlist2('birds.txt')\n", "print birdlist2" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[('robin', 'kentucky', 'may 23'), ('robin', 'west virginia', 'may 24'), ('seagull', 'maine', 'may 24'), ('chickadee', 'kentucky', 'june 1'), ('seagull', 'maine', 'june 1')]\n" ] } ], "prompt_number": 44 }, { "cell_type": "code", "collapsed": false, "input": [ "kentucky_birds = []\n", "for bird, state, date in birdlist2:\n", " if state == 'kentucky':\n", " kentucky_birds.append((bird, date))\n", " \n", "print kentucky_birds" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[('robin', 'may 23'), ('chickadee', 'june 1')]\n" ] } ], "prompt_number": 45 }, { "cell_type": "code", "collapsed": false, "input": [ "import csv\n", "\n", "# now, open a file for writing, and use 'csv.writer' to write rows to it.\n", "# just for grins, use tab for a delimiter, instead of a comma.\n", "fp = file('kentucky-birds.tsv', 'wb')\n", "w = csv.writer(fp, delimiter='\\t') # <- use tab instead of the default, which is a comma\n", "\n", "for bird, date in kentucky_birds:\n", " row = (bird, date)\n", " w.writerow(row)\n", "fp.close()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 46 }, { "cell_type": "code", "collapsed": false, "input": [ "# check it out -- did it work?\n", "print open('kentucky-birds.tsv').read()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "robin\tmay 23\r\n", "chickadee\tjune 1\r\n", "\n" ] } ], "prompt_number": 47 }, { "cell_type": "markdown", "metadata": {}, "source": [ "yep!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Correlating across multiple files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You might be thinking to yourself, sure, I know how to do all of that in Excel. And heck, maybe you do.\n", "\n", "But there are three reasons you might not *want* to do it in Excel.\n", "\n", "First, by doing everything manually, your work increases in direct proportion to the number of things you want to do to the data.\n", "\n", "Second, by doing everything manually, you cause errors that give you the wrong results.\n", "\n", "And third, the trickier the analysis, the more likely it is that you introduce errors.\n", "\n", "Well, and fourth, Excel has an upper limit of 2 million rows of data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One thing that I would never want to do with Excel is integrate two different files. (I *have* done it, which is why I never want to do it again!)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%file bird-weights.txt\n", "robin,5\n", "seagull,12\n", "chickadee,4" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Overwriting bird-weights.txt\n" ] } ], "prompt_number": 48 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now suppose we want to create a combined list of birds, states, weights, and dates?\n", "\n", "This kind of merge can be done by using a dictionary to associate the birds with their weights, and then output everything to another file." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# first, load in the bird weights\n", "fp = file('bird-weights.txt', 'rb')\n", "r = csv.reader(fp)\n", "\n", "weight_dict = {}\n", "for bird, weight in r:\n", " weight_dict[bird] = weight\n", " \n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 49 }, { "cell_type": "code", "collapsed": false, "input": [ "# now, go through all of the birdlist2 entries\n", "birdlist2 = read_birdlist2('birds.txt')\n", "\n", "new_birdlist = []\n", "for bird, state, day in birdlist2:\n", " weight = weight_dict[bird]\n", " new_birdlist.append((bird,state,day,weight))\n", " \n", "print new_birdlist" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[('robin', 'kentucky', 'may 23', '5'), ('robin', 'west virginia', 'may 24', '5'), ('seagull', 'maine', 'may 24', '12'), ('chickadee', 'kentucky', 'june 1', '4'), ('seagull', 'maine', 'june 1', '12')]\n" ] } ], "prompt_number": 50 }, { "cell_type": "code", "collapsed": false, "input": [ "# what if one of the birds doesn't have a weight in the file, though?\n", "del weight_dict['robin']\n", "\n", "new_birdlist = []\n", "for bird, state, day in birdlist2:\n", " weight = weight_dict[bird]\n", " new_birdlist.append((bird,state,day,weight))\n", " \n", "print new_birdlist" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "KeyError", "evalue": "'robin'", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mnew_birdlist\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mbird\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mday\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbirdlist2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mweight\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mweight_dict\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mbird\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0mnew_birdlist\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbird\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mday\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mweight\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mKeyError\u001b[0m: 'robin'" ] } ], "prompt_number": 51 }, { "cell_type": "code", "collapsed": false, "input": [ "# change the code to be aware of potentially missing data:\n", "new_birdlist = []\n", "for bird, state, day in birdlist2:\n", " weight = weight_dict.get(bird, -1) # use '-1' or something patently absurd if no weight in table\n", " new_birdlist.append((bird,state,day,weight))\n", " \n", "print new_birdlist" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "# and now you can output to a file, or whatever." ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Some basic principles of this kind of computing\n", "\n", "Try to make your code easy to read. Rather than commenting everything to death, make your function and variable names descriptive.\n", "\n", "Test out your functions on small data sets where you know the answer.\n", "\n", "The third time you find yourself performing the same query or merge, write a function to do it instead. Corrollary: don't overplan in advance! Only do this the third time!" ] } ], "metadata": {} } ] }