├── .DS_Store ├── .gitignore ├── LICENSE ├── README.md ├── examples └── faceting.py ├── mlb-data ├── drange └── scrape-mlb.sh └── notebooks ├── 00 - The Baseball Data - Cleaning it.ipynb ├── 01 - The Basics - The API, Datasets, Your First ggplot.ipynb ├── 02 - A Case Study - Exploring a baseball dataset.ipynb ├── 03 - Looking for Trends - Colors & Stat Smooth.ipynb ├── 04 - The Strike Zone - scales, labels, and themes.ipynb ├── 05 - What's next.ipynb ├── 06 - Under the Hood.ipynb ├── baseball-pitches-clean.csv ├── baseball-pitches.csv └── old-tutorials ├── 01 - Baseball.ipynb ├── 01 - Basics - Datasets, Layers, and Geoms.ipynb └── 02 - Stats, Facets, and Scaling.ipynb /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glamp/ggplot-tutorial/2cc1d4b9b7b35f643a888a57c68c7349a3db6430/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | bin/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # Installer logs 26 | pip-log.txt 27 | pip-delete-this-directory.txt 28 | 29 | # Unit test / coverage reports 30 | htmlcov/ 31 | .tox/ 32 | .coverage 33 | .cache 34 | nosetests.xml 35 | coverage.xml 36 | 37 | # Translations 38 | *.mo 39 | 40 | # Mr Developer 41 | .mr.developer.cfg 42 | .project 43 | .pydevproject 44 | 45 | # Rope 46 | .ropeproject 47 | 48 | # Django stuff: 49 | *.log 50 | *.pot 51 | 52 | # Sphinx documentation 53 | docs/_build/ 54 | 55 | notebooks/.ipynb_checkpoints/ 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Greg Lamp 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ggplot for python 2 | ## CFP 3 | Making basic, good-looking plots in Python is tough. Matplotlib gives you great 4 | control, but at the expense of being very detailed. The rise of pandas has made 5 | Python the go-to language for data wrangling and munging but many people are 6 | still reluctant to leave R because of its outstanding data viz packages. ggplot 7 | is a port of the popular R package ggplot2. It provides a high level grammar 8 | that allow users to quickly and easily make good looking plots. So say good-bye 9 | to matplotlib, and hello to ggplot as your everyday Python plotting library! 10 | 11 | ## The Talk 12 | 13 | ### Data 14 | - [https://github.com/slnovak/mlb_terminal](https://github.com/slnovak/mlb_terminal) 15 | - [baseball-pitches-clean.csv](https://s3.amazonaws.com/yhat-examples/baseball-pitches-clean.csv) 16 | 17 | ### Outline 18 | #### Slides (20 mins) 19 | http://www.slideshare.net/Yhat/ggplot-for-python 20 | #### IPython Notebook (40-50 mins) *Safety not guaranteed* 21 | Runing the notebooks 22 | ```bash 23 | $ ipython notebook notebooks/ --pylab inline 24 | ``` 25 | 26 | ### Final Thoughts 27 | #### Where it's going 28 | #### Want to help? 29 | -------------------------------------------------------------------------------- /examples/faceting.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import pandas as pd 3 | import numpy as np 4 | 5 | N = 100 6 | industry = ['a','b','c'] 7 | city = ['x','y','z'] 8 | ind = np.random.choice(industry, N) 9 | cty = np.random.choice(city, N) 10 | jobs = np.random.randint(low=1,high=250,size=N) 11 | df_city =pd.DataFrame({'industry':ind,'city':cty,'jobs':jobs}) 12 | 13 | ## how many panels do we need? 14 | cols =df_city.city.value_counts().shape[0] 15 | fig, axes = plt.subplots(1, cols, figsize=(8, 8)) 16 | 17 | for x, city in enumerate(df_city.city.value_counts().index.values): 18 | data = df_city[(df_city['city'] == city)] 19 | data = data.groupby(['industry']).jobs.sum() 20 | print (data) 21 | print type(data.index) 22 | left= [k[0] for k in enumerate(data)] 23 | right= [k[1] for k in enumerate(data)] 24 | 25 | axes[x].bar(left,right,label="%s" % (city)) 26 | axes[x].set_xticks(left, minor=False) 27 | axes[x].set_xticklabels(data.index.values) 28 | 29 | axes[x].legend(loc='best') 30 | axes[x].grid(True) 31 | fig.suptitle('Employment By Industry By City', fontsize=20) 32 | plt.show(1) 33 | 34 | from ggplot import * 35 | 36 | print ggplot(aes(x='city'), data=df_city) + geom_bar() + facet_grid(x=None, y="city", nrow=1) 37 | -------------------------------------------------------------------------------- /mlb-data/drange: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import datetime 4 | 5 | base = datetime.datetime.strptime(sys.argv[1], "%Y-%m-%d") 6 | numdays = int(sys.argv[2]) 7 | 8 | for x in range(0, numdays): 9 | print (base - datetime.timedelta(days=x)).strftime("%Y-%m-%d") 10 | -------------------------------------------------------------------------------- /mlb-data/scrape-mlb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | cat cols-pitch.tsv > pitches.tsv 6 | for current_date in $(./drange 2013-10-01 180) 7 | do 8 | echo "Scraping day ${current_date}" 9 | for i in $(mlb games --date "${current_date}" | cut -f 1) 10 | do 11 | echo " Scraping game #${i}..." 12 | mlb game --date "$current_date" --pitches "${i}" >> pitches.tsv 13 | # mlb game --date yesterday --hits "${i}" >> hits.tsv 14 | done 15 | done 16 | -------------------------------------------------------------------------------- /notebooks/00 - The Baseball Data - Cleaning it.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": false, 13 | "input": [ 14 | "import pandas as pd\n", 15 | "import numpy as np" 16 | ], 17 | "language": "python", 18 | "metadata": {}, 19 | "outputs": [], 20 | "prompt_number": 1 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "## The Data\n", 27 | "The data comes from the MLB [PitchFX](http://www.fangraphs.com/library/misc/pitch-fx/) dataset. It's publicly available and is updated __very__ frequently.\n", 28 | "\n", 29 | "I used [`mlb_terminal`](https://github.com/slnovak/mlb_terminal) to collect 2 months worth of data from the 2013 season. You can see it in the bash script `scrape-mlb.sh`." 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "collapsed": false, 35 | "input": [ 36 | "! open http://gd2.mlb.com/components/game/mlb/year_2012/month_06/day_01/gid_2012_06_01_arimlb_sdnmlb_1/inning/inning_2.xml" 37 | ], 38 | "language": "python", 39 | "metadata": {}, 40 | "outputs": [], 41 | "prompt_number": 4 42 | }, 43 | { 44 | "cell_type": "code", 45 | "collapsed": false, 46 | "input": [ 47 | "df = pd.read_csv(\"./baseball-pitches.csv\")\n", 48 | "df.head()" 49 | ], 50 | "language": "python", 51 | "metadata": {}, 52 | "outputs": [ 53 | { 54 | "html": [ 55 | "
\n",
 56 |         "<class 'pandas.core.frame.DataFrame'>\n",
 57 |         "Int64Index: 5 entries, 0 to 4\n",
 58 |         "Data columns (total 36 columns):\n",
 59 |         "pitch_time         5  non-null values\n",
 60 |         "inning             5  non-null values\n",
 61 |         "top_or_bottom      5  non-null values\n",
 62 |         "pitcher_name       5  non-null values\n",
 63 |         "hitter_name        5  non-null values\n",
 64 |         "pitch_type         5  non-null values\n",
 65 |         "x                  5  non-null values\n",
 66 |         "y                  5  non-null values\n",
 67 |         "start_speed        5  non-null values\n",
 68 |         "end_speed          5  non-null values\n",
 69 |         "sz_top             5  non-null values\n",
 70 |         "sz_bottom          5  non-null values\n",
 71 |         "pfx_x              5  non-null values\n",
 72 |         "pfx_z              5  non-null values\n",
 73 |         "px                 5  non-null values\n",
 74 |         "pz                 5  non-null values\n",
 75 |         "x0                 5  non-null values\n",
 76 |         "y0                 5  non-null values\n",
 77 |         "ax                 5  non-null values\n",
 78 |         "ay                 5  non-null values\n",
 79 |         "az                 5  non-null values\n",
 80 |         "z0                 5  non-null values\n",
 81 |         "vx0                5  non-null values\n",
 82 |         "vy0                5  non-null values\n",
 83 |         "vz0                5  non-null values\n",
 84 |         "break_y            5  non-null values\n",
 85 |         "break_angle        5  non-null values\n",
 86 |         "break_length       5  non-null values\n",
 87 |         "pitch_name         5  non-null values\n",
 88 |         "type_confidence    5  non-null values\n",
 89 |         "zone               5  non-null values\n",
 90 |         "nasty              5  non-null values\n",
 91 |         "spin_dir           5  non-null values\n",
 92 |         "spin_rate          5  non-null values\n",
 93 |         "comments           0  non-null values\n",
 94 |         "unk                0  non-null values\n",
 95 |         "dtypes: float64(28), int64(1), object(7)\n",
 96 |         "
" 97 | ], 98 | "metadata": {}, 99 | "output_type": "pyout", 100 | "prompt_number": 30, 101 | "text": [ 102 | "\n", 103 | "Int64Index: 5 entries, 0 to 4\n", 104 | "Data columns (total 36 columns):\n", 105 | "pitch_time 5 non-null values\n", 106 | "inning 5 non-null values\n", 107 | "top_or_bottom 5 non-null values\n", 108 | "pitcher_name 5 non-null values\n", 109 | "hitter_name 5 non-null values\n", 110 | "pitch_type 5 non-null values\n", 111 | "x 5 non-null values\n", 112 | "y 5 non-null values\n", 113 | "start_speed 5 non-null values\n", 114 | "end_speed 5 non-null values\n", 115 | "sz_top 5 non-null values\n", 116 | "sz_bottom 5 non-null values\n", 117 | "pfx_x 5 non-null values\n", 118 | "pfx_z 5 non-null values\n", 119 | "px 5 non-null values\n", 120 | "pz 5 non-null values\n", 121 | "x0 5 non-null values\n", 122 | "y0 5 non-null values\n", 123 | "ax 5 non-null values\n", 124 | "ay 5 non-null values\n", 125 | "az 5 non-null values\n", 126 | "z0 5 non-null values\n", 127 | "vx0 5 non-null values\n", 128 | "vy0 5 non-null values\n", 129 | "vz0 5 non-null values\n", 130 | "break_y 5 non-null values\n", 131 | "break_angle 5 non-null values\n", 132 | "break_length 5 non-null values\n", 133 | "pitch_name 5 non-null values\n", 134 | "type_confidence 5 non-null values\n", 135 | "zone 5 non-null values\n", 136 | "nasty 5 non-null values\n", 137 | "spin_dir 5 non-null values\n", 138 | "spin_rate 5 non-null values\n", 139 | "comments 0 non-null values\n", 140 | "unk 0 non-null values\n", 141 | "dtypes: float64(28), int64(1), object(7)" 142 | ] 143 | } 144 | ], 145 | "prompt_number": 30 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "Let's limit this to a few less columns." 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "Cleaning the `pitch_name` column." 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "collapsed": false, 164 | "input": [ 165 | "lu = \"\"\"FA,Fastball\n", 166 | "FF,Fastball\n", 167 | "FT,Fastball\n", 168 | "FC,Cut fastball\n", 169 | "FS,Fastball (sinker|split-fingered)\n", 170 | "SI,Fastball (sinker|split-fingered)\n", 171 | "SF,Fastball (sinker|split-fingered)\n", 172 | "SL,Slider\n", 173 | "CH,Changeup\n", 174 | "CB,Curveball\n", 175 | "CU,Curveball\n", 176 | "KC,Curveball\n", 177 | "KN,Knuckleball\n", 178 | "EP,Eephus\n", 179 | "UN,Unidentified\n", 180 | "XX,Unidentified\n", 181 | "PO,Pitch out\n", 182 | "FO,Pitch out\"\"\".split('\\n')" 183 | ], 184 | "language": "python", 185 | "metadata": {}, 186 | "outputs": [], 187 | "prompt_number": 31 188 | }, 189 | { 190 | "cell_type": "code", 191 | "collapsed": false, 192 | "input": [ 193 | "for row in lu:\n", 194 | " row = row.split(',')\n", 195 | " abbrv, name = row[0], row[1]\n", 196 | " df['pitch_name'] = df['pitch_name'].replace(abbrv, name)\n", 197 | "df['pitch_name'] = df['pitch_name']\n", 198 | "# df = df[df.pitch_name.isin(df.pitch_name.value_counts().head(8).index)]" 199 | ], 200 | "language": "python", 201 | "metadata": {}, 202 | "outputs": [], 203 | "prompt_number": 32 204 | }, 205 | { 206 | "cell_type": "code", 207 | "collapsed": false, 208 | "input": [ 209 | "df.ix[:,:10].head()" 210 | ], 211 | "language": "python", 212 | "metadata": {}, 213 | "outputs": [ 214 | { 215 | "html": [ 216 | "
\n", 217 | "\n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | "
pitch_timeinningtop_or_bottompitcher_namehitter_namepitch_typexystart_speedend_speed
0 2013-10-01 20:07:43 -0400 1 Top Francisco Liriano Shin-Soo Choo B 78.97 164.92 93.2 85.3
1 2013-10-01 20:07:57 -0400 1 Top Francisco Liriano Shin-Soo Choo S 82.40 131.24 93.4 85.6
2 2013-10-01 20:08:12 -0400 1 Top Francisco Liriano Shin-Soo Choo S 96.14 161.47 89.1 82.8
3 2013-10-01 20:08:31 -0400 1 Top Francisco Liriano Shin-Soo Choo S 106.44 163.19 90.0 83.3
4 2013-10-01 20:09:09 -0400 1 Top Francisco Liriano Ryan Ludwick B 163.95 194.28 87.7 81.6
\n", 301 | "
" 302 | ], 303 | "metadata": {}, 304 | "output_type": "pyout", 305 | "prompt_number": 33, 306 | "text": [ 307 | " pitch_time inning top_or_bottom pitcher_name \\\n", 308 | "0 2013-10-01 20:07:43 -0400 1 Top Francisco Liriano \n", 309 | "1 2013-10-01 20:07:57 -0400 1 Top Francisco Liriano \n", 310 | "2 2013-10-01 20:08:12 -0400 1 Top Francisco Liriano \n", 311 | "3 2013-10-01 20:08:31 -0400 1 Top Francisco Liriano \n", 312 | "4 2013-10-01 20:09:09 -0400 1 Top Francisco Liriano \n", 313 | "\n", 314 | " hitter_name pitch_type x y start_speed end_speed \n", 315 | "0 Shin-Soo Choo B 78.97 164.92 93.2 85.3 \n", 316 | "1 Shin-Soo Choo S 82.40 131.24 93.4 85.6 \n", 317 | "2 Shin-Soo Choo S 96.14 161.47 89.1 82.8 \n", 318 | "3 Shin-Soo Choo S 106.44 163.19 90.0 83.3 \n", 319 | "4 Ryan Ludwick B 163.95 194.28 87.7 81.6 " 320 | ] 321 | } 322 | ], 323 | "prompt_number": 33 324 | }, 325 | { 326 | "cell_type": "code", 327 | "collapsed": false, 328 | "input": [ 329 | "df.ix[:,25:].head()" 330 | ], 331 | "language": "python", 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "html": [ 336 | "
\n", 337 | "\n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | "
break_ybreak_anglebreak_lengthpitch_nametype_confidencezonenastyspin_dirspin_ratecommentsunk
0 23.8-41.3 6.3 Fastball 0.894 9 65 120.583 2541.561 NaNNaN
1 23.8-44.6 5.4 Fastball 0.895 12 62 128.371 2589.087 NaNNaN
2 23.8-10.4 5.8 Slider 0.931 8 32 148.073 1133.227 NaNNaN
3 23.8 2.6 6.8 Slider 0.926 8 34 189.793 430.593 NaNNaN
4 23.8 -3.1 7.3 Slider 0.915 13 55 140.567 482.080 NaNNaN
\n", 427 | "
" 428 | ], 429 | "metadata": {}, 430 | "output_type": "pyout", 431 | "prompt_number": 34, 432 | "text": [ 433 | " break_y break_angle break_length pitch_name type_confidence zone \\\n", 434 | "0 23.8 -41.3 6.3 Fastball 0.894 9 \n", 435 | "1 23.8 -44.6 5.4 Fastball 0.895 12 \n", 436 | "2 23.8 -10.4 5.8 Slider 0.931 8 \n", 437 | "3 23.8 2.6 6.8 Slider 0.926 8 \n", 438 | "4 23.8 -3.1 7.3 Slider 0.915 13 \n", 439 | "\n", 440 | " nasty spin_dir spin_rate comments unk \n", 441 | "0 65 120.583 2541.561 NaN NaN \n", 442 | "1 62 128.371 2589.087 NaN NaN \n", 443 | "2 32 148.073 1133.227 NaN NaN \n", 444 | "3 34 189.793 430.593 NaN NaN \n", 445 | "4 55 140.567 482.080 NaN NaN " 446 | ] 447 | } 448 | ], 449 | "prompt_number": 34 450 | }, 451 | { 452 | "cell_type": "code", 453 | "collapsed": false, 454 | "input": [ 455 | "df.ix[:,25:].head()" 456 | ], 457 | "language": "python", 458 | "metadata": {}, 459 | "outputs": [ 460 | { 461 | "html": [ 462 | "
\n", 463 | "\n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | "
break_ybreak_anglebreak_lengthpitch_nametype_confidencezonenastyspin_dirspin_ratecommentsunk
0 23.8-41.3 6.3 Fastball 0.894 9 65 120.583 2541.561 NaNNaN
1 23.8-44.6 5.4 Fastball 0.895 12 62 128.371 2589.087 NaNNaN
2 23.8-10.4 5.8 Slider 0.931 8 32 148.073 1133.227 NaNNaN
3 23.8 2.6 6.8 Slider 0.926 8 34 189.793 430.593 NaNNaN
4 23.8 -3.1 7.3 Slider 0.915 13 55 140.567 482.080 NaNNaN
\n", 553 | "
" 554 | ], 555 | "metadata": {}, 556 | "output_type": "pyout", 557 | "prompt_number": 35, 558 | "text": [ 559 | " break_y break_angle break_length pitch_name type_confidence zone \\\n", 560 | "0 23.8 -41.3 6.3 Fastball 0.894 9 \n", 561 | "1 23.8 -44.6 5.4 Fastball 0.895 12 \n", 562 | "2 23.8 -10.4 5.8 Slider 0.931 8 \n", 563 | "3 23.8 2.6 6.8 Slider 0.926 8 \n", 564 | "4 23.8 -3.1 7.3 Slider 0.915 13 \n", 565 | "\n", 566 | " nasty spin_dir spin_rate comments unk \n", 567 | "0 65 120.583 2541.561 NaN NaN \n", 568 | "1 62 128.371 2589.087 NaN NaN \n", 569 | "2 32 148.073 1133.227 NaN NaN \n", 570 | "3 34 189.793 430.593 NaN NaN \n", 571 | "4 55 140.567 482.080 NaN NaN " 572 | ] 573 | } 574 | ], 575 | "prompt_number": 35 576 | }, 577 | { 578 | "cell_type": "code", 579 | "collapsed": false, 580 | "input": [ 581 | "df = df[df.pitch_name.isin([\"IN\", \"Pitch out\", \"SC\"])==False]\n", 582 | "df = df[df.pitch_name.isnull()==False]" 583 | ], 584 | "language": "python", 585 | "metadata": {}, 586 | "outputs": [], 587 | "prompt_number": 37 588 | }, 589 | { 590 | "cell_type": "code", 591 | "collapsed": false, 592 | "input": [ 593 | "df.to_csv(\"./baseball-pitches-clean.csv\", index=False)" 594 | ], 595 | "language": "python", 596 | "metadata": {}, 597 | "outputs": [], 598 | "prompt_number": 38 599 | } 600 | ], 601 | "metadata": {} 602 | } 603 | ] 604 | } -------------------------------------------------------------------------------- /notebooks/01 - The Basics - The API, Datasets, Your First ggplot.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": false, 13 | "input": [ 14 | "# import * is a personal choice\n", 15 | "from ggplot import *\n", 16 | "# our trusty old friends\n", 17 | "import pandas as pd\n", 18 | "import numpy as np" 19 | ], 20 | "language": "python", 21 | "metadata": {}, 22 | "outputs": [], 23 | "prompt_number": 2 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "%matplotlib inline" 30 | ], 31 | "language": "python", 32 | "metadata": {}, 33 | "outputs": [], 34 | "prompt_number": 1 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "## Built in datasets" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "collapsed": false, 46 | "input": [ 47 | "meat.head()" 48 | ], 49 | "language": "python", 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "html": [ 54 | "
\n", 55 | "\n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | "
datebeefvealporklamb_and_muttonbroilersother_chickenturkey
01944-01-01 751 85 1280 89NaNNaNNaN
11944-02-01 713 77 1169 72NaNNaNNaN
21944-03-01 741 90 1128 75NaNNaNNaN
31944-04-01 650 89 978 66NaNNaNNaN
41944-05-01 681 106 1029 78NaNNaNNaN
\n", 127 | "

5 rows \u00d7 8 columns

\n", 128 | "
" 129 | ], 130 | "metadata": {}, 131 | "output_type": "pyout", 132 | "prompt_number": 3, 133 | "text": [ 134 | " date beef veal pork lamb_and_mutton broilers other_chicken \\\n", 135 | "0 1944-01-01 751 85 1280 89 NaN NaN \n", 136 | "1 1944-02-01 713 77 1169 72 NaN NaN \n", 137 | "2 1944-03-01 741 90 1128 75 NaN NaN \n", 138 | "3 1944-04-01 650 89 978 66 NaN NaN \n", 139 | "4 1944-05-01 681 106 1029 78 NaN NaN \n", 140 | "\n", 141 | " turkey \n", 142 | "0 NaN \n", 143 | "1 NaN \n", 144 | "2 NaN \n", 145 | "3 NaN \n", 146 | "4 NaN \n", 147 | "\n", 148 | "[5 rows x 8 columns]" 149 | ] 150 | } 151 | ], 152 | "prompt_number": 3 153 | }, 154 | { 155 | "cell_type": "code", 156 | "collapsed": false, 157 | "input": [ 158 | "diamonds.head()" 159 | ], 160 | "language": "python", 161 | "metadata": {}, 162 | "outputs": [ 163 | { 164 | "html": [ 165 | "
\n", 166 | "\n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | "
caratcutcolorclaritydepthtablepricexyz
0 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
\n", 250 | "

5 rows \u00d7 10 columns

\n", 251 | "
" 252 | ], 253 | "metadata": {}, 254 | "output_type": "pyout", 255 | "prompt_number": 4, 256 | "text": [ 257 | " carat cut color clarity depth table price x y z\n", 258 | "0 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43\n", 259 | "1 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31\n", 260 | "2 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31\n", 261 | "3 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63\n", 262 | "4 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75\n", 263 | "\n", 264 | "[5 rows x 10 columns]" 265 | ] 266 | } 267 | ], 268 | "prompt_number": 4 269 | }, 270 | { 271 | "cell_type": "code", 272 | "collapsed": false, 273 | "input": [ 274 | "mtcars.head()" 275 | ], 276 | "language": "python", 277 | "metadata": {}, 278 | "outputs": [ 279 | { 280 | "html": [ 281 | "
\n", 282 | "\n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | "
namempgcyldisphpdratwtqsecvsamgearcarb
0 Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
1 Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
2 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
3 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
4 Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
\n", 378 | "

5 rows \u00d7 12 columns

\n", 379 | "
" 380 | ], 381 | "metadata": {}, 382 | "output_type": "pyout", 383 | "prompt_number": 5, 384 | "text": [ 385 | " name mpg cyl disp hp drat wt qsec vs am gear \\\n", 386 | "0 Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 \n", 387 | "1 Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 \n", 388 | "2 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 \n", 389 | "3 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 \n", 390 | "4 Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 \n", 391 | "\n", 392 | " carb \n", 393 | "0 4 \n", 394 | "1 4 \n", 395 | "2 1 \n", 396 | "3 1 \n", 397 | "4 2 \n", 398 | "\n", 399 | "[5 rows x 12 columns]" 400 | ] 401 | } 402 | ], 403 | "prompt_number": 5 404 | }, 405 | { 406 | "cell_type": "code", 407 | "collapsed": false, 408 | "input": [ 409 | "pageviews.head()" 410 | ], 411 | "language": "python", 412 | "metadata": {}, 413 | "outputs": [ 414 | { 415 | "html": [ 416 | "
\n", 417 | "\n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | "
date_hourpageviews
02013-02-11 21:00:00 8860.982383
12013-02-11 22:00:00 8637.474753
22013-02-11 23:00:00 9020.593099
32013-02-12 00:00:00 8437.500380
42013-02-12 01:00:00 9157.399672
\n", 453 | "
" 454 | ], 455 | "metadata": {}, 456 | "output_type": "pyout", 457 | "prompt_number": 7, 458 | "text": [ 459 | " date_hour pageviews\n", 460 | "0 2013-02-11 21:00:00 8860.982383\n", 461 | "1 2013-02-11 22:00:00 8637.474753\n", 462 | "2 2013-02-11 23:00:00 9020.593099\n", 463 | "3 2013-02-12 00:00:00 8437.500380\n", 464 | "4 2013-02-12 01:00:00 9157.399672" 465 | ] 466 | } 467 | ], 468 | "prompt_number": 7 469 | }, 470 | { 471 | "cell_type": "markdown", 472 | "metadata": {}, 473 | "source": [ 474 | "## The API\n", 475 | "\n", 476 | "### `ggplot`\n", 477 | "`ggplot`'s API revolves around the `ggplot` class. It's class that behaves much more like a function (you don't really operate on `ggplot` methods). " 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "collapsed": false, 483 | "input": [ 484 | "?ggplot" 485 | ], 486 | "language": "python", 487 | "metadata": {}, 488 | "outputs": [], 489 | "prompt_number": 9 490 | }, 491 | { 492 | "cell_type": "markdown", 493 | "metadata": {}, 494 | "source": [ 495 | "ggplots take 2 arguments: a data frame and accompanying \"aesthetics\" or `aes`. These are equivalent." 496 | ] 497 | }, 498 | { 499 | "cell_type": "code", 500 | "collapsed": false, 501 | "input": [ 502 | "p = ggplot(aes(x='wt'), data=mtcars)" 503 | ], 504 | "language": "python", 505 | "metadata": {}, 506 | "outputs": [], 507 | "prompt_number": 6 508 | }, 509 | { 510 | "cell_type": "code", 511 | "collapsed": false, 512 | "input": [ 513 | "p = ggplot(mtcars, aes(x='wt'))" 514 | ], 515 | "language": "python", 516 | "metadata": {}, 517 | "outputs": [], 518 | "prompt_number": 7 519 | }, 520 | { 521 | "cell_type": "markdown", 522 | "metadata": {}, 523 | "source": [ 524 | "A ggplot is a \"base layer\". It won't create any aesthetics but think of it as a canvas. Watch what happens when you render it." 525 | ] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "collapsed": false, 530 | "input": [ 531 | "p" 532 | ], 533 | "language": "python", 534 | "metadata": {}, 535 | "outputs": [ 536 | { 537 | "metadata": {}, 538 | "output_type": "display_data", 539 | "png": "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\n1rVaLU6dOhXd3d0xMTERv/rVr2y9zaxn57eu+81vfhN33nlnm07KjVrP1leuXFl+m9v+/v6Ym5tr\n44nZqPVs/cILL8Ttt98e999/f8zNzcWPfvSjuOeee6JcLrfx5GTdd9998dGPfjSeeuqpd/38Rpps\n1V/js1HeArE41rP1+973vuju7o6I61vX6/V2HJUbsJ6dIyJ+//vfx4EDB2LPnj1tOCWbYT1bv/TS\nS/HBD35w+Z3K7L09rWfrvr6+WFhYiIiIhYWF6OnpEY/b0P79+5f/O/xuNtJkWxKQ7/YWiDMzMyuu\n+V9vgcj2sp6t3+4Pf/jDO/5WPze/9excr9fj5Zdfjo985COtPh6baD1bT01NxZUrV+JnP/tZ/PSn\nP13+XcBsL+vZemRkJP75z3/G97///fjJT34Sn/vc51p9TFpgI022JQF5o2+ByPaR2frVV1+NP/7x\nj/HZz352C0/EVljPzmfOnIn7778/SqVS+Lt529d6tr527Vr84x//iC9/+cvxla98JcbHx+Nf//pX\nC07HZlrP1r/73e/itttui+9+97vxzW9+M5577rnl70hSbFvyM5A3+haIbB/r3fH111+PX/7yl3Hy\n5Mno6elp5RHZBOvZ+e9//3s88cQTERHx5ptvxsWLF6OjoyPuvvvulp6VG7Oerfv7+2P37t3R2dkZ\nnZ2dsX///nj99dfjlltuafVxuQHr2fq1116LT3/60xERyy93v/HGG/He9763pWdla22kybbkO5A3\n+haIbB/r2frf//53/OIXv4jPf/7z/gOzTa1n50cffXT5nwMHDsTx48fF4za03v///utf/xqNRiOu\nXr0ak5OT3qp2G1rP1rfeemv8+c9/jojr75v8xhtvRK1Wa8dx2UIbabIt+z2Qb/1qgLfeAvFTn/rU\nirdAjIh47rnn4uLFi8tvgbhv376tOApbbK2tn3nmmbhw4cLyz9p0dHTEN77xjXYemQ1Yz7/Tb3n6\n6afjrrvu8mt8tqn1bP3888/H//3f/0WpVIqRkZH42Mc+1s4js0FrbT03NxfPPPNMXL58OZrNZhw+\nfDjuueeeNp+arCeeeCL+8pe/xJtvvhm9vb3xmc98JhqNRkRsvMn8InEAAFK25CVsAAB2LgEJAECK\ngAQAIEVAAgCQIiABAEgRkAAApAhIAABS/h/62YH95FMTSgAAAABJRU5ErkJggg==\n", 540 | "text": [ 541 | "" 542 | ] 543 | }, 544 | { 545 | "metadata": {}, 546 | "output_type": "pyout", 547 | "prompt_number": 8, 548 | "text": [ 549 | "" 550 | ] 551 | } 552 | ], 553 | "prompt_number": 8 554 | }, 555 | { 556 | "cell_type": "markdown", 557 | "metadata": {}, 558 | "source": [ 559 | "### `aes`\n", 560 | "Aesthetics or `aes` define how ggplot with extract data from your data frame and render it. Think of it as the instructions for creating x, y, color, etc. components.\n", 561 | "\n", 562 | "`aes` is just a dictionary with keys being an aesthetic property and values being strings or formulas--for more on formulas read [this]( http://patsy.readthedocs.org/en/v0.1.0/formulas.html)--relating to data in your data frame." 563 | ] 564 | }, 565 | { 566 | "cell_type": "code", 567 | "collapsed": false, 568 | "input": [ 569 | "aes(x='date', y='price')" 570 | ], 571 | "language": "python", 572 | "metadata": {}, 573 | "outputs": [ 574 | { 575 | "metadata": {}, 576 | "output_type": "pyout", 577 | "prompt_number": 9, 578 | "text": [ 579 | "{'y': 'price', 'x': 'date'}" 580 | ] 581 | } 582 | ], 583 | "prompt_number": 9 584 | }, 585 | { 586 | "cell_type": "code", 587 | "collapsed": false, 588 | "input": [ 589 | "# shorthand\n", 590 | "aes('date', 'price')" 591 | ], 592 | "language": "python", 593 | "metadata": {}, 594 | "outputs": [ 595 | { 596 | "metadata": {}, 597 | "output_type": "pyout", 598 | "prompt_number": 10, 599 | "text": [ 600 | "{u'y': 'price', u'x': 'date'}" 601 | ] 602 | } 603 | ], 604 | "prompt_number": 10 605 | }, 606 | { 607 | "cell_type": "code", 608 | "collapsed": false, 609 | "input": [ 610 | "# shorthand\n", 611 | "aes('date', 'price', 'name')" 612 | ], 613 | "language": "python", 614 | "metadata": {}, 615 | "outputs": [ 616 | { 617 | "metadata": {}, 618 | "output_type": "pyout", 619 | "prompt_number": 11, 620 | "text": [ 621 | "{u'y': 'price', u'x': 'date', u'color': 'name'}" 622 | ] 623 | } 624 | ], 625 | "prompt_number": 11 626 | }, 627 | { 628 | "cell_type": "code", 629 | "collapsed": false, 630 | "input": [ 631 | "# formula\n", 632 | "aes(x='date', y='price', color='date * price', shape='factor(name)')" 633 | ], 634 | "language": "python", 635 | "metadata": {}, 636 | "outputs": [ 637 | { 638 | "metadata": {}, 639 | "output_type": "pyout", 640 | "prompt_number": 12, 641 | "text": [ 642 | "{'color': 'date * price', 'y': 'price', 'shape': 'factor(name)', 'x': 'date'}" 643 | ] 644 | } 645 | ], 646 | "prompt_number": 12 647 | }, 648 | { 649 | "cell_type": "markdown", 650 | "metadata": {}, 651 | "source": [ 652 | "## Your first `ggplot`\n", 653 | "\n", 654 | "So taking everything that we've learned, let's use the `mtcars` dataset to plot the relationship between car weight (`wt`) and miles per gallon (`mpg`). First create a `ggplot` object with the proper `aes` and name it `p`." 655 | ] 656 | }, 657 | { 658 | "cell_type": "code", 659 | "collapsed": false, 660 | "input": [ 661 | "p = ggplot(aes(x='wt', y='mpg'), data=mtcars)\n", 662 | "p" 663 | ], 664 | "language": "python", 665 | "metadata": {}, 666 | "outputs": [ 667 | { 668 | "metadata": {}, 669 | "output_type": "display_data", 670 | "png": "iVBORw0KGgoAAAANSUhEUgAAApAAAAHhCAYAAADZI46pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHBdJREFUeJzt3W9r3Xf9x/H3yTlpkjY5yekW2eq0XliWWerc0oj/qrUw\nL9gyNrRe0TopougE2QVvgDdABEFQxy6I9Iow9ke3UPGCBNkFR6s/t17oluLEGR12JvYkWZMmPed3\noSwubiZ5p8k5Tb6PBwx6ku/J+Rxezj3JSXNKzWazGQAAsE4d7T4AAADbi4AEACBFQAIAkCIgAQBI\nEZAAAKQISAAAUiprXfD000/HxMRE7NmzJx555JF3vWZsbCwuXrwYnZ2d8dBDD8Xtt9++6QcFAODm\nsOZ3IO+77744efLk//z8K6+8ElNTU/Gd73wnHnjggXj22Wc39YAAANxc1gzI/fv3R3d39//8/Msv\nvxz33ntvRETccccdMT8/H7Ozs5t3QgAAbiprvoS9lpmZmahWq8u3q9Vq1Ov16O3tjXq9/o6Y7O3t\nXXE9AADbyw0H5GrOnTsX4+PjKz525MiROHr06FY+LAAAW+iGA7Kvry8uX768fLtery9/h/HQoUMx\nPDy84vre3t6Ynp6OpaWlG33obaOrqysWFhbafYyWqlQqUavVbL3DFXXnCFsXia2LoWg7R/xn6w3d\n90YffHh4OF544YX40Ic+FK+99lp0d3dHb29vRFx/OfvdXq6+dOlSLC4u3uhDbxuVSqVQz/ftlpaW\nCvXci7p10XaOsHWR2LoYirrzRq0ZkE888UT85S9/iTfffDN+8IMfxGc+85loNBoRETE6Ohp33XVX\nTExMxA9/+MPYtWtXPPjgg1t+aAAA2mfNgDxx4sSaX+T48eObchgAAG5+3okGAIAUAQkAQIqABAAg\nRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgA\nAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqA\nBAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACk\nCEgAAFIEJAAAKaVms9ls5QPOz8/H/Px8tPhh26qjoyMajUa7j9FSpVIpdu3aFVevXrX1DlbUnSNs\nXSS2Loai7RxxfeuBgYEN3beyyWdZU3d3d8zMzMTi4mKrH7ptenp64sqVK+0+Rkt1dnbGwMBAzM3N\n2XoHK+rOEbYuElsXQ9F2jri+9UZ5CRsAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQk\nAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBF\nQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAA\nUgQkAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKRU1rpgYmIizpw5E81mM0ZGRuLw4cMr\nPj83NxdPPvlkzM7ORqPRiE984hNx3333bdmBAQBor1UDstFoxNjYWDz88MNRrVbjsccei+Hh4Rgc\nHFy+5oUXXojbb7897r///pibm4sf/ehHcc8990S5XN7ywwMA0HqrvoQ9OTkZe/fujVqtFuVyOQ4e\nPBgXLlxYcU1fX18sLCxERMTCwkL09PSIRwCAHWzVgKzX69Hf3798u1qtxszMzIprRkZG4p///Gd8\n//vfj5/85Cfxuc99bmtOCgDATWHVl7BLpdKaX+B3v/td3HbbbXHq1KmYmpqKn//85/Gtb30rurq6\nol6vx+zs7Irre3t7o1JZ80cvd5RyuRydnZ3tPkZLvbWxrXe2ou4cYesisXUxFG3niBvbeNV79vX1\nxeXLl5dv1+v1qFarK6557bXX4tOf/nRExPLL3W+88Ua8973vjXPnzsX4+PiK648cORJHjx7d8IHZ\nXmq1WruPQAvYuThsXRy2ZjWrBuS+fftiamoqpqeno6+vL86fPx8nTpxYcc2tt94af/7zn+P9739/\nzM7OxhtvvLH8P7pDhw7F8PDwiut7e3tjeno6lpaWNvmp3Ly6urqWf060KCqVStRqNVvvcEXdOcLW\nRWLrYijazhH/2XpD913tk+VyOY4dOxanT5+ORqMRIyMjMTg4GGfPno2IiNHR0fjUpz4VzzzzTPz4\nxz+OZrMZn/3sZ2P37t0Rcf1nJv/7O5YREZcuXYrFxcUNHXg7qlQqhXq+b7e0tFSo517UrYu2c4St\ni8TWxVDUnTdqzRe/h4aGYmhoaMXHRkdHl/+8Z8+e+NKXvrT5JwMA4KbknWgAAEgRkAAApAhIAABS\nBCQAACkCEgCAFAEJAECKgAQAIEVAAgCQIiABAEgRkAAApAhIAABSBCQAACkCEgCAFAEJAECKgAQA\nIEVAAgCQIiABAEgRkAAApAhIAABSBCQAACkCEgCAFAEJAECKgAQAIEVAAgCQIiABAEgRkAAApAhI\nAABSBCQAACkCEgCAFAEJAECKgAQAIEVAAgCQIiABAEgRkAAApAhIAABSBCQAACkCEgCAFAEJAECK\ngAQAIEVAAgCQUmo2m81WPuD8/HzMz89Hix+2rTo6OqLRaLT7GC1VKpVi165dcfXqVVvvYEXdOcLW\nRWLrYijazhHXtx4YGNjQfSubfJY1dXd3x8zMTCwuLrb6odump6cnrly50u5jtFRnZ2cMDAzE3Nyc\nrXewou4cYesisXUxFG3niOtbb5SXsAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUAC\nAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIE\nJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAg\nRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgpbLWBRMTE3HmzJloNpsxMjIS\nhw8ffsc1r776avz617+Oa9euxe7du+PUqVNbclgAANpv1YBsNBoxNjYWDz/8cFSr1XjsscdieHg4\nBgcHl6+5cuVKjI2NxcmTJ6O/vz/m5ua2/NAAALTPqi9hT05Oxt69e6NWq0W5XI6DBw/GhQsXVlzz\n0ksvxQc/+MHo7++PiIg9e/Zs3WkBAGi7Vb8DWa/Xl8MwIqJarcbk5OSKa6ampuLatWvxs5/9LBYW\nFuJjH/tYfPjDH16+/+zs7Irre3t7o1JZ85XzHaVcLkdnZ2e7j9FSb21s652tqDtH2LpIbF0MRds5\n4sY2XvWepVJpzS9w7dq1+Mc//hFf/epXY3FxMR5//PG444474pZbbolz587F+Pj4iuuPHDkSR48e\n3fCB2V5qtVq7j0AL2Lk4bF0ctmY1qwZkX19fXL58efl2vV6ParW64pr+/v7YvXt3dHZ2RmdnZ+zf\nvz9ef/31uOWWW+LQoUMxPDy84vre3t6Ynp6OpaWlTXwaN7eurq5YWFho9zFaqlKpRK1Ws/UOV9Sd\nI2xdJLYuhqLtHPGfrTd039U+uW/fvpiamorp6eno6+uL8+fPx4kTJ1ZcMzw8HGNjY9FoNGJpaSkm\nJyfj4x//eERcf8n7v4MzIuLSpUuxuLi4oQNvR5VKpVDP9+2WlpYK9dyLunXRdo6wdZHYuhiKuvNG\nrRqQ5XI5jh07FqdPn45GoxEjIyMxODgYZ8+ejYiI0dHRGBwcjDvvvDN+/OMfR6lUipGRkXjPe97T\nksMDANB6a/705NDQUAwNDa342Ojo6Irbn/zkJ+OTn/zk5p4MAICbkneiAQAgRUACAJAiIAEASBGQ\nAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAU\nAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEA\nSBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQIS\nAIAUAQkAQEqp2Ww2W/mA8/PzMT8/Hy1+2Lbq6OiIRqPR7mO0VKlUil27dsXVq1dtvYMVdecIWxeJ\nrYuhaDtHXN96YGBgQ/etbPJZ1tTd3R0zMzOxuLjY6odum56enrhy5Uq7j9FSnZ2dMTAwEHNzc7be\nwYq6c4Sti8TWxVC0nSOub71RXsIGACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBA\nioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAA\nAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQB\nCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAAplbUumJiYiDNnzkSz2YyRkZE4fPjwu143\nOTkZjz/+eHzxi1+MAwcObPpBAQC4Oaz6HchGoxFjY2Nx8uTJ+Pa3vx0vvfRSXLp06V2v+81vfhN3\n3nnnlh0UAICbw6oBOTk5GXv37o1arRblcjkOHjwYFy5ceMd1v//97+PAgQOxZ8+eLTsoAAA3h1Vf\nwq7X69Hf3798u1qtxuTk5Duuefnll+OrX/1qPPPMM+/43Ozs7IqP9fb2RqWy5ivnO0q5XI7Ozs52\nH6Ol3trY1jtbUXeOsHWR2LoYirZzxI1tvOo9S6XSml/gzJkzcf/990epVIpms7nic+fOnYvx8fEV\nHzty5EgcPXp0A0dlO6rVau0+Ai1g5+KwdXHYmtWsGpB9fX1x+fLl5dv1ej2q1eqKa/7+97/HE088\nERERb775Zly8eDE6Ojri7rvvjkOHDsXw8PCK63t7e2N6ejqWlpY26znc9Lq6umJhYaHdx2ipSqUS\ntVrN1jtcUXeOsHWR2LoYirZzxH+23tB9V/vkvn37YmpqKqanp6Ovry/Onz8fJ06cWHHNo48+uvzn\np59+Ou666664++67I+L6S97/HZwREZcuXYrFxcUNHXg7qlQqhXq+b7e0tFSo517UrYu2c4Sti8TW\nxVDUnTdq1YAsl8tx7NixOH36dDQajRgZGYnBwcE4e/ZsRESMjo625JAAANw81vzpyaGhoRgaGlrx\nsf8Vjg899NDmnAoAgJuWd6IBACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAE\nACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQI\nSAAAUgQkAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBA\nioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBASqnZbDZb+YDz8/MxPz8fLX7Y\nturo6IhGo9HuY7RUqVSKXbt2xdWrV229gxV15whbF4mti6FoO0dc33pgYGBD961s8lnW1N3dHTMz\nM7G4uNjqh26bnp6euHLlSruP0VKdnZ0xMDAQc3Nztt7BirpzhK2LxNbFULSdI65vvVFewgYAIEVA\nAgCQIiABAEgRkAAApAhIAABSBCQAACkCEgCAFAEJAECKgAQAIEVAAgCQIiABAEgRkAAApAhIAABS\nBCQAACkCEgCAFAEJAECKgAQAIEVAAgCQIiABAEgRkAAApAhIAABSBCQAACkCEgCAFAEJAECKgAQA\nIEVAAgCQIiABAEgRkAAApAhIAABSBCQAACkCEgCAFAEJAECKgAQAIEVAAgCQIiABAEgRkAAApAhI\nAABSBCQAACmV9Vw0MTERZ86ciWazGSMjI3H48OEVn3/xxRfj+eefj2azGV1dXXH8+PG47bbbtuTA\nAAC015oB2Wg0YmxsLB5++OGoVqvx2GOPxfDwcAwODi5fU6vV4tSpU9Hd3R0TExPxq1/9Kr7+9a9v\n6cEBAGiPNV/CnpycjL1790atVotyuRwHDx6MCxcurLjmfe97X3R3d0dExB133BH1en1rTgsAQNut\nGZD1ej36+/uXb1er1ZiZmfmf1//hD3+IoaGhzTkdAAA3nTVfwi6VSuv+Yq+++mr88Y9/jK997WsR\ncT0+Z2dnV1zT29sblcq6fvRyxyiXy9HZ2dnuY7TUWxvbemcr6s4Rti4SWxdD0XaOuLGN17xnX19f\nXL58efl2vV6ParX6jutef/31+OUvfxknT56Mnp6eiIg4d+5cjI+Pr7juyJEjcfTo0Q0fmO2lVqu1\n+wi0gJ2Lw9bFYWtWs2ZA7tu3L6ampmJ6ejr6+vri/PnzceLEiRXX/Pvf/45f/OIX8fnPfz5uueWW\n5Y8fOnQohoeHV1zb29sb09PTsbS0tElP4ebX1dUVCwsL7T5GS1UqlajVarbe4Yq6c4Sti8TWxVC0\nnSP+s/WG7rvWBeVyOY4dOxanT5+ORqMRIyMjMTg4GGfPno2IiNHR0RgfH4/5+fl47rnnIiKio6Mj\nvvGNb0S1Wn3X71ZeunQpFhcXN3Tg7ahSqRTq+b7d0tJSoZ57Ubcu2s4Rti4SWxdDUXfeqHW9+D00\nNPSOvxgzOjq6/OcHH3wwHnzwwc09GQAANyXvRAMAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIE\nJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAg\nRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgA\nAFIEJAAAKQISAIAUAQkAQIqABAAgRUACAJAiIAEASBGQAACkCEgAAFIEJAAAKQISAICUUrPZbLby\nAefn52N+fj5a/LBt1dHREY1Go93HaKlSqRS7du2Kq1ev2noHK+rOEbYuElsXQ9F2jri+9cDAwIbu\nW9nks6ypu7s7ZmZmYnFxsdUP3TY9PT1x5cqVdh+jpTo7O2NgYCDm5uZsvYMVdecIWxeJrYuhaDtH\nXN96o7yEDQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBFQAIA\nkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQk\nAAApAhIAgBQBCQBAioAEACBFQAIAkCIgAQBIEZAAAKQISAAAUgQkAAApAhIAgBQBCQBAioAEACBF\nQAIAkCIgAQBIEZAAAKQISAAAUgQkAAAplbUumJiYiDNnzkSz2YyRkZE4fPjwO64ZGxuLixcvRmdn\nZzz00ENx++23b8lhAQBov1W/A9loNGJsbCxOnjwZ3/72t+Oll16KS5curbjmlVdeiampqfjOd74T\nDzzwQDz77LNbemAAANpr1YCcnJyMvXv3Rq1Wi3K5HAcPHowLFy6suObll1+Oe++9NyIi7rjjjpif\nn4/Z2dmtOzEAAG216kvY9Xo9+vv7l29Xq9WYnJxccc3MzExUq9UV19Tr9ejt7Y16vf6OmOzt7Y1K\nZc1XzneUcrkcnZ2d7T5GS721sa13tqLuHGHrIrF1MRRt54gb23jVe5ZKpQ1/4YiIc+fOxfj4+IqP\n7d+/P77whS9ErVa7oa/Nza1er8dvf/vbOHTokK13MDsXh62Lw9bF8fat3/7NwPVYNSD7+vri8uXL\nKx7ovx9gtWsOHToUw8PDy5+7dOlSPPXUUzE7O5s+KNvL7OxsjI+Px/DwsK13MDsXh62Lw9bFcSNb\nr/ozkPv27YupqamYnp6OpaWlOH/+/IogjIgYHh6OP/3pTxER8dprr0V3d3f09vZGxPWXs/ft27f8\nz+DgYOpwAADcfFb9DmS5XI5jx47F6dOno9FoxMjISAwODsbZs2cjImJ0dDTuuuuumJiYiB/+8Iex\na9euePDBB1tycAAA2mPNn54cGhqKoaGhFR8bHR1dcfv48eObeyoAAG5a5e9973vfa9WDNZvN2LVr\nV3zgAx+Irq6uVj0sbWDrYrBzcdi6OGxdHDeydanZbDa36FwAAOxAW/ZLnrwFYnGstfWLL74Yzz//\nfDSbzejq6orjx4/Hbbfd1qbTslHr+Xc64vobEDz++OPxxS9+MQ4cONDiU7IZ1rP1q6++Gr/+9a/j\n2rVrsXv37jh16lQbTsqNWmvrubm5ePLJJ2N2djYajUZ84hOfiPvuu69Np2Wjnn766ZiYmIg9e/bE\nI4888q7XZJtsSwLyrbdAfPjhh6NarcZjjz0Ww8PDK/4W9tvfAvFvf/tbPPvss/H1r399K47DFlrP\n1rVaLU6dOhXd3d0xMTERv/rVr2y9zaxn57eu+81vfhN33nlnm07KjVrP1leuXFl+m9v+/v6Ym5tr\n44nZqPVs/cILL8Ttt98e999/f8zNzcWPfvSjuOeee6JcLrfx5GTdd9998dGPfjSeeuqpd/38Rpps\n1V/js1HeArE41rP1+973vuju7o6I61vX6/V2HJUbsJ6dIyJ+//vfx4EDB2LPnj1tOCWbYT1bv/TS\nS/HBD35w+Z3K7L09rWfrvr6+WFhYiIiIhYWF6OnpEY/b0P79+5f/O/xuNtJkWxKQ7/YWiDMzMyuu\n+V9vgcj2sp6t3+4Pf/jDO/5WPze/9excr9fj5Zdfjo985COtPh6baD1bT01NxZUrV+JnP/tZ/PSn\nP13+XcBsL+vZemRkJP75z3/G97///fjJT34Sn/vc51p9TFpgI022JQF5o2+ByPaR2frVV1+NP/7x\nj/HZz352C0/EVljPzmfOnIn7778/SqVS+Lt529d6tr527Vr84x//iC9/+cvxla98JcbHx+Nf//pX\nC07HZlrP1r/73e/itttui+9+97vxzW9+M5577rnl70hSbFvyM5A3+haIbB/r3fH111+PX/7yl3Hy\n5Mno6elp5RHZBOvZ+e9//3s88cQTERHx5ptvxsWLF6OjoyPuvvvulp6VG7Oerfv7+2P37t3R2dkZ\nnZ2dsX///nj99dfjlltuafVxuQHr2fq1116LT3/60xERyy93v/HGG/He9763pWdla22kybbkO5A3\n+haIbB/r2frf//53/OIXv4jPf/7z/gOzTa1n50cffXT5nwMHDsTx48fF4za03v///utf/xqNRiOu\nXr0ak5OT3qp2G1rP1rfeemv8+c9/jojr75v8xhtvRK1Wa8dx2UIbabIt+z2Qb/1qgLfeAvFTn/rU\nirdAjIh47rnn4uLFi8tvgbhv376tOApbbK2tn3nmmbhw4cLyz9p0dHTEN77xjXYemQ1Yz7/Tb3n6\n6afjrrvu8mt8tqn1bP3888/H//3f/0WpVIqRkZH42Mc+1s4js0FrbT03NxfPPPNMXL58OZrNZhw+\nfDjuueeeNp+arCeeeCL+8pe/xJtvvhm9vb3xmc98JhqNRkRsvMn8InEAAFK25CVsAAB2LgEJAECK\ngAQAIEVAAgCQIiABAEgRkAAApAhIAABS/h/62YH95FMTSgAAAABJRU5ErkJggg==\n", 671 | "text": [ 672 | "" 673 | ] 674 | }, 675 | { 676 | "metadata": {}, 677 | "output_type": "pyout", 678 | "prompt_number": 30, 679 | "text": [ 680 | "" 681 | ] 682 | } 683 | ], 684 | "prompt_number": 30 685 | }, 686 | { 687 | "cell_type": "markdown", 688 | "metadata": {}, 689 | "source": [ 690 | "Now let's (quite literally) add a scatterplot (`geom_point`) to our plot. We'll get into more detail on how this works later." 691 | ] 692 | }, 693 | { 694 | "cell_type": "code", 695 | "collapsed": false, 696 | "input": [ 697 | "p + geom_point()" 698 | ], 699 | "language": "python", 700 | "metadata": {}, 701 | "outputs": [ 702 | { 703 | "metadata": {}, 704 | "output_type": "display_data", 705 | "png": "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\nLDFrp3DanCVm7SQul6tV27Xqt2D+/Pn6xS9+od/85jfq0aOH9u7dqzvvvFO33367otFofDvTxTM9\nPV3V1dV8SkpyXq9XoVBItbW1zDqJOXXOErN2CqfNWWLWTuL1elu1XasOnbemQLpcLkUikVa96Klg\nd3zy49CLMzh1zhKzdgqnzVli1k6S0EPnZWVl37mLtBU9FQAAAA7UqqIZCoX0hz/8QR988IFqamri\n610ul9atW2csHAAAANqvVhXNmTNnKhqN6vzzz1d6enp8fWtPBAUAAIDztKpovvfee/riiy+OuwsH\nAAAA8F1a9TXxkSNHatu2baazAAAAIIm0ao/mkiVLNGnSJI0YMUI5OTnxLwC5XC7ddtttRgMCAACg\nfWpV0Zw3b54OHDigzz//XFVVVaYzAUktEomooqJCmZmZnI4CAEhqrSqay5Yt0/bt29WtWzfTeYCk\ntnPnTl1zzTWqqKhQIBDQvHnzNHnyZLtjAQBgRKvO0ezdu3errwAP4Lvdcsst+vTTT3X48GHt2rVL\nd999tyU3OmiNTz/9VBdeeKGmTJmi//7v/24zuU5FU1OT/uu//ktTpkzRzJkztXPnTrsjAYCjtGqP\n5uWXX65p06bp+uuvV05OToufjR071kgwIBl98zq0klRXV6fa2loFg0GbEv0jx5w5c7Rjxw5J0scf\nf6z09HT95je/sTXXqbr11lu1bNmy+HnlV199tV577TU+OAOARVpVNB999FG5XC7NmzfvuJ/t2rUr\n4aGAZJWXl6ePPvoovty1a1cFAgEbE31t9+7dOnjwYHw5HA7r448/tjFRYnz22Wct7l72+eef69Ch\nQzr99NNtTAUAztGqorl7927DMQBnePDBB+X1elVWVqaOHTvqgQceaBM3PujatasyMzNVV1cXX5eV\nlWVjosT49p7iQCCgTp062ZQGAJynVUUTQGKkp6fr97//vd0xjpOVlaXrrrtOTzzxhBoaGtSjRw/d\nfffddsc6Zffff7+uuOIKHTp0SB06dNANN9ygjIwMu2MBgGNQNIF2KhKJ6K677tJHH32krKws3XXX\nXae0F/Lyyy/XxRdfrNraWmVmZp50T+uaNWv07LPPyuVy6T//8z81fPjw7/3apuTk5Gjt2rX66quv\nFAgElJqaanckAHAUiibQTv3617/W0qVLFQ6HJUkHDhzQmjVrTulQfFpaWquu7blhwwbdeuut+vLL\nLyVJO3bs0LJly9S7d+/v/dqmuFwuDpcDgE1adXkjAG3Phx9+GC+ZkrR//3599dVXlrz2ihUr4iVT\nkg4ePKi1a9da8toAgPaDogm0U+np6cct+/1+S167W7duLfacpqamqkePHpa8NgCg/aBoAu3UHXfc\nob59+6pDhw7q1q2b5syZY9ktLX/5y19q5MiRCgQCCoVCmjBhgs477zxLXhsA0H5wjibQTvXv31+v\nvvqqdu3apZycHHXu3Nmy105LS9Pzzz+vnTt3yuPxqFevXm3iMk0AgLaFogm0Yx06dNCZZ55py2u7\n3W7l5+fb8toAgPaBQ+cAAAAwgqIJAAAAIyiaAAAAMIKiCQAAACMs+zLQ0aNHVVxcrNraWknSkCFD\ndPbZZ6uurk4rVqzQkSNHFAqFNHPmTPl8PqtiAQAAwBDLiqbb7dbEiROVm5urxsZGLVq0SH369NEH\nH3ygvLw8jRo1Shs2bNCGDRs0fvx4q2IBAADAEMsOnQcCAeXm5kr6+hp8nTt3VlVVlbZv366zzjpL\nkjRw4EBt27bNqkgAAAAwyJbraFZWVqq8vFynnXaaamtr47fN8/v98UPrVVVVqqmpafE4v98vj8dZ\nl/5MSUmR1+u1O4aljs2YWSc3p85ZYtZO4bQ5S8zaSVo7Y8t/ExobG7Vs2TKde+65x90u75t3Ftm4\ncaNKSkpa/LywsFBjxoyxJCfsl5mZaXcEWIA5Owezdg5mjWMsLZqRSETLli3TgAED1L9/f0lSRkaG\nqqurFQgEVF1drYyMDElff1mooKCgxeP9fr8qKysVDoetjG2rtLQ0NTY22h3DUh6PR5mZmczaYuXl\n5QqHw+revbslt5N06pwl+2dtNafO2mlzlpi1kxyb9Um3syCLJCkWi2n16tXKzs7WiBEj4usLCgq0\nZcsWjRo1Sps3b1a/fv0kScFgUMFg8LjnqaioUHNzs1WxbefxeBz1fr8pHA476r3bNetYLKbrr79e\nb775pmKxmAYOHKgnn3zSskNfTpuz5Ny/a6fN2qlzlpg1/sGyorl37159+OGHysnJ0YIFCyRJ48aN\n06hRo7R8+XJt2rQpfnkjANZZs2aNXnnllfin8ZKSEi1YsEDXXXedzckAAO2dZUWzZ8+emj9//gl/\nNmvWLKtiAPiWnTt3tjjkE4lEVFZWZmMiAECy4M5AgMNNnjxZXbt2jS936tRJ06dPtzERACBZOOv6\nAwCO069fP917771auHChYrGYLrroIv3kJz+xOxYAIAlQNAGoqKhIRUVFdscAACQZDp0DQILs27dP\nl112mWbMmKE77rhD0WjU7kjfyyuvvKILL7xQF154oVavXm13HADtGHs0ASABGhsbdcUVV+jTTz+V\nJG3atEkul0u33nqrzcn+NZs3b9avfvUrffHFF5Kk0tJS5ebmatiwYTYnA9AesUcTABJg3759OnDg\nQHy5ublZH3zwgY2Jvp+XXnopXjIl6fDhw+zVBPC9UTQBIAGysrLk9/tbrAsEAjal+f769Omj1NTU\n+LLH41FeXp6NiQC0ZxRNAEiArKwsXX311erevbtCoZDOPPNM3XXXXXbH+pf99Kc/1fjx49WpUydl\nZWVp3Lhxmj17tt2xALRTnKMJAAly1VVX6aKLLtJXX32l0047TV6v1+5I/zK3262FCxfq0KFDisVi\n6tatm1wul92xALRT7NEEgASJxWLasGGD1q5dq71799od53tzuVzq1q2bunfvTskEcErYowkACXL9\n9dfH7xu/ZMkSPfTQQzrnnHPsjgUAtmGPJgAkwIEDB/S3v/0tft/4Q4cO6ZFHHrE5FQDYi6IJAAnQ\n3Nx83AXaY7GYTWkAoG2gaAJAApx++un64Q9/KLf76/+sZmVlaebMmTanAgB7cY4mACSA2+3W008/\nrT/84Q/at2+fpk+frjFjxtgdCwBsRdEEgARJTU3VTTfdZHcMAGgzOHQOAAAAIyiaAJBgsVhMDz/8\nsGbOnKnLL79ce/bssTsSANiCQ+cAkGCPPPKIHnnkETU0NEiS9u/fr7Vr18rn89mcDACsxR5NAEiw\nd955J14yJWnPnj0qLS21MREA2IOiCQAJ5vf7WywHAgF16tTJpjQAYB+KJgAkyHvvvafJkydr27Zt\nCgaD8vv9ysnJ0aWXXqru3bvbHQ8ALMc5mgCQAHV1dbrxxhtVVlYWXzdp0iTddddd6tKli43JAMA+\n7NEEgAQ4cOCADh8+3GJdZWUlJROAo1E0ASABunbtqszMzBbrcnJybEoDAG0DRRMAEiAQCOjXv/61\nzjjjDPXo0UOjRo3Svffea3csALAV52gCQIJMmjRJkyZNUjQaldvN53gAcMVisZjdIVqroaFBDQ0N\nakeRT5nb7VY0GrU7hqVcLpdSU1PV1NTErJOYU+csWTfrTz75RI899ph8Pp/mzZtn2yWWnDprp/1N\n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\n/wPupitjAMddIwAAAABJRU5ErkJggg==\n", 706 | "text": [ 707 | "" 708 | ] 709 | }, 710 | { 711 | "metadata": {}, 712 | "output_type": "pyout", 713 | "prompt_number": 31, 714 | "text": [ 715 | "" 716 | ] 717 | } 718 | ], 719 | "prompt_number": 31 720 | }, 721 | { 722 | "cell_type": "code", 723 | "collapsed": false, 724 | "input": [], 725 | "language": "python", 726 | "metadata": {}, 727 | "outputs": [] 728 | } 729 | ], 730 | "metadata": {} 731 | } 732 | ] 733 | } -------------------------------------------------------------------------------- /notebooks/05 - What's next.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# The Future" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "`ggplot` is still rough. We need to:\n", 22 | "\n", 23 | "- improved options for scales and geoms\n", 24 | "- improved legends\n", 25 | "- fix up facets" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "collapsed": false, 31 | "input": [ 32 | "from ggplot import *\n", 33 | "%matplotlib inline" 34 | ], 35 | "language": "python", 36 | "metadata": {}, 37 | "outputs": [ 38 | { 39 | "output_type": "stream", 40 | "stream": "stderr", 41 | "text": [ 42 | "/usr/local/lib/python2.7/site-packages/numpy/oldnumeric/__init__.py:11: ModuleDeprecationWarning: The oldnumeric module will be dropped in Numpy 1.9\n", 43 | " warnings.warn(_msg, ModuleDeprecationWarning)\n" 44 | ] 45 | } 46 | ], 47 | "prompt_number": 2 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "## [mpld3](https://github.com/jakevdp/mpld3)\n", 54 | "Output matplotlib figures as d3 charts." 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "collapsed": false, 60 | "input": [ 61 | "from mpld3 import enable_notebook, save_json\n", 62 | "enable_notebook()\n", 63 | "\n", 64 | "p = ggplot(aes(x='price'), data=diamonds)\n", 65 | "p + geom_histogram()" 66 | ], 67 | "language": "python", 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "output_type": "stream", 72 | "stream": "stderr", 73 | "text": [ 74 | "stat_bin: binwidth defaulted to range/30.\n", 75 | " Use 'binwidth = x' to adjust this.\n" 76 | ] 77 | }, 78 | { 79 | "html": [ 80 | "\n", 81 | "\n", 82 | "\n", 85 | "\n", 86 | "
\n", 87 | "" 123 | ], 124 | "metadata": {}, 125 | "output_type": "display_data", 126 | "png": "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\ng3IKAAAAY1BOAQAAYAzKKQAAAIxBOQUAAIAxKKcAAAAwBuUUAAAAxqCcAgAAwBiUUwAAABiDcgoA\nAABjUE4BAABgDMopAAAAjEE5BQAAgDEopwAAADAG5RQAAADGoJwCAADAGJRTAAAAGINyCgAAAGNQ\nTgEAAGAMyikAAACMQTkFAACAMSinAAAAMAblFAAAAMagnAIAAMAYlFMAAAAYw7Pcg93d3RodHVVV\nVZUOHTokSUomk+rq6tLNmzdVXV2t9vZ2+f1+SVJfX58GBgZkWZZaWlq0efNmSVIsFlN3d7fS6bQi\nkYhaWlokSel0WidPntS1a9fk9/vV3t6u6urqQp4vAAAADLbsldMnn3xSHR0dS7b19/dr06ZN6uzs\n1KZNm9Tf3y9Jun79uoaGhnT48GF1dHTo9OnTymQykqRTp06pra1NnZ2dunHjhkZHRyVJ586dk9/v\nV2dnp5qamvT2228X4hwBAABQJpYtpxs2bFBFRcWSbSMjI9q1a5ckaefOnRoeHs5u3759u9xut8Lh\nsGpqajQ2NibbtjU/P6+GhoZ77rM41tatW3Xx4sX8nh0AAADKyrLL+veSSCQUCAQkSYFAQIlEQpJk\n23a2gEpSKBSSbdtyu90KhUJ3bV/cZ/Ext9stn8+nZDKpyspKxeNxTU9PLzl2IBCQx3P/KadSKaen\ntSyv15vX8YrJ7XaX9fyLbTFfK8kZbiNjzpCx3JAzZ8iZc2TMmUJma1UjW5aVr3nc5ezZs+rt7V2y\nbd++fdq/f/99943FYnmdS21tbV7Hg/nC4XCpp4AHHBlDMZAzlCPH5bSqqkq2bSsYDMq2bVVVVUmS\ngsGgpqamss+Lx+MKhUIKBoOKx+N3bb9zn1AopIWFBc3NzamyslKS1NjYqGg0uuTYgUBAk5OTSqfT\nzs90FcbHx4t6vHzy+Xyam5sr9TTKhsfjUTgcLknOyhUZc4aM5YacOUPOnCNjzixmrCBjO90hGo1q\ncHBQzc3NOn/+vLZs2ZLdfvz4cTU1Ncm2bU1MTKi+vl6WZcnn82lsbEz19fUaHBzUnj17loy1fv16\nXbhwQRs3bsweJxQKLfk4wKLx8fG8L9vfT7GPl08ej6es518q6XSa122FyFhuyJgz5Cw35GzlyJg5\nli2nXV1dunTpkpLJpF588UXt379fzc3NOnbsmM6dO5e9lZQk1dXVadu2bTpy5IhcLpdaW1uzy/6t\n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\n", 127 | "text": [ 128 | "" 129 | ] 130 | }, 131 | { 132 | "metadata": {}, 133 | "output_type": "pyout", 134 | "prompt_number": 3, 135 | "text": [ 136 | "" 137 | ] 138 | } 139 | ], 140 | "prompt_number": 3 141 | }, 142 | { 143 | "cell_type": "code", 144 | "collapsed": false, 145 | "input": [], 146 | "language": "python", 147 | "metadata": {}, 148 | "outputs": [] 149 | } 150 | ], 151 | "metadata": {} 152 | } 153 | ] 154 | } -------------------------------------------------------------------------------- /notebooks/06 - Under the Hood.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## I didn't get this far" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "collapsed": false, 20 | "input": [], 21 | "language": "python", 22 | "metadata": {}, 23 | "outputs": [] 24 | } 25 | ], 26 | "metadata": {} 27 | } 28 | ] 29 | } --------------------------------------------------------------------------------