##// END OF EJS Templates
add other text example
Matthias BUSSONNIER -
Show More
This diff has been collapsed as it changes many lines, (511 lines changed) Show them Hide them
@@ -0,0 +1,511 b''
1 # A brief tour of the IPython notebook
2
3 This document will give you a brief tour of the capabilities of the IPython notebook.
4 You can view its contents by scrolling around, or execute each cell by typing `Shift-Enter`.
5 After you conclude this brief high-level tour, you should read the accompanying notebook
6 titled `01_notebook_introduction`, which takes a more step-by-step approach to the features of the
7 system.
8
9 The rest of the notebooks in this directory illustrate various other aspects and
10 capabilities of the IPython notebook; some of them may require additional libraries to be executed.
11
12 **NOTE:** This notebook *must* be run from its own directory, so you must ``cd``
13 to this directory and then start the notebook, but do *not* use the ``--notebook-dir``
14 option to run it from another location.
15
16 The first thing you need to know is that you are still controlling the same old IPython you're used to,
17 so things like shell aliases and magic commands still work:
18
19 <div class="highlight"><pre><span class="n">pwd</span>
20 </pre></div>
21
22
23 <pre>
24 u'/Users/minrk/dev/ip/mine/docs/examples/notebooks'
25 </pre>
26
27
28 <div class="highlight"><pre><span class="n">ls</span>
29 </pre></div>
30
31
32 00_notebook_tour.ipynb callbacks.ipynb python-logo.svg
33 01_notebook_introduction.ipynb cython_extension.ipynb rmagic_extension.ipynb
34 Animations_and_Progress.ipynb display_protocol.ipynb sympy.ipynb
35 Capturing Output.ipynb formatting.ipynb sympy_quantum_computing.ipynb
36 Script Magics.ipynb octavemagic_extension.ipynb trapezoid_rule.ipynb
37 animation.m4v progbar.ipynb
38
39
40 <div class="highlight"><pre><span class="n">message</span> <span class="o">=</span> <span class="s">&#39;The IPython notebook is great!&#39;</span>
41 <span class="c"># note: the echo command does not run on Windows, it&#39;s a unix command.</span>
42 <span class="o">!</span><span class="nb">echo</span> <span class="nv">$message</span>
43 </pre></div>
44
45
46 The IPython notebook is great!
47
48
49 ## Plots with matplotlib
50
51 IPython adds an 'inline' matplotlib backend,
52 which embeds any matplotlib figures into the notebook.
53
54 <div class="highlight"><pre><span class="o">%</span><span class="k">pylab</span> <span class="n">inline</span>
55 </pre></div>
56
57
58
59 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
60 For more information, type 'help(pylab)'.
61
62
63 <div class="highlight"><pre><span class="n">x</span> <span class="o">=</span> <span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="o">*</span><span class="n">pi</span><span class="p">,</span> <span class="mi">500</span><span class="p">)</span>
64 <span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span>
65 <span class="n">title</span><span class="p">(</span><span class="s">&#39;A simple chirp&#39;</span><span class="p">);</span>
66 </pre></div>
67
68
69
70 ![](tests/ipynbref/00_notebook_tour_orig_files/00_notebook_tour_orig_fig_00.png)
71
72
73 You can paste blocks of input with prompt markers, such as those from
74 [the official Python tutorial](http://docs.python.org/tutorial/interpreter.html#interactive-mode)
75
76 <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">the_world_is_flat</span> <span class="o">=</span> <span class="mi">1</span>
77 <span class="o">&gt;&gt;&gt;</span> <span class="k">if</span> <span class="n">the_world_is_flat</span><span class="p">:</span>
78 <span class="o">...</span> <span class="k">print</span> <span class="s">&quot;Be careful not to fall off!&quot;</span>
79 </pre></div>
80
81
82 Be careful not to fall off!
83
84
85 Errors are shown in informative ways:
86
87 <div class="highlight"><pre><span class="o">%</span><span class="k">run</span> <span class="n">non_existent_file</span>
88 </pre></div>
89
90
91 ERROR: File `u'non_existent_file.py'` not found.
92
93 <div class="highlight"><pre><span class="n">x</span> <span class="o">=</span> <span class="mi">1</span>
94 <span class="n">y</span> <span class="o">=</span> <span class="mi">4</span>
95 <span class="n">z</span> <span class="o">=</span> <span class="n">y</span><span class="o">/</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">x</span><span class="p">)</span>
96 </pre></div>
97
98
99 ---------------------------------------------------------------------------
100 ZeroDivisionError Traceback (most recent call last)
101 <ipython-input-8-dc39888fd1d2> in <module>()
102 1 x = 1
103 2 y = 4
104 ----> 3 z = y/(1-x)
105
106 ZeroDivisionError: integer division or modulo by zero
107
108
109 When IPython needs to display additional information (such as providing details on an object via `x?`
110 it will automatically invoke a pager at the bottom of the screen:
111
112 <div class="highlight"><pre><span class="n">magic</span>
113 </pre></div>
114
115
116
117 ## Non-blocking output of kernel
118
119 If you execute the next cell, you will see the output arriving as it is generated, not all at the end.
120
121 <div class="highlight"><pre><span class="kn">import</span> <span class="nn">time</span><span class="o">,</span> <span class="nn">sys</span>
122 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">):</span>
123 <span class="k">print</span> <span class="n">i</span><span class="p">,</span>
124 <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
125 </pre></div>
126
127
128 0
129 1
130 2
131 3
132 4
133 5
134 6
135 7
136
137
138 ## Clean crash and restart
139
140 We call the low-level system libc.time routine with the wrong argument via
141 ctypes to segfault the Python interpreter:
142
143 <div class="highlight"><pre><span class="kn">import</span> <span class="nn">sys</span>
144 <span class="kn">from</span> <span class="nn">ctypes</span> <span class="kn">import</span> <span class="n">CDLL</span>
145 <span class="c"># This will crash a Linux or Mac system; equivalent calls can be made on Windows</span>
146 <span class="n">dll</span> <span class="o">=</span> <span class="s">&#39;dylib&#39;</span> <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s">&#39;darwin&#39;</span> <span class="k">else</span> <span class="s">&#39;.so.6&#39;</span>
147 <span class="n">libc</span> <span class="o">=</span> <span class="n">CDLL</span><span class="p">(</span><span class="s">&quot;libc.</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">dll</span><span class="p">)</span>
148 <span class="n">libc</span><span class="o">.</span><span class="n">time</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="c"># BOOM!!</span>
149 </pre></div>
150
151
152
153 ## Markdown cells can contain formatted text and code
154
155 You can *italicize*, **boldface**
156
157 * build
158 * lists
159
160 and embed code meant for illustration instead of execution in Python:
161
162 def f(x):
163 """a docstring"""
164 return x**2
165
166 or other languages:
167
168 if (i=0; i<n; i++) {
169 printf("hello %d\n", i);
170 x += 4;
171 }
172
173 Courtesy of MathJax, you can include mathematical expressions both inline:
174 $e^{i\pi} + 1 = 0$ and displayed:
175
176 $$e^x=\sum_{i=0}^\infty \frac{1}{i!}x^i$$
177
178 ## Rich displays: include anyting a browser can show
179
180 Note that we have an actual protocol for this, see the `display_protocol` notebook for further details.
181
182 ### Images
183
184 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">Image</span>
185 <span class="n">Image</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s">&#39;../../source/_static/logo.png&#39;</span><span class="p">)</span>
186 </pre></div>
187
188
189 <pre>
190 <IPython.core.display.Image at 0x10faeafd0>
191 </pre>
192
193
194 An image can also be displayed from raw data or a url
195
196 <div class="highlight"><pre><span class="n">Image</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">&#39;http://python.org/images/python-logo.gif&#39;</span><span class="p">)</span>
197 </pre></div>
198
199
200 <pre>
201 <IPython.core.display.Image at 0x1060e7410>
202 </pre>
203
204
205 SVG images are also supported out of the box (since modern browsers do a good job of rendering them):
206
207 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">SVG</span>
208 <span class="n">SVG</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s">&#39;python-logo.svg&#39;</span><span class="p">)</span>
209 </pre></div>
210
211
212 <pre>
213 <IPython.core.display.SVG at 0x10fb998d0>
214 </pre>
215
216
217 #### Embedded vs Non-embedded Images
218
219 As of IPython 0.13, images are embedded by default for compatibility with QtConsole, and the ability to still be displayed offline.
220
221 Let's look at the differences:
222
223 <div class="highlight"><pre><span class="c"># by default Image data are embedded</span>
224 <span class="n">Embed</span> <span class="o">=</span> <span class="n">Image</span><span class="p">(</span> <span class="s">&#39;http://scienceview.berkeley.edu/view/images/newview.jpg&#39;</span><span class="p">)</span>
225
226 <span class="c"># if kwarg `url` is given, the embedding is assumed to be false</span>
227 <span class="n">SoftLinked</span> <span class="o">=</span> <span class="n">Image</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">&#39;http://scienceview.berkeley.edu/view/images/newview.jpg&#39;</span><span class="p">)</span>
228
229 <span class="c"># In each case, embed can be specified explicitly with the `embed` kwarg</span>
230 <span class="c"># ForceEmbed = Image(url=&#39;http://scienceview.berkeley.edu/view/images/newview.jpg&#39;, embed=True)</span>
231 </pre></div>
232
233
234
235 Today's image from a webcam at Berkeley, (at the time I created this notebook). This should also work in the Qtconsole.
236 Drawback is that the saved notebook will be larger, but the image will still be present offline.
237
238 <div class="highlight"><pre><span class="n">Embed</span>
239 </pre></div>
240
241
242 <pre>
243 <IPython.core.display.Image at 0x10fb99b50>
244 </pre>
245
246
247 Today's image from same webcam at Berkeley, (refreshed every minutes, if you reload the notebook), visible only with an active internet connexion, that should be different from the previous one. This will not work on Qtconsole.
248 Notebook saved with this kind of image will be lighter and always reflect the current version of the source, but the image won't display offline.
249
250 <div class="highlight"><pre><span class="n">SoftLinked</span>
251 </pre></div>
252
253
254 <pre>
255 <IPython.core.display.Image at 0x10fb99b10>
256 </pre>
257
258
259 Of course, if you re-run the all notebook, the two images will be the same again.
260
261 ### Video
262
263 And more exotic objects can also be displayed, as long as their representation supports
264 the IPython display protocol.
265
266 For example, videos hosted externally on YouTube are easy to load (and writing a similar wrapper for other
267 hosted content is trivial):
268
269 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">YouTubeVideo</span>
270 <span class="c"># a talk about IPython at Sage Days at U. Washington, Seattle.</span>
271 <span class="c"># Video credit: William Stein.</span>
272 <span class="n">YouTubeVideo</span><span class="p">(</span><span class="s">&#39;1j_HxD4iLn8&#39;</span><span class="p">)</span>
273 </pre></div>
274
275
276 <pre>
277 <IPython.lib.display.YouTubeVideo at 0x10fba2190>
278 </pre>
279
280
281 Using the nascent video capabilities of modern browsers, you may also be able to display local
282 videos. At the moment this doesn't work very well in all browsers, so it may or may not work for you;
283 we will continue testing this and looking for ways to make it more robust.
284
285 The following cell loads a local file called `animation.m4v`, encodes the raw video as base64 for http
286 transport, and uses the HTML5 video tag to load it. On Chrome 15 it works correctly, displaying a control
287 bar at the bottom with a play/pause button and a location slider.
288
289 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">HTML</span>
290 <span class="n">video</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&quot;animation.m4v&quot;</span><span class="p">,</span> <span class="s">&quot;rb&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
291 <span class="n">video_encoded</span> <span class="o">=</span> <span class="n">video</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&quot;base64&quot;</span><span class="p">)</span>
292 <span class="n">video_tag</span> <span class="o">=</span> <span class="s">&#39;&lt;video controls alt=&quot;test&quot; src=&quot;data:video/x-m4v;base64,{0}&quot;&gt;&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">video_encoded</span><span class="p">)</span>
293 <span class="n">HTML</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">video_tag</span><span class="p">)</span>
294 </pre></div>
295
296
297 <pre>
298 <IPython.core.display.HTML at 0x10fba28d0>
299 </pre>
300
301
302 ## Local Files
303
304 The above examples embed images and video from the notebook filesystem in the output
305 areas of code cells. It is also possible to request these files directly in markdown cells
306 if they reside in the notebook directory via relative urls prefixed with `files/`:
307
308 files/[subdirectory/]<filename>
309
310
311 For example, in the example notebook folder, we have the Python logo, addressed as:
312
313 <img src="files/python-logo.svg" />
314
315 <img src="python-logo.svg" />
316
317 and a video with the HTML5 video tag:
318
319 <video controls src="files/animation.m4v" />
320
321 <video controls src="animation.m4v" />
322
323 These do not embed the data into the notebook file,
324 and require that the files exist when you are viewing the notebook.
325
326 ### Security of local files
327
328 Note that this means that the IPython notebook server also acts as a generic file server
329 for files inside the same tree as your notebooks. Access is not granted outside the
330 notebook folder so you have strict control over what files are visible, but for this
331 reason it is highly recommended that you do not run the notebook server with a notebook
332 directory at a high level in your filesystem (e.g. your home directory).
333
334 When you run the notebook in a password-protected manner, local file access is restricted
335 to authenticated users unless read-only views are active.
336
337 ## Linking to files and directories for viewing in the browser
338
339 It is also possible to link directly to files or directories so they can be opened in the browser. This is especially convenient if you're interacting with a tool within IPython that generates HTML pages, and you'd like to easily be able to open those in a new browser window. Alternatively, if your IPython notebook server is on a remote system, creating links provides an easy way to download any files that get generated.
340
341 As we saw above, there are a bunch of `.ipynb` files in our current directory.
342
343 <div class="highlight"><pre><span class="n">ls</span>
344 </pre></div>
345
346
347 00_notebook_tour.ipynb formatting.ipynb
348 01_notebook_introduction.ipynb octavemagic_extension.ipynb
349 Animations_and_Progress.ipynb publish_data.ipynb
350 Capturing Output.ipynb python-logo.svg
351 Script Magics.ipynb rmagic_extension.ipynb
352 animation.m4v sympy.ipynb
353 cython_extension.ipynb sympy_quantum_computing.ipynb
354 display_protocol.ipynb trapezoid_rule.ipynb
355
356
357 If we want to create a link to one of them, we can call use the `FileLink` object.
358
359 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">FileLink</span>
360 <span class="n">FileLink</span><span class="p">(</span><span class="s">&#39;00_notebook_tour.ipynb&#39;</span><span class="p">)</span>
361 </pre></div>
362
363
364 <pre>
365 <IPython.lib.display.FileLink at 0x10f7ea3d0>
366 </pre>
367
368
369 Alternatively, if we want to link to all of them, we can use the `FileLinks` object, passing `'.'` to indicate that we want links generated for the current working directory. Note that if there were other directories under the current directory, `FileLinks` would work in a recursive manner creating links to files in all sub-directories as well.
370
371 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">FileLinks</span>
372 <span class="n">FileLinks</span><span class="p">(</span><span class="s">&#39;.&#39;</span><span class="p">)</span>
373 </pre></div>
374
375
376 <pre>
377 <IPython.lib.display.FileLinks at 0x10f7eaad0>
378 </pre>
379
380
381 ### External sites
382
383 You can even embed an entire page from another site in an iframe; for example this is today's Wikipedia
384 page for mobile users:
385
386 <div class="highlight"><pre><span class="n">HTML</span><span class="p">(</span><span class="s">&#39;&lt;iframe src=http://en.mobile.wikipedia.org/?useformat=mobile width=700 height=350&gt;&lt;/iframe&gt;&#39;</span><span class="p">)</span>
387 </pre></div>
388
389
390 <pre>
391 <IPython.core.display.HTML at 0x1094900d0>
392 </pre>
393
394
395 ### Mathematics
396
397 And we also support the display of mathematical expressions typeset in LaTeX, which is rendered
398 in the browser thanks to the [MathJax library](http://mathjax.org).
399
400 Note that this is *different* from the above examples. Above we were typing mathematical expressions
401 in Markdown cells (along with normal text) and letting the browser render them; now we are displaying
402 the output of a Python computation as a LaTeX expression wrapped by the `Math()` object so the browser
403 renders it. The `Math` object will add the needed LaTeX delimiters (`$$`) if they are not provided:
404
405 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">Math</span>
406 <span class="n">Math</span><span class="p">(</span><span class="s">r&#39;F(k) = \int_{-\infty}^{\infty} f(x) e^{2\pi i k} dx&#39;</span><span class="p">)</span>
407 </pre></div>
408
409
410 <pre>
411 <IPython.core.display.Math at 0x10fba26d0>
412 </pre>
413
414
415 With the `Latex` class, you have to include the delimiters yourself. This allows you to use other LaTeX modes such as `eqnarray`:
416
417 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">Latex</span>
418 <span class="n">Latex</span><span class="p">(</span><span class="s">r&quot;&quot;&quot;\begin{eqnarray}</span>
419 <span class="s">\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\</span>
420 <span class="s">\nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\</span>
421 <span class="s">\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\</span>
422 <span class="s">\nabla \cdot \vec{\mathbf{B}} &amp; = 0 </span>
423 <span class="s">\end{eqnarray}&quot;&quot;&quot;</span><span class="p">)</span>
424 </pre></div>
425
426
427 <pre>
428 <IPython.core.display.Latex at 0x10fba2c10>
429 </pre>
430
431
432 Or you can enter latex directly with the `%%latex` cell magic:
433
434 <div class="highlight"><pre><span class="o">%%</span><span class="k">latex</span>
435 \<span class="n">begin</span><span class="p">{</span><span class="n">aligned</span><span class="p">}</span>
436 \<span class="n">nabla</span> \<span class="n">times</span> \<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="n">B</span><span class="p">}}</span> <span class="o">-</span>\<span class="p">,</span> \<span class="n">frac1c</span>\<span class="p">,</span> \<span class="n">frac</span><span class="p">{</span>\<span class="n">partial</span>\<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="n">E</span><span class="p">}}}{</span>\<span class="n">partial</span> <span class="n">t</span><span class="p">}</span> <span class="o">&amp;</span> <span class="o">=</span> \<span class="n">frac</span><span class="p">{</span><span class="mi">4</span>\<span class="n">pi</span><span class="p">}{</span><span class="n">c</span><span class="p">}</span>\<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="n">j</span><span class="p">}}</span> \\
437 \<span class="n">nabla</span> \<span class="n">cdot</span> \<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="n">E</span><span class="p">}}</span> <span class="o">&amp;</span> <span class="o">=</span> <span class="mi">4</span> \<span class="n">pi</span> \<span class="n">rho</span> \\
438 \<span class="n">nabla</span> \<span class="n">times</span> \<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="n">E</span><span class="p">}}</span>\<span class="p">,</span> <span class="o">+</span>\<span class="p">,</span> \<span class="n">frac1c</span>\<span class="p">,</span> \<span class="n">frac</span><span class="p">{</span>\<span class="n">partial</span>\<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="n">B</span><span class="p">}}}{</span>\<span class="n">partial</span> <span class="n">t</span><span class="p">}</span> <span class="o">&amp;</span> <span class="o">=</span> \<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="mi">0</span><span class="p">}}</span> \\
439 \<span class="n">nabla</span> \<span class="n">cdot</span> \<span class="n">vec</span><span class="p">{</span>\<span class="n">mathbf</span><span class="p">{</span><span class="n">B</span><span class="p">}}</span> <span class="o">&amp;</span> <span class="o">=</span> <span class="mi">0</span>
440 \<span class="n">end</span><span class="p">{</span><span class="n">aligned</span><span class="p">}</span>
441 </pre></div>
442
443
444 <IPython.core.display.Latex at 0x10a617c90>
445
446 There is also a `%%javascript` cell magic for running javascript directly,
447 and `%%svg` for manually entering SVG content.
448
449 # Loading external codes
450 * Drag and drop a ``.py`` in the dashboard
451 * Use ``%load`` with any local or remote url: [the Matplotlib Gallery!](http://matplotlib.sourceforge.net/gallery.html)
452
453 In this notebook we've kept the output saved so you can see the result, but you should run the next
454 cell yourself (with an active internet connection).
455
456 Let's make sure we have pylab again, in case we have restarted the kernel due to the crash demo above
457
458 <div class="highlight"><pre><span class="o">%</span><span class="k">pylab</span> <span class="n">inline</span>
459 </pre></div>
460
461
462
463 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
464 For more information, type 'help(pylab)'.
465
466
467 <div class="highlight"><pre><span class="o">%</span><span class="k">load</span> <span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">matplotlib</span><span class="o">.</span><span class="n">sourceforge</span><span class="o">.</span><span class="n">net</span><span class="o">/</span><span class="n">mpl_examples</span><span class="o">/</span><span class="n">pylab_examples</span><span class="o">/</span><span class="n">integral_demo</span><span class="o">.</span><span class="n">py</span>
468 </pre></div>
469
470
471
472 <div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
473
474 <span class="c"># implement the example graphs/integral from pyx</span>
475 <span class="kn">from</span> <span class="nn">pylab</span> <span class="kn">import</span> <span class="o">*</span>
476 <span class="kn">from</span> <span class="nn">matplotlib.patches</span> <span class="kn">import</span> <span class="n">Polygon</span>
477
478 <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
479 <span class="k">return</span> <span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">3</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">5</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">7</span><span class="p">)</span><span class="o">+</span><span class="mi">85</span>
480
481 <span class="n">ax</span> <span class="o">=</span> <span class="n">subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
482
483 <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">9</span> <span class="c"># integral area</span>
484 <span class="n">x</span> <span class="o">=</span> <span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mf">0.01</span><span class="p">)</span>
485 <span class="n">y</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
486 <span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">linewidth</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
487
488 <span class="c"># make the shaded region</span>
489 <span class="n">ix</span> <span class="o">=</span> <span class="n">arange</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="mf">0.01</span><span class="p">)</span>
490 <span class="n">iy</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="n">ix</span><span class="p">)</span>
491 <span class="n">verts</span> <span class="o">=</span> <span class="p">[(</span><span class="n">a</span><span class="p">,</span><span class="mi">0</span><span class="p">)]</span> <span class="o">+</span> <span class="nb">zip</span><span class="p">(</span><span class="n">ix</span><span class="p">,</span><span class="n">iy</span><span class="p">)</span> <span class="o">+</span> <span class="p">[(</span><span class="n">b</span><span class="p">,</span><span class="mi">0</span><span class="p">)]</span>
492 <span class="n">poly</span> <span class="o">=</span> <span class="n">Polygon</span><span class="p">(</span><span class="n">verts</span><span class="p">,</span> <span class="n">facecolor</span><span class="o">=</span><span class="s">&#39;0.8&#39;</span><span class="p">,</span> <span class="n">edgecolor</span><span class="o">=</span><span class="s">&#39;k&#39;</span><span class="p">)</span>
493 <span class="n">ax</span><span class="o">.</span><span class="n">add_patch</span><span class="p">(</span><span class="n">poly</span><span class="p">)</span>
494
495 <span class="n">text</span><span class="p">(</span><span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">),</span> <span class="mi">30</span><span class="p">,</span>
496 <span class="s">r&quot;$\int_a^b f(x)\mathrm{d}x$&quot;</span><span class="p">,</span> <span class="n">horizontalalignment</span><span class="o">=</span><span class="s">&#39;center&#39;</span><span class="p">,</span>
497 <span class="n">fontsize</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
498
499 <span class="n">axis</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">180</span><span class="p">])</span>
500 <span class="n">figtext</span><span class="p">(</span><span class="mf">0.9</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">,</span> <span class="s">&#39;x&#39;</span><span class="p">)</span>
501 <span class="n">figtext</span><span class="p">(</span><span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.9</span><span class="p">,</span> <span class="s">&#39;y&#39;</span><span class="p">)</span>
502 <span class="n">ax</span><span class="o">.</span><span class="n">set_xticks</span><span class="p">((</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">))</span>
503 <span class="n">ax</span><span class="o">.</span><span class="n">set_xticklabels</span><span class="p">((</span><span class="s">&#39;a&#39;</span><span class="p">,</span><span class="s">&#39;b&#39;</span><span class="p">))</span>
504 <span class="n">ax</span><span class="o">.</span><span class="n">set_yticks</span><span class="p">([])</span>
505 <span class="n">show</span><span class="p">()</span>
506 </pre></div>
507
508
509
510 ![](tests/ipynbref/00_notebook_tour_orig_files/00_notebook_tour_orig_fig_01.png)
511
This diff has been collapsed as it changes many lines, (828 lines changed) Show them Hide them
@@ -0,0 +1,828 b''
1 %% This file was auto-generated by IPython.
2 %% Conversion from the original notebook file:
3 %% tests/ipynbref/00_notebook_tour.orig.ipynb
4 %%
5 \documentclass[11pt,english]{article}
6
7 %% This is the automatic preamble used by IPython. Note that it does *not*
8 %% include a documentclass declaration, that is added at runtime to the overall
9 %% document.
10
11 \usepackage{amsmath}
12 \usepackage{amssymb}
13 \usepackage{graphicx}
14 \usepackage{ucs}
15 \usepackage[utf8x]{inputenc}
16
17 % needed for markdown enumerations to work
18 \usepackage{enumerate}
19
20 % Slightly bigger margins than the latex defaults
21 \usepackage{geometry}
22 \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm}
23
24 % Define a few colors for use in code, links and cell shading
25 \usepackage{color}
26 \definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
27 \definecolor{darkorange}{rgb}{.71,0.21,0.01}
28 \definecolor{darkgreen}{rgb}{.12,.54,.11}
29 \definecolor{myteal}{rgb}{.26, .44, .56}
30 \definecolor{gray}{gray}{0.45}
31 \definecolor{lightgray}{gray}{.95}
32 \definecolor{mediumgray}{gray}{.8}
33 \definecolor{inputbackground}{rgb}{.95, .95, .85}
34 \definecolor{outputbackground}{rgb}{.95, .95, .95}
35 \definecolor{traceback}{rgb}{1, .95, .95}
36
37 % Framed environments for code cells (inputs, outputs, errors, ...). The
38 % various uses of \unskip (or not) at the end were fine-tuned by hand, so don't
39 % randomly change them unless you're sure of the effect it will have.
40 \usepackage{framed}
41
42 % remove extraneous vertical space in boxes
43 \setlength\fboxsep{0pt}
44
45 % codecell is the whole input+output set of blocks that a Code cell can
46 % generate.
47
48 % TODO: unfortunately, it seems that using a framed codecell environment breaks
49 % the ability of the frames inside of it to be broken across pages. This
50 % causes at least the problem of having lots of empty space at the bottom of
51 % pages as new frames are moved to the next page, and if a single frame is too
52 % long to fit on a page, will completely stop latex from compiling the
53 % document. So unless we figure out a solution to this, we'll have to instead
54 % leave the codecell env. as empty. I'm keeping the original codecell
55 % definition here (a thin vertical bar) for reference, in case we find a
56 % solution to the page break issue.
57
58 %% \newenvironment{codecell}{%
59 %% \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}%
60 %% \MakeFramed{\vspace{-0.5em}}}
61 %% {\unskip\endMakeFramed}
62
63 % For now, make this a no-op...
64 \newenvironment{codecell}{}
65
66 \newenvironment{codeinput}{%
67 \def\FrameCommand{\colorbox{inputbackground}}%
68 \MakeFramed{\advance\hsize-\width \FrameRestore}}
69 {\unskip\endMakeFramed}
70
71 \newenvironment{codeoutput}{%
72 \def\FrameCommand{\colorbox{outputbackground}}%
73 \vspace{-1.4em}
74 \MakeFramed{\advance\hsize-\width \FrameRestore}}
75 {\unskip\medskip\endMakeFramed}
76
77 \newenvironment{traceback}{%
78 \def\FrameCommand{\colorbox{traceback}}%
79 \MakeFramed{\advance\hsize-\width \FrameRestore}}
80 {\endMakeFramed}
81
82 % Use and configure listings package for nicely formatted code
83 \usepackage{listingsutf8}
84 \lstset{
85 language=python,
86 inputencoding=utf8x,
87 extendedchars=\true,
88 aboveskip=\smallskipamount,
89 belowskip=\smallskipamount,
90 xleftmargin=2mm,
91 breaklines=true,
92 basicstyle=\small \ttfamily,
93 showstringspaces=false,
94 keywordstyle=\color{blue}\bfseries,
95 commentstyle=\color{myteal},
96 stringstyle=\color{darkgreen},
97 identifierstyle=\color{darkorange},
98 columns=fullflexible, % tighter character kerning, like verb
99 }
100
101 % The hyperref package gives us a pdf with properly built
102 % internal navigation ('pdf bookmarks' for the table of contents,
103 % internal cross-reference links, web links for URLs, etc.)
104 \usepackage{hyperref}
105 \hypersetup{
106 breaklinks=true, % so long urls are correctly broken across lines
107 colorlinks=true,
108 urlcolor=blue,
109 linkcolor=darkorange,
110 citecolor=darkgreen,
111 }
112
113 % hardcode size of all verbatim environments to be a bit smaller
114 \makeatletter
115 \g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt
116 \makeatother
117
118 % Prevent overflowing lines due to urls and other hard-to-break entities.
119 \sloppy
120
121 \begin{document}
122
123 \section{A brief tour of the IPython notebook}
124
125 This document will give you a brief tour of the capabilities of the
126 IPython notebook.\\You can view its contents by scrolling around, or
127 execute each cell by typing \texttt{Shift-Enter}. After you conclude
128 this brief high-level tour, you should read the accompanying notebook
129 titled \texttt{01\_notebook\_introduction}, which takes a more
130 step-by-step approach to the features of the system.
131
132 The rest of the notebooks in this directory illustrate various other
133 aspects and capabilities of the IPython notebook; some of them may
134 require additional libraries to be executed.
135
136 \textbf{NOTE:} This notebook \emph{must} be run from its own directory,
137 so you must \texttt{cd} to this directory and then start the notebook,
138 but do \emph{not} use the \texttt{-{}-notebook-dir} option to run it
139 from another location.
140
141 The first thing you need to know is that you are still controlling the
142 same old IPython you're used to, so things like shell aliases and magic
143 commands still work:
144
145 \begin{codecell}
146 \begin{codeinput}
147 \begin{lstlisting}
148 pwd
149 \end{lstlisting}
150 \end{codeinput}
151 \begin{codeoutput}
152 \begin{verbatim}
153 u'/Users/minrk/dev/ip/mine/docs/examples/notebooks'
154 \end{verbatim}
155 \end{codeoutput}
156 \end{codecell}
157 \begin{codecell}
158 \begin{codeinput}
159 \begin{lstlisting}
160 ls
161 \end{lstlisting}
162 \end{codeinput}
163 \begin{codeoutput}
164 \begin{verbatim}
165 00_notebook_tour.ipynb callbacks.ipynb python-logo.svg
166 01_notebook_introduction.ipynb cython_extension.ipynb rmagic_extension.ipynb
167 Animations_and_Progress.ipynb display_protocol.ipynb sympy.ipynb
168 Capturing Output.ipynb formatting.ipynb sympy_quantum_computing.ipynb
169 Script Magics.ipynb octavemagic_extension.ipynb trapezoid_rule.ipynb
170 animation.m4v progbar.ipynb
171 \end{verbatim}
172 \end{codeoutput}
173 \end{codecell}
174 \begin{codecell}
175 \begin{codeinput}
176 \begin{lstlisting}
177 message = 'The IPython notebook is great!'
178 # note: the echo command does not run on Windows, it's a unix command.
179 !echo $message
180 \end{lstlisting}
181 \end{codeinput}
182 \begin{codeoutput}
183 \begin{verbatim}
184 The IPython notebook is great!
185 \end{verbatim}
186 \end{codeoutput}
187 \end{codecell}
188 \subsection{Plots with matplotlib}
189 IPython adds an `inline' matplotlib backend, which embeds any matplotlib
190 figures into the notebook.
191
192 \begin{codecell}
193 \begin{codeinput}
194 \begin{lstlisting}
195 %pylab inline
196 \end{lstlisting}
197 \end{codeinput}
198 \begin{codeoutput}
199 \begin{verbatim}
200 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
201 For more information, type 'help(pylab)'.
202 \end{verbatim}
203 \end{codeoutput}
204 \end{codecell}
205 \begin{codecell}
206 \begin{codeinput}
207 \begin{lstlisting}
208 x = linspace(0, 3*pi, 500)
209 plot(x, sin(x**2))
210 title('A simple chirp');
211 \end{lstlisting}
212 \end{codeinput}
213 \begin{codeoutput}
214 \begin{center}
215 \includegraphics[width=0.7\textwidth]{00_notebook_tour_orig_files/00_notebook_tour_orig_fig_00.png}
216 \par
217 \end{center}
218 \end{codeoutput}
219 \end{codecell}
220 You can paste blocks of input with prompt markers, such as those from
221 \href{http://docs.python.org/tutorial/interpreter.html\#interactive-mode}{the
222 official Python tutorial}
223
224 \begin{codecell}
225 \begin{codeinput}
226 \begin{lstlisting}
227 >>> the_world_is_flat = 1
228 >>> if the_world_is_flat:
229 ... print "Be careful not to fall off!"
230 \end{lstlisting}
231 \end{codeinput}
232 \begin{codeoutput}
233 \begin{verbatim}
234 Be careful not to fall off!
235 \end{verbatim}
236 \end{codeoutput}
237 \end{codecell}
238 Errors are shown in informative ways:
239
240 \begin{codecell}
241 \begin{codeinput}
242 \begin{lstlisting}
243 %run non_existent_file
244 \end{lstlisting}
245 \end{codeinput}
246 \begin{codeoutput}
247 \begin{verbatim}
248 ERROR: File `u'non_existent_file.py'` not found.
249 \end{verbatim}
250 \end{codeoutput}
251 \end{codecell}
252 \begin{codecell}
253 \begin{codeinput}
254 \begin{lstlisting}
255 x = 1
256 y = 4
257 z = y/(1-x)
258 \end{lstlisting}
259 \end{codeinput}
260 \begin{codeoutput}
261 \begin{traceback}
262 \begin{verbatim}
263 ---------------------------------------------------------------------------
264 ZeroDivisionError Traceback (most recent call last)
265 <ipython-input-8-dc39888fd1d2> in <module>()
266 1 x = 1
267 2 y = 4
268 ----> 3 z = y/(1-x)
269
270 ZeroDivisionError: integer division or modulo by zero
271 \end{verbatim}
272 \end{traceback}
273 \end{codeoutput}
274 \end{codecell}
275 When IPython needs to display additional information (such as providing
276 details on an object via \texttt{x?} it will automatically invoke a
277 pager at the bottom of the screen:
278
279 \begin{codecell}
280 \begin{codeinput}
281 \begin{lstlisting}
282 magic
283 \end{lstlisting}
284 \end{codeinput}
285 \end{codecell}
286 \subsection{Non-blocking output of kernel}
287
288 If you execute the next cell, you will see the output arriving as it is
289 generated, not all at the end.
290
291 \begin{codecell}
292 \begin{codeinput}
293 \begin{lstlisting}
294 import time, sys
295 for i in range(8):
296 print i,
297 time.sleep(0.5)
298 \end{lstlisting}
299 \end{codeinput}
300 \begin{codeoutput}
301 \begin{verbatim}
302 0
303 \end{verbatim}
304 \begin{verbatim}
305 1
306 \end{verbatim}
307 \begin{verbatim}
308 2
309 \end{verbatim}
310 \begin{verbatim}
311 3
312 \end{verbatim}
313 \begin{verbatim}
314 4
315 \end{verbatim}
316 \begin{verbatim}
317 5
318 \end{verbatim}
319 \begin{verbatim}
320 6
321 \end{verbatim}
322 \begin{verbatim}
323 7
324 \end{verbatim}
325 \end{codeoutput}
326 \end{codecell}
327 \subsection{Clean crash and restart}
328
329 We call the low-level system libc.time routine with the wrong argument
330 via ctypes to segfault the Python interpreter:
331
332 \begin{codecell}
333 \begin{codeinput}
334 \begin{lstlisting}
335 import sys
336 from ctypes import CDLL
337 # This will crash a Linux or Mac system; equivalent calls can be made on Windows
338 dll = 'dylib' if sys.platform == 'darwin' else '.so.6'
339 libc = CDLL("libc.%s" % dll)
340 libc.time(-1) # BOOM!!
341 \end{lstlisting}
342 \end{codeinput}
343 \end{codecell}
344 \subsection{Markdown cells can contain formatted text and code}
345
346 You can \emph{italicize}, \textbf{boldface}
347
348 \begin{itemize}
349 \item
350 build
351 \item
352 lists
353 \end{itemize}
354 and embed code meant for illustration instead of execution in Python:
355
356 \begin{verbatim}
357 def f(x):
358 """a docstring"""
359 return x**2
360 \end{verbatim}
361 or other languages:
362
363 \begin{verbatim}
364 if (i=0; i<n; i++) {
365 printf("hello %d\n", i);
366 x += 4;
367 }
368 \end{verbatim}
369
370
371 Courtesy of MathJax, you can include mathematical expressions both
372 inline: $e^{i\pi} + 1 = 0$ and displayed:
373
374 \[e^x=\sum_{i=0}^\infty \frac{1}{i!}x^i\]
375
376 \subsection{Rich displays: include anyting a browser can show}
377
378 Note that we have an actual protocol for this, see the
379 \texttt{display\_protocol} notebook for further details.
380
381 \subsubsection{Images}
382
383
384 \begin{codecell}
385 \begin{codeinput}
386 \begin{lstlisting}
387 from IPython.display import Image
388 Image(filename='../../source/_static/logo.png')
389 \end{lstlisting}
390 \end{codeinput}
391 \begin{codeoutput}
392 \begin{verbatim}
393 <IPython.core.display.Image at 0x10faeafd0>
394 \end{verbatim}
395 \end{codeoutput}
396 \end{codecell}
397 An image can also be displayed from raw data or a url
398
399 \begin{codecell}
400 \begin{codeinput}
401 \begin{lstlisting}
402 Image(url='http://python.org/images/python-logo.gif')
403 \end{lstlisting}
404 \end{codeinput}
405 \begin{codeoutput}
406 \begin{verbatim}
407 <IPython.core.display.Image at 0x1060e7410>
408 \end{verbatim}
409 \end{codeoutput}
410 \end{codecell}
411 SVG images are also supported out of the box (since modern browsers do a
412 good job of rendering them):
413
414 \begin{codecell}
415 \begin{codeinput}
416 \begin{lstlisting}
417 from IPython.display import SVG
418 SVG(filename='python-logo.svg')
419 \end{lstlisting}
420 \end{codeinput}
421 \begin{codeoutput}
422 \begin{verbatim}
423 <IPython.core.display.SVG at 0x10fb998d0>
424 \end{verbatim}
425 \end{codeoutput}
426 \end{codecell}
427 \paragraph{Embedded vs Non-embedded Images}
428
429
430 As of IPython 0.13, images are embedded by default for compatibility
431 with QtConsole, and the ability to still be displayed offline.
432
433 Let's look at the differences:
434
435 \begin{codecell}
436 \begin{codeinput}
437 \begin{lstlisting}
438 # by default Image data are embedded
439 Embed = Image( 'http://scienceview.berkeley.edu/view/images/newview.jpg')
440
441 # if kwarg `url` is given, the embedding is assumed to be false
442 SoftLinked = Image(url='http://scienceview.berkeley.edu/view/images/newview.jpg')
443
444 # In each case, embed can be specified explicitly with the `embed` kwarg
445 # ForceEmbed = Image(url='http://scienceview.berkeley.edu/view/images/newview.jpg', embed=True)
446 \end{lstlisting}
447 \end{codeinput}
448 \end{codecell}
449 Today's image from a webcam at Berkeley, (at the time I created this
450 notebook). This should also work in the Qtconsole. Drawback is that the
451 saved notebook will be larger, but the image will still be present
452 offline.
453
454 \begin{codecell}
455 \begin{codeinput}
456 \begin{lstlisting}
457 Embed
458 \end{lstlisting}
459 \end{codeinput}
460 \begin{codeoutput}
461 \begin{verbatim}
462 <IPython.core.display.Image at 0x10fb99b50>
463 \end{verbatim}
464 \end{codeoutput}
465 \end{codecell}
466 Today's image from same webcam at Berkeley, (refreshed every minutes, if
467 you reload the notebook), visible only with an active internet
468 connexion, that should be different from the previous one. This will not
469 work on Qtconsole. Notebook saved with this kind of image will be
470 lighter and always reflect the current version of the source, but the
471 image won't display offline.
472
473 \begin{codecell}
474 \begin{codeinput}
475 \begin{lstlisting}
476 SoftLinked
477 \end{lstlisting}
478 \end{codeinput}
479 \begin{codeoutput}
480 \begin{verbatim}
481 <IPython.core.display.Image at 0x10fb99b10>
482 \end{verbatim}
483 \end{codeoutput}
484 \end{codecell}
485 Of course, if you re-run the all notebook, the two images will be the
486 same again.
487
488 \subsubsection{Video}
489
490
491 And more exotic objects can also be displayed, as long as their
492 representation supports the IPython display protocol.
493
494 For example, videos hosted externally on YouTube are easy to load (and
495 writing a similar wrapper for other hosted content is trivial):
496
497 \begin{codecell}
498 \begin{codeinput}
499 \begin{lstlisting}
500 from IPython.display import YouTubeVideo
501 # a talk about IPython at Sage Days at U. Washington, Seattle.
502 # Video credit: William Stein.
503 YouTubeVideo('1j_HxD4iLn8')
504 \end{lstlisting}
505 \end{codeinput}
506 \begin{codeoutput}
507 \begin{verbatim}
508 <IPython.lib.display.YouTubeVideo at 0x10fba2190>
509 \end{verbatim}
510 \end{codeoutput}
511 \end{codecell}
512 Using the nascent video capabilities of modern browsers, you may also be
513 able to display local videos. At the moment this doesn't work very well
514 in all browsers, so it may or may not work for you; we will continue
515 testing this and looking for ways to make it more robust.
516
517 The following cell loads a local file called \texttt{animation.m4v},
518 encodes the raw video as base64 for http transport, and uses the HTML5
519 video tag to load it. On Chrome 15 it works correctly, displaying a
520 control bar at the bottom with a play/pause button and a location
521 slider.
522
523 \begin{codecell}
524 \begin{codeinput}
525 \begin{lstlisting}
526 from IPython.display import HTML
527 video = open("animation.m4v", "rb").read()
528 video_encoded = video.encode("base64")
529 video_tag = '<video controls alt="test" src="data:video/x-m4v;base64,{0}">'.format(video_encoded)
530 HTML(data=video_tag)
531 \end{lstlisting}
532 \end{codeinput}
533 \begin{codeoutput}
534 \begin{verbatim}
535 <IPython.core.display.HTML at 0x10fba28d0>
536 \end{verbatim}
537 \end{codeoutput}
538 \end{codecell}
539 \subsection{Local Files}
540
541 The above examples embed images and video from the notebook filesystem
542 in the output areas of code cells. It is also possible to request these
543 files directly in markdown cells if they reside in the notebook
544 directory via relative urls prefixed with \texttt{files/}:
545
546 \begin{verbatim}
547 files/[subdirectory/]<filename>
548 \end{verbatim}
549 For example, in the example notebook folder, we have the Python logo,
550 addressed as:
551
552 \begin{verbatim}
553 <img src="files/python-logo.svg" />
554 \end{verbatim}
555 and a video with the HTML5 video tag:
556
557 \begin{verbatim}
558 <video controls src="files/animation.m4v" />
559 \end{verbatim}
560 These do not embed the data into the notebook file, and require that the
561 files exist when you are viewing the notebook.
562
563 \subsubsection{Security of local files}
564
565 Note that this means that the IPython notebook server also acts as a
566 generic file server for files inside the same tree as your notebooks.
567 Access is not granted outside the notebook folder so you have strict
568 control over what files are visible, but for this reason it is highly
569 recommended that you do not run the notebook server with a notebook
570 directory at a high level in your filesystem (e.g.~your home directory).
571
572 When you run the notebook in a password-protected manner, local file
573 access is restricted to authenticated users unless read-only views are
574 active.
575
576 \subsection{Linking to files and directories for viewing in the browser}
577
578 It is also possible to link directly to files or directories so they can
579 be opened in the browser. This is especially convenient if you're
580 interacting with a tool within IPython that generates HTML pages, and
581 you'd like to easily be able to open those in a new browser window.
582 Alternatively, if your IPython notebook server is on a remote system,
583 creating links provides an easy way to download any files that get
584 generated.
585
586 As we saw above, there are a bunch of \texttt{.ipynb} files in our
587 current directory.
588
589 \begin{codecell}
590 \begin{codeinput}
591 \begin{lstlisting}
592 ls
593 \end{lstlisting}
594 \end{codeinput}
595 \begin{codeoutput}
596 \begin{verbatim}
597 00_notebook_tour.ipynb formatting.ipynb
598 01_notebook_introduction.ipynb octavemagic_extension.ipynb
599 Animations_and_Progress.ipynb publish_data.ipynb
600 Capturing Output.ipynb python-logo.svg
601 Script Magics.ipynb rmagic_extension.ipynb
602 animation.m4v sympy.ipynb
603 cython_extension.ipynb sympy_quantum_computing.ipynb
604 display_protocol.ipynb trapezoid_rule.ipynb
605 \end{verbatim}
606 \end{codeoutput}
607 \end{codecell}
608 If we want to create a link to one of them, we can call use the
609 \texttt{FileLink} object.
610
611 \begin{codecell}
612 \begin{codeinput}
613 \begin{lstlisting}
614 from IPython.display import FileLink
615 FileLink('00_notebook_tour.ipynb')
616 \end{lstlisting}
617 \end{codeinput}
618 \begin{codeoutput}
619 \begin{verbatim}
620 <IPython.lib.display.FileLink at 0x10f7ea3d0>
621 \end{verbatim}
622 \end{codeoutput}
623 \end{codecell}
624 Alternatively, if we want to link to all of them, we can use the
625 \texttt{FileLinks} object, passing \texttt{'.'} to indicate that we want
626 links generated for the current working directory. Note that if there
627 were other directories under the current directory, \texttt{FileLinks}
628 would work in a recursive manner creating links to files in all
629 sub-directories as well.
630
631 \begin{codecell}
632 \begin{codeinput}
633 \begin{lstlisting}
634 from IPython.display import FileLinks
635 FileLinks('.')
636 \end{lstlisting}
637 \end{codeinput}
638 \begin{codeoutput}
639 \begin{verbatim}
640 <IPython.lib.display.FileLinks at 0x10f7eaad0>
641 \end{verbatim}
642 \end{codeoutput}
643 \end{codecell}
644 \subsubsection{External sites}
645
646 You can even embed an entire page from another site in an iframe; for
647 example this is today's Wikipedia page for mobile users:
648
649 \begin{codecell}
650 \begin{codeinput}
651 \begin{lstlisting}
652 HTML('<iframe src=http://en.mobile.wikipedia.org/?useformat=mobile width=700 height=350></iframe>')
653 \end{lstlisting}
654 \end{codeinput}
655 \begin{codeoutput}
656 \begin{verbatim}
657 <IPython.core.display.HTML at 0x1094900d0>
658 \end{verbatim}
659 \end{codeoutput}
660 \end{codecell}
661 \subsubsection{Mathematics}
662
663 And we also support the display of mathematical expressions typeset in
664 LaTeX, which is rendered in the browser thanks to the
665 \href{http://mathjax.org}{MathJax library}.
666
667 Note that this is \emph{different} from the above examples. Above we
668 were typing mathematical expressions in Markdown cells (along with
669 normal text) and letting the browser render them; now we are displaying
670 the output of a Python computation as a LaTeX expression wrapped by the
671 \texttt{Math()} object so the browser renders it. The \texttt{Math}
672 object will add the needed LaTeX delimiters (\texttt{\$\$}) if they are
673 not provided:
674
675 \begin{codecell}
676 \begin{codeinput}
677 \begin{lstlisting}
678 from IPython.display import Math
679 Math(r'F(k) = \int_{-\infty}^{\infty} f(x) e^{2\pi i k} dx')
680 \end{lstlisting}
681 \end{codeinput}
682 \begin{codeoutput}
683 \begin{equation*}
684 F(k) = \int_{-\infty}^{\infty} f(x) e^{2\pi i k} dx
685 \end{equation*}
686 \end{codeoutput}
687 \end{codecell}
688 With the \texttt{Latex} class, you have to include the delimiters
689 yourself. This allows you to use other LaTeX modes such as
690 \texttt{eqnarray}:
691
692 \begin{codecell}
693 \begin{codeinput}
694 \begin{lstlisting}
695 from IPython.display import Latex
696 Latex(r"""\begin{eqnarray}
697 \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\
698 \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
699 \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
700 \nabla \cdot \vec{\mathbf{B}} & = 0
701 \end{eqnarray}""")
702 \end{lstlisting}
703 \end{codeinput}
704 \begin{codeoutput}
705 \begin{equation*}
706 \begin{eqnarray}
707 \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\
708 \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
709 \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
710 \nabla \cdot \vec{\mathbf{B}} & = 0
711 \end{eqnarray}
712 \end{equation*}
713 \end{codeoutput}
714 \end{codecell}
715 Or you can enter latex directly with the \texttt{\%\%latex} cell magic:
716
717 \begin{codecell}
718 \begin{codeinput}
719 \begin{lstlisting}
720 %%latex
721 \begin{aligned}
722 \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\
723 \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
724 \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
725 \nabla \cdot \vec{\mathbf{B}} & = 0
726 \end{aligned}
727 \end{lstlisting}
728 \end{codeinput}
729 \begin{codeoutput}
730 \begin{equation*}
731 \begin{aligned}
732 \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\
733 \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
734 \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
735 \nabla \cdot \vec{\mathbf{B}} & = 0
736 \end{aligned}
737 \end{equation*}
738 \end{codeoutput}
739 \end{codecell}
740 There is also a \texttt{\%\%javascript} cell magic for running
741 javascript directly, and \texttt{\%\%svg} for manually entering SVG
742 content.
743
744 \section{Loading external codes}
745
746 \begin{itemize}
747 \item
748 Drag and drop a \texttt{.py} in the dashboard
749 \item
750 Use \texttt{\%load} with any local or remote url:
751 \href{http://matplotlib.sourceforge.net/gallery.html}{the Matplotlib
752 Gallery!}
753 \end{itemize}
754 In this notebook we've kept the output saved so you can see the result,
755 but you should run the next cell yourself (with an active internet
756 connection).
757
758 Let's make sure we have pylab again, in case we have restarted the
759 kernel due to the crash demo above
760
761 \begin{codecell}
762 \begin{codeinput}
763 \begin{lstlisting}
764 %pylab inline
765 \end{lstlisting}
766 \end{codeinput}
767 \begin{codeoutput}
768 \begin{verbatim}
769 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
770 For more information, type 'help(pylab)'.
771 \end{verbatim}
772 \end{codeoutput}
773 \end{codecell}
774 \begin{codecell}
775 \begin{codeinput}
776 \begin{lstlisting}
777 %load http://matplotlib.sourceforge.net/mpl_examples/pylab_examples/integral_demo.py
778 \end{lstlisting}
779 \end{codeinput}
780 \end{codecell}
781 \begin{codecell}
782 \begin{codeinput}
783 \begin{lstlisting}
784 #!/usr/bin/env python
785
786 # implement the example graphs/integral from pyx
787 from pylab import *
788 from matplotlib.patches import Polygon
789
790 def func(x):
791 return (x-3)*(x-5)*(x-7)+85
792
793 ax = subplot(111)
794
795 a, b = 2, 9 # integral area
796 x = arange(0, 10, 0.01)
797 y = func(x)
798 plot(x, y, linewidth=1)
799
800 # make the shaded region
801 ix = arange(a, b, 0.01)
802 iy = func(ix)
803 verts = [(a,0)] + zip(ix,iy) + [(b,0)]
804 poly = Polygon(verts, facecolor='0.8', edgecolor='k')
805 ax.add_patch(poly)
806
807 text(0.5 * (a + b), 30,
808 r"$\int_a^b f(x)\mathrm{d}x$", horizontalalignment='center',
809 fontsize=20)
810
811 axis([0,10, 0, 180])
812 figtext(0.9, 0.05, 'x')
813 figtext(0.1, 0.9, 'y')
814 ax.set_xticks((a,b))
815 ax.set_xticklabels(('a','b'))
816 ax.set_yticks([])
817 show()
818
819 \end{lstlisting}
820 \end{codeinput}
821 \begin{codeoutput}
822 \begin{center}
823 \includegraphics[width=0.7\textwidth]{00_notebook_tour_orig_files/00_notebook_tour_orig_fig_01.png}
824 \par
825 \end{center}
826 \end{codeoutput}
827 \end{codecell}
828 \end{document}
@@ -0,0 +1,322 b''
1 # Some gun violence analysis with Wikipedia data
2
3 As [requested by John Stokes](https://twitter.com/jonst0kes/status/282330530412888064),
4 here are per-capita numbers for gun-related homicides,
5 relating to GDP and total homicides,
6 so the situation in the United States can be put in context relative to other nations.
7
8 main data source is UNODC (via Wikipedia [here](http://en.wikipedia.org/wiki/List_of_countries_by_intentional_homicide_rate)
9 and [here](http://en.wikipedia.org/wiki/List_of_countries_by_firearm-related_death_rate)).
10
11 GDP data from World Bank, again [via Wikipedia](http://en.wikipedia.org/wiki/List_of_countries_by_GDP_(PPP)_per_capita).
12
13 If the numbers on Wikipedia are inaccurate, or their relationship is not sound
14 (e.g. numbers taken from different years, during which significant change occured)
15 then obviously None of this analysis is valid.
16
17 To summarize the data,
18 every possible way you look at it the US is lousy at preventing gun violence.
19 Even when compared to significantly more violent places,
20 gun violence in the US is a serious problem,
21 and when compared to similarly wealthy places,
22 the US is an outstanding disaster.
23
24 **UPDATE:** the relationship of the gun data and totals does not seem to be valid.
25 [FBI data](http://www2.fbi.gov/ucr/cius2009/offenses/violent_crime/index.html) suggests that
26 the relative contribution of guns to homicides in the US is 47%,
27 but relating these two data sources gives 80%.
28 Internal comparisons should still be fine, but 'fraction' analysis has been stricken.
29
30 <div class="highlight"><pre><span class="o">%</span><span class="k">load_ext</span> <span class="n">retina</span>
31 <span class="o">%</span><span class="k">pylab</span> <span class="n">inline</span>
32 </pre></div>
33
34
35
36 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
37 For more information, type 'help(pylab)'.
38
39
40 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">display</span>
41 <span class="kn">import</span> <span class="nn">pandas</span>
42 <span class="n">pandas</span><span class="o">.</span><span class="n">set_option</span><span class="p">(</span><span class="s">&#39;display.notebook_repr_html&#39;</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
43 <span class="n">pandas</span><span class="o">.</span><span class="n">set_option</span><span class="p">(</span><span class="s">&#39;display.precision&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
44 </pre></div>
45
46
47
48 Some utility functions for display
49
50 <div class="highlight"><pre><span class="k">def</span> <span class="nf">plot_percent</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">10</span><span class="p">):</span>
51 <span class="n">df</span><span class="p">[</span><span class="s">&#39;Gun Percent&#39;</span><span class="p">][:</span><span class="n">limit</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
52 <span class="n">plt</span><span class="o">.</span><span class="n">ylim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">100</span><span class="p">)</span>
53 <span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s">&quot;</span><span class="si">% G</span><span class="s">un Homicide&quot;</span><span class="p">)</span>
54 <span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
55 </pre></div>
56
57
58
59 <div class="highlight"><pre><span class="k">def</span> <span class="nf">plot_percapita</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">10</span><span class="p">):</span>
60 <span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">ix</span><span class="p">[:,[</span><span class="s">&#39;Homicides&#39;</span><span class="p">,</span> <span class="s">&#39;Gun Homicides&#39;</span><span class="p">]][:</span><span class="n">limit</span><span class="p">]</span>
61 <span class="n">df</span><span class="p">[</span><span class="s">&#39;Total Homicides&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">&#39;Homicides&#39;</span><span class="p">]</span> <span class="o">-</span> <span class="n">df</span><span class="p">[</span><span class="s">&#39;Gun Homicides&#39;</span><span class="p">]</span>
62 <span class="k">del</span> <span class="n">df</span><span class="p">[</span><span class="s">&#39;Homicides&#39;</span><span class="p">]</span>
63 <span class="n">df</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">kind</span><span class="o">=</span><span class="s">&#39;bar&#39;</span><span class="p">,</span> <span class="n">stacked</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">sort_columns</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
64 <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s">&quot;per 100k&quot;</span><span class="p">)</span>
65 <span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
66 </pre></div>
67
68
69
70 <div class="highlight"><pre><span class="k">def</span> <span class="nf">display_relevant</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">10</span><span class="p">):</span>
71 <span class="n">display</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">ix</span><span class="p">[:,[</span><span class="s">&#39;Homicides&#39;</span><span class="p">,</span> <span class="s">&#39;Gun Homicides&#39;</span><span class="p">,</span> <span class="s">&#39;Gun Data Source&#39;</span><span class="p">]][:</span><span class="n">limit</span><span class="p">])</span>
72 </pre></div>
73
74
75
76 Load the data
77
78 <div class="highlight"><pre><span class="n">totals</span> <span class="o">=</span> <span class="n">pandas</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">&#39;totals.csv&#39;</span><span class="p">,</span> <span class="s">&#39;</span><span class="se">\t</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">index_col</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
79 <span class="n">guns</span> <span class="o">=</span> <span class="n">pandas</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">&#39;guns.csv&#39;</span><span class="p">,</span> <span class="s">&#39;</span><span class="se">\t</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">index_col</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
80 <span class="n">gdp</span> <span class="o">=</span> <span class="n">pandas</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">&#39;gdp.csv&#39;</span><span class="p">,</span> <span class="s">&#39;</span><span class="se">\t</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">index_col</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
81 <span class="n">data</span> <span class="o">=</span> <span class="n">totals</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">guns</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">gdp</span><span class="p">)</span>
82 <span class="n">data</span><span class="p">[</span><span class="s">&#39;Gun Percent&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="o">*</span> <span class="n">data</span><span class="p">[</span><span class="s">&#39;Gun Homicides&#39;</span><span class="p">]</span> <span class="o">/</span> <span class="n">data</span><span class="p">[</span><span class="s">&#39;Homicides&#39;</span><span class="p">]</span>
83 <span class="k">del</span> <span class="n">data</span><span class="p">[</span><span class="s">&#39;Unintentional&#39;</span><span class="p">],</span><span class="n">data</span><span class="p">[</span><span class="s">&#39;Undetermined&#39;</span><span class="p">],</span><span class="n">data</span><span class="p">[</span><span class="s">&#39;Gun Suicides&#39;</span><span class="p">]</span>
84 <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">dropna</span><span class="p">()</span>
85 </pre></div>
86
87
88
89 Of all sampled countries (Found data for 68 countries),
90 the US is in the top 15 in Gun Homicides per capita.
91
92 Numbers are per 100k.
93
94 <div class="highlight"><pre><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="s">&quot;Gun Homicides&quot;</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
95 <span class="n">display_relevant</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
96 </pre></div>
97
98
99 Homicides Gun Homicides Gun Data Source
100 Country
101 El Salvador 69.2 50.4 OAS 2011[1]
102 Jamaica 52.2 47.4 OAS 2011[1]
103 Honduras 91.6 46.7 OAS 2011[1]
104 Guatemala 38.5 38.5 OAS 2011[1]
105 Colombia 33.4 27.1 UNODC 2011 [2]
106 Brazil 21.0 18.1 UNODC 2011[3]
107 Panama 21.6 12.9 OAS 2011[1]
108 Mexico 16.9 10.0 UNODC 2011[4]
109 Paraguay 11.5 7.3 UNODC 2000[11]
110 Nicaragua 13.6 7.1 OAS 2011[1]
111 United States 4.2 3.7 OAS 2012[5][6]
112 Costa Rica 10.0 3.3 UNODC 2002[7]
113 Uruguay 5.9 3.2 UNODC 2002[7]
114 Argentina 3.4 3.0 UNODC 2011[12]
115 Barbados 11.3 3.0 UNODC 2000[11]
116
117 Take top 30 Countries by GDP
118
119 <div class="highlight"><pre><span class="n">top</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="s">&#39;GDP&#39;</span><span class="p">)[</span><span class="o">-</span><span class="mi">30</span><span class="p">:]</span>
120 </pre></div>
121
122
123
124 and rank them by Gun Homicides per capita:
125
126 <div class="highlight"><pre><span class="n">top_by_guns</span> <span class="o">=</span> <span class="n">top</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="s">&quot;Gun Homicides&quot;</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
127 <span class="n">display_relevant</span><span class="p">(</span><span class="n">top_by_guns</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
128 <span class="n">plot_percapita</span><span class="p">(</span><span class="n">top_by_guns</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
129 </pre></div>
130
131
132 Homicides Gun Homicides Gun Data Source
133 Country
134 United States 4.2 3.7 OAS 2012[5][6]
135 Israel 2.1 0.9 WHO 2012[10]
136 Canada 1.6 0.8 Krug 1998[13]
137 Luxembourg 2.5 0.6 WHO 2012[10]
138 Greece 1.5 0.6 Krug 1998[13]
139
140 ![](tests/ipynbref/Gun_Data_orig_files/Gun_Data_orig_fig_00.png)
141
142
143 **NOTE:** these bar graphs should not be interpreted as fractions of a total,
144 as the two data sources do not appear to be comparable.
145 But the red and blue bar graphs should still be internally comparable.
146
147 The US is easily #1 of 30 wealthiest countries in Gun Homicides per capita,
148 by a factor of 4:1
149
150 Adding USA, Canada, and Mexico to all of Europe,
151 USA is a strong #2 behind Mexico in total gun homicides per-capita
152
153 <div class="highlight"><pre><span class="n">index</span> <span class="o">=</span> <span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s">&#39;Region&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s">&#39;Europe&#39;</span><span class="p">)</span> <span class="o">+</span> \
154 <span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">index</span> <span class="o">==</span> <span class="s">&#39;United States&#39;</span><span class="p">)</span> <span class="o">+</span> \
155 <span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">index</span> <span class="o">==</span> <span class="s">&#39;Canada&#39;</span><span class="p">)</span> <span class="o">+</span> \
156 <span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">index</span> <span class="o">==</span> <span class="s">&#39;Mexico&#39;</span><span class="p">)</span>
157 <span class="n">selected</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
158
159 <span class="k">print</span> <span class="s">&quot;By Total Gun Homicides&quot;</span>
160 <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
161
162 <span class="n">by_guns</span> <span class="o">=</span> <span class="n">selected</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="s">&quot;Gun Homicides&quot;</span><span class="p">,</span> <span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
163 <span class="c">#by_guns[&#39;Gun Homicides&#39;].plot(kind=&#39;bar&#39;)</span>
164 <span class="n">plot_percapita</span><span class="p">(</span><span class="n">by_guns</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">25</span><span class="p">)</span>
165 <span class="n">display_relevant</span><span class="p">(</span><span class="n">selected</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
166 </pre></div>
167
168
169 By Total Gun Homicides
170
171
172 ![](tests/ipynbref/Gun_Data_orig_files/Gun_Data_orig_fig_01.png)
173
174 Homicides Gun Homicides Gun Data Source
175 Country
176 Mexico 16.9 10.0 UNODC 2011[4]
177 United States 4.2 3.7 OAS 2012[5][6]
178 Montenegro 3.5 2.1 WHO 2012[10]
179 Moldova 7.5 1.0 WHO 2012[10]
180 Canada 1.6 0.8 Krug 1998[13]
181 Serbia 1.2 0.6 WHO 2012[10]
182 Luxembourg 2.5 0.6 WHO 2012[10]
183 Greece 1.5 0.6 Krug 1998[13]
184 Croatia 1.4 0.6 WHO 2012[10]
185 Switzerland 0.7 0.5 OAS 2011[1]
186 Malta 1.0 0.5 WHO 2012[10]
187 Portugal 1.2 0.5 WHO 2012[10]
188 Belarus 4.9 0.4 UNODC 2002[7]
189 Ireland 1.2 0.4 WHO 2012[10]
190 Italy 0.9 0.4 WHO 2012[10]
191 Ukraine 5.2 0.3 UNODC 2000[11]
192 Estonia 5.2 0.3 WHO 2012[10]
193 Belgium 1.7 0.3 WHO 2012[10]
194 Finland 2.2 0.3 WHO 2012[10]
195 Lithuania 6.6 0.2 WHO 2012[10]
196 Bulgaria 2.0 0.2 WHO 2012[10]
197 Georgia 4.3 0.2 WHO 2012[10]
198 Denmark 0.9 0.2 WHO 2012[10]
199 France 1.1 0.2 WHO 2012[10]
200 Netherlands 1.1 0.2 WHO 2012[10]
201 Sweden 1.0 0.2 WHO 2012[10]
202 Slovakia 1.5 0.2 WHO 2012[10]
203 Austria 0.6 0.2 WHO 2012[10]
204 Latvia 3.1 0.2 WHO 2012[10]
205 Spain 0.8 0.1 WHO 2012[10]
206 Hungary 1.3 0.1 WHO 2012[10]
207 Czech Republic 1.7 0.1 WHO 2012[10]
208 Germany 0.8 0.1 WHO 2012[10]
209 Slovenia 0.7 0.1 WHO 2012[10]
210 Romania 2.0 0.0 WHO 2012[10]
211 United Kingdom 1.2 0.0 WHO2012 [10]
212 Norway 0.6 0.0 WHO 2012[10]
213 Poland 1.1 0.0 WHO 2012[10]
214
215 Let's just compare US, Canada, and UK:
216
217 <div class="highlight"><pre><span class="n">select</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">ix</span><span class="p">[[</span><span class="s">&#39;United States&#39;</span><span class="p">,</span> <span class="s">&#39;Canada&#39;</span><span class="p">,</span> <span class="s">&#39;United Kingdom&#39;</span><span class="p">]]</span>
218 <span class="n">plot_percapita</span><span class="p">(</span><span class="n">select</span><span class="p">)</span>
219 </pre></div>
220
221
222
223 ![](tests/ipynbref/Gun_Data_orig_files/Gun_Data_orig_fig_02.png)
224
225
226 Normalize to the US numbers (inverse)
227
228 <div class="highlight"><pre><span class="n">select</span><span class="p">[</span><span class="s">&#39;Homicides&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">select</span><span class="p">[</span><span class="s">&#39;Homicides&#39;</span><span class="p">][</span><span class="s">&#39;United States&#39;</span><span class="p">]</span> <span class="o">/</span> <span class="n">select</span><span class="p">[</span><span class="s">&#39;Homicides&#39;</span><span class="p">]</span>
229 <span class="n">select</span><span class="p">[</span><span class="s">&#39;Gun Homicides&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">select</span><span class="p">[</span><span class="s">&#39;Gun Homicides&#39;</span><span class="p">][</span><span class="s">&#39;United States&#39;</span><span class="p">]</span> <span class="o">/</span> <span class="n">select</span><span class="p">[</span><span class="s">&#39;Gun Homicides&#39;</span><span class="p">]</span>
230 <span class="n">display_relevant</span><span class="p">(</span><span class="n">select</span><span class="p">)</span>
231 </pre></div>
232
233
234 Homicides Gun Homicides Gun Data Source
235 United States 1.0 1.0 OAS 2012[5][6]
236 Canada 2.6 4.9 Krug 1998[13]
237 United Kingdom 3.5 92.5 WHO2012 [10]
238
239 So, you are 2.6 times more likely to be killed in the US than Canada,
240 and 3.5 times more likely than in the UK.
241 That's bad, but not extreme.
242
243 However, you are 4.9 times more likely to be killed *with a gun* in the US than Canada,
244 and almost 100 times more likely than in the UK. That is pretty extreme.
245
246
247 Countries represented:
248
249 <div class="highlight"><pre><span class="k">for</span> <span class="n">country</span> <span class="ow">in</span> <span class="n">data</span><span class="o">.</span><span class="n">index</span><span class="p">:</span>
250 <span class="k">print</span> <span class="n">country</span>
251 </pre></div>
252
253
254 El Salvador
255 Jamaica
256 Honduras
257 Guatemala
258 Colombia
259 Brazil
260 Panama
261 Mexico
262 Paraguay
263 Nicaragua
264 United States
265 Costa Rica
266 Uruguay
267 Argentina
268 Barbados
269 Montenegro
270 Peru
271 Moldova
272 Israel
273 India
274 Canada
275 Serbia
276 Luxembourg
277 Greece
278 Uzbekistan
279 Croatia
280 Kyrgyzstan
281 Switzerland
282 Malta
283 Portugal
284 Belarus
285 Ireland
286 Italy
287 Kuwait
288 Ukraine
289 Estonia
290 Belgium
291 Finland
292 Lithuania
293 Cyprus
294 Bulgaria
295 Georgia
296 Denmark
297 France
298 Netherlands
299 Sweden
300 Slovakia
301 Qatar
302 Austria
303 Latvia
304 New Zealand
305 Spain
306 Hungary
307 Czech Republic
308 Hong Kong
309 Australia
310 Singapore
311 Chile
312 Germany
313 Slovenia
314 Romania
315 Azerbaijan
316 South Korea
317 United Kingdom
318 Norway
319 Japan
320 Poland
321 Mauritius
322
@@ -0,0 +1,304 b''
1 ## Some gun violence analysis with Wikipedia data
2
3 # As [requested by John Stokes](https://twitter.com/jonst0kes/status/282330530412888064),
4 # here are per-capita numbers for gun-related homicides,
5 # relating to GDP and total homicides,
6 # so the situation in the United States can be put in context relative to other nations.
7
8 # main data source is UNODC (via Wikipedia [here](http://en.wikipedia.org/wiki/List_of_countries_by_intentional_homicide_rate)
9 # and [here](http://en.wikipedia.org/wiki/List_of_countries_by_firearm-related_death_rate)).
10 #
11 # GDP data from World Bank, again [via Wikipedia](http://en.wikipedia.org/wiki/List_of_countries_by_GDP_(PPP)_per_capita).
12 #
13 # If the numbers on Wikipedia are inaccurate, or their relationship is not sound
14 # (e.g. numbers taken from different years, during which significant change occured)
15 # then obviously None of this analysis is valid.
16 #
17 # To summarize the data,
18 # every possible way you look at it the US is lousy at preventing gun violence.
19 # Even when compared to significantly more violent places,
20 # gun violence in the US is a serious problem,
21 # and when compared to similarly wealthy places,
22 # the US is an outstanding disaster.
23
24 # **UPDATE:** the relationship of the gun data and totals does not seem to be valid.
25 # [FBI data](http://www2.fbi.gov/ucr/cius2009/offenses/violent_crime/index.html) suggests that
26 # the relative contribution of guns to homicides in the US is 47%,
27 # but relating these two data sources gives 80%.
28 # Internal comparisons should still be fine, but 'fraction' analysis has been stricken.
29
30 # In[1]:
31 %load_ext retina
32 %pylab inline
33
34 # Out[1]:
35 #
36 # Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
37 # For more information, type 'help(pylab)'.
38 #
39 # In[2]:
40 from IPython.display import display
41 import pandas
42 pandas.set_option('display.notebook_repr_html', True)
43 pandas.set_option('display.precision', 2)
44
45 # Some utility functions for display
46
47 # In[3]:
48 def plot_percent(df, limit=10):
49 df['Gun Percent'][:limit].plot()
50 plt.ylim(0,100)
51 plt.title("% Gun Homicide")
52 plt.show()
53
54
55 # In[4]:
56 def plot_percapita(df, limit=10):
57 df = df.ix[:,['Homicides', 'Gun Homicides']][:limit]
58 df['Total Homicides'] = df['Homicides'] - df['Gun Homicides']
59 del df['Homicides']
60 df.plot(kind='bar', stacked=True, sort_columns=True)
61 plt.ylabel("per 100k")
62 plt.show()
63
64
65 # In[8]:
66 def display_relevant(df, limit=10):
67 display(df.ix[:,['Homicides', 'Gun Homicides', 'Gun Data Source']][:limit])
68
69 # Load the data
70
71 # In[9]:
72 totals = pandas.read_csv('totals.csv', '\t', index_col=0)
73 guns = pandas.read_csv('guns.csv', '\t', index_col=0)
74 gdp = pandas.read_csv('gdp.csv', '\t', index_col=1)
75 data = totals.join(guns).join(gdp)
76 data['Gun Percent'] = 100 * data['Gun Homicides'] / data['Homicides']
77 del data['Unintentional'],data['Undetermined'],data['Gun Suicides']
78 data = data.dropna()
79
80 # Of all sampled countries (Found data for 68 countries),
81 # the US is in the top 15 in Gun Homicides per capita.
82 #
83 # Numbers are per 100k.
84
85 # In[10]:
86 data = data.sort("Gun Homicides", ascending=False)
87 display_relevant(data, 15)
88
89 # Out[10]:
90 # Homicides Gun Homicides Gun Data Source
91 # Country
92 # El Salvador 69.2 50.4 OAS 2011[1]
93 # Jamaica 52.2 47.4 OAS 2011[1]
94 # Honduras 91.6 46.7 OAS 2011[1]
95 # Guatemala 38.5 38.5 OAS 2011[1]
96 # Colombia 33.4 27.1 UNODC 2011 [2]
97 # Brazil 21.0 18.1 UNODC 2011[3]
98 # Panama 21.6 12.9 OAS 2011[1]
99 # Mexico 16.9 10.0 UNODC 2011[4]
100 # Paraguay 11.5 7.3 UNODC 2000[11]
101 # Nicaragua 13.6 7.1 OAS 2011[1]
102 # United States 4.2 3.7 OAS 2012[5][6]
103 # Costa Rica 10.0 3.3 UNODC 2002[7]
104 # Uruguay 5.9 3.2 UNODC 2002[7]
105 # Argentina 3.4 3.0 UNODC 2011[12]
106 # Barbados 11.3 3.0 UNODC 2000[11]
107 # Take top 30 Countries by GDP
108
109 # In[11]:
110 top = data.sort('GDP')[-30:]
111
112 # and rank them by Gun Homicides per capita:
113
114 # In[12]:
115 top_by_guns = top.sort("Gun Homicides", ascending=False)
116 display_relevant(top_by_guns, 5)
117 plot_percapita(top_by_guns, 10)
118
119 # Out[12]:
120 # Homicides Gun Homicides Gun Data Source
121 # Country
122 # United States 4.2 3.7 OAS 2012[5][6]
123 # Israel 2.1 0.9 WHO 2012[10]
124 # Canada 1.6 0.8 Krug 1998[13]
125 # Luxembourg 2.5 0.6 WHO 2012[10]
126 # Greece 1.5 0.6 Krug 1998[13]
127 # image file: tests/ipynbref/Gun_Data_orig_files/Gun_Data_orig_fig_00.png
128
129 # **NOTE:** these bar graphs should not be interpreted as fractions of a total,
130 # as the two data sources do not appear to be comparable.
131 # But the red and blue bar graphs should still be internally comparable.
132
133 # The US is easily #1 of 30 wealthiest countries in Gun Homicides per capita,
134 # by a factor of 4:1
135
136 # Adding USA, Canada, and Mexico to all of Europe,
137 # USA is a strong #2 behind Mexico in total gun homicides per-capita
138
139 # In[13]:
140 index = (data['Region'] == 'Europe') + \
141 (data.index == 'United States') + \
142 (data.index == 'Canada') + \
143 (data.index == 'Mexico')
144 selected = data[index]
145
146 print "By Total Gun Homicides"
147 sys.stdout.flush()
148
149 by_guns = selected.sort("Gun Homicides", ascending=False)
150 #by_guns['Gun Homicides'].plot(kind='bar')
151 plot_percapita(by_guns, limit=25)
152 display_relevant(selected, limit=None)
153
154
155 # Out[13]:
156 # By Total Gun Homicides
157 #
158 # image file: tests/ipynbref/Gun_Data_orig_files/Gun_Data_orig_fig_01.png
159
160 # Homicides Gun Homicides Gun Data Source
161 # Country
162 # Mexico 16.9 10.0 UNODC 2011[4]
163 # United States 4.2 3.7 OAS 2012[5][6]
164 # Montenegro 3.5 2.1 WHO 2012[10]
165 # Moldova 7.5 1.0 WHO 2012[10]
166 # Canada 1.6 0.8 Krug 1998[13]
167 # Serbia 1.2 0.6 WHO 2012[10]
168 # Luxembourg 2.5 0.6 WHO 2012[10]
169 # Greece 1.5 0.6 Krug 1998[13]
170 # Croatia 1.4 0.6 WHO 2012[10]
171 # Switzerland 0.7 0.5 OAS 2011[1]
172 # Malta 1.0 0.5 WHO 2012[10]
173 # Portugal 1.2 0.5 WHO 2012[10]
174 # Belarus 4.9 0.4 UNODC 2002[7]
175 # Ireland 1.2 0.4 WHO 2012[10]
176 # Italy 0.9 0.4 WHO 2012[10]
177 # Ukraine 5.2 0.3 UNODC 2000[11]
178 # Estonia 5.2 0.3 WHO 2012[10]
179 # Belgium 1.7 0.3 WHO 2012[10]
180 # Finland 2.2 0.3 WHO 2012[10]
181 # Lithuania 6.6 0.2 WHO 2012[10]
182 # Bulgaria 2.0 0.2 WHO 2012[10]
183 # Georgia 4.3 0.2 WHO 2012[10]
184 # Denmark 0.9 0.2 WHO 2012[10]
185 # France 1.1 0.2 WHO 2012[10]
186 # Netherlands 1.1 0.2 WHO 2012[10]
187 # Sweden 1.0 0.2 WHO 2012[10]
188 # Slovakia 1.5 0.2 WHO 2012[10]
189 # Austria 0.6 0.2 WHO 2012[10]
190 # Latvia 3.1 0.2 WHO 2012[10]
191 # Spain 0.8 0.1 WHO 2012[10]
192 # Hungary 1.3 0.1 WHO 2012[10]
193 # Czech Republic 1.7 0.1 WHO 2012[10]
194 # Germany 0.8 0.1 WHO 2012[10]
195 # Slovenia 0.7 0.1 WHO 2012[10]
196 # Romania 2.0 0.0 WHO 2012[10]
197 # United Kingdom 1.2 0.0 WHO2012 [10]
198 # Norway 0.6 0.0 WHO 2012[10]
199 # Poland 1.1 0.0 WHO 2012[10]
200 # Let's just compare US, Canada, and UK:
201
202 # In[15]:
203 select = data.ix[['United States', 'Canada', 'United Kingdom']]
204 plot_percapita(select)
205
206 # Out[15]:
207 # image file: tests/ipynbref/Gun_Data_orig_files/Gun_Data_orig_fig_02.png
208
209 # Normalize to the US numbers (inverse)
210
211 # In[16]:
212 select['Homicides'] = select['Homicides']['United States'] / select['Homicides']
213 select['Gun Homicides'] = select['Gun Homicides']['United States'] / select['Gun Homicides']
214 display_relevant(select)
215
216 # Out[16]:
217 # Homicides Gun Homicides Gun Data Source
218 # United States 1.0 1.0 OAS 2012[5][6]
219 # Canada 2.6 4.9 Krug 1998[13]
220 # United Kingdom 3.5 92.5 WHO2012 [10]
221 # So, you are 2.6 times more likely to be killed in the US than Canada,
222 # and 3.5 times more likely than in the UK.
223 # That's bad, but not extreme.
224 #
225 # However, you are 4.9 times more likely to be killed *with a gun* in the US than Canada,
226 # and almost 100 times more likely than in the UK. That is pretty extreme.
227 #
228
229 # Countries represented:
230
231 # In[14]:
232 for country in data.index:
233 print country
234
235 # Out[14]:
236 # El Salvador
237 # Jamaica
238 # Honduras
239 # Guatemala
240 # Colombia
241 # Brazil
242 # Panama
243 # Mexico
244 # Paraguay
245 # Nicaragua
246 # United States
247 # Costa Rica
248 # Uruguay
249 # Argentina
250 # Barbados
251 # Montenegro
252 # Peru
253 # Moldova
254 # Israel
255 # India
256 # Canada
257 # Serbia
258 # Luxembourg
259 # Greece
260 # Uzbekistan
261 # Croatia
262 # Kyrgyzstan
263 # Switzerland
264 # Malta
265 # Portugal
266 # Belarus
267 # Ireland
268 # Italy
269 # Kuwait
270 # Ukraine
271 # Estonia
272 # Belgium
273 # Finland
274 # Lithuania
275 # Cyprus
276 # Bulgaria
277 # Georgia
278 # Denmark
279 # France
280 # Netherlands
281 # Sweden
282 # Slovakia
283 # Qatar
284 # Austria
285 # Latvia
286 # New Zealand
287 # Spain
288 # Hungary
289 # Czech Republic
290 # Hong Kong
291 # Australia
292 # Singapore
293 # Chile
294 # Germany
295 # Slovenia
296 # Romania
297 # Azerbaijan
298 # South Korea
299 # United Kingdom
300 # Norway
301 # Japan
302 # Poland
303 # Mauritius
304 # No newline at end of file
This diff has been collapsed as it changes many lines, (505 lines changed) Show them Hide them
@@ -0,0 +1,505 b''
1 %% This file was auto-generated by IPython.
2 %% Conversion from the original notebook file:
3 %% tests/ipynbref/Gun_Data.orig.ipynb
4 %%
5 \documentclass[11pt,english]{article}
6
7 %% This is the automatic preamble used by IPython. Note that it does *not*
8 %% include a documentclass declaration, that is added at runtime to the overall
9 %% document.
10
11 \usepackage{amsmath}
12 \usepackage{amssymb}
13 \usepackage{graphicx}
14 \usepackage{ucs}
15 \usepackage[utf8x]{inputenc}
16
17 % needed for markdown enumerations to work
18 \usepackage{enumerate}
19
20 % Slightly bigger margins than the latex defaults
21 \usepackage{geometry}
22 \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm}
23
24 % Define a few colors for use in code, links and cell shading
25 \usepackage{color}
26 \definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
27 \definecolor{darkorange}{rgb}{.71,0.21,0.01}
28 \definecolor{darkgreen}{rgb}{.12,.54,.11}
29 \definecolor{myteal}{rgb}{.26, .44, .56}
30 \definecolor{gray}{gray}{0.45}
31 \definecolor{lightgray}{gray}{.95}
32 \definecolor{mediumgray}{gray}{.8}
33 \definecolor{inputbackground}{rgb}{.95, .95, .85}
34 \definecolor{outputbackground}{rgb}{.95, .95, .95}
35 \definecolor{traceback}{rgb}{1, .95, .95}
36
37 % Framed environments for code cells (inputs, outputs, errors, ...). The
38 % various uses of \unskip (or not) at the end were fine-tuned by hand, so don't
39 % randomly change them unless you're sure of the effect it will have.
40 \usepackage{framed}
41
42 % remove extraneous vertical space in boxes
43 \setlength\fboxsep{0pt}
44
45 % codecell is the whole input+output set of blocks that a Code cell can
46 % generate.
47
48 % TODO: unfortunately, it seems that using a framed codecell environment breaks
49 % the ability of the frames inside of it to be broken across pages. This
50 % causes at least the problem of having lots of empty space at the bottom of
51 % pages as new frames are moved to the next page, and if a single frame is too
52 % long to fit on a page, will completely stop latex from compiling the
53 % document. So unless we figure out a solution to this, we'll have to instead
54 % leave the codecell env. as empty. I'm keeping the original codecell
55 % definition here (a thin vertical bar) for reference, in case we find a
56 % solution to the page break issue.
57
58 %% \newenvironment{codecell}{%
59 %% \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}%
60 %% \MakeFramed{\vspace{-0.5em}}}
61 %% {\unskip\endMakeFramed}
62
63 % For now, make this a no-op...
64 \newenvironment{codecell}{}
65
66 \newenvironment{codeinput}{%
67 \def\FrameCommand{\colorbox{inputbackground}}%
68 \MakeFramed{\advance\hsize-\width \FrameRestore}}
69 {\unskip\endMakeFramed}
70
71 \newenvironment{codeoutput}{%
72 \def\FrameCommand{\colorbox{outputbackground}}%
73 \vspace{-1.4em}
74 \MakeFramed{\advance\hsize-\width \FrameRestore}}
75 {\unskip\medskip\endMakeFramed}
76
77 \newenvironment{traceback}{%
78 \def\FrameCommand{\colorbox{traceback}}%
79 \MakeFramed{\advance\hsize-\width \FrameRestore}}
80 {\endMakeFramed}
81
82 % Use and configure listings package for nicely formatted code
83 \usepackage{listingsutf8}
84 \lstset{
85 language=python,
86 inputencoding=utf8x,
87 extendedchars=\true,
88 aboveskip=\smallskipamount,
89 belowskip=\smallskipamount,
90 xleftmargin=2mm,
91 breaklines=true,
92 basicstyle=\small \ttfamily,
93 showstringspaces=false,
94 keywordstyle=\color{blue}\bfseries,
95 commentstyle=\color{myteal},
96 stringstyle=\color{darkgreen},
97 identifierstyle=\color{darkorange},
98 columns=fullflexible, % tighter character kerning, like verb
99 }
100
101 % The hyperref package gives us a pdf with properly built
102 % internal navigation ('pdf bookmarks' for the table of contents,
103 % internal cross-reference links, web links for URLs, etc.)
104 \usepackage{hyperref}
105 \hypersetup{
106 breaklinks=true, % so long urls are correctly broken across lines
107 colorlinks=true,
108 urlcolor=blue,
109 linkcolor=darkorange,
110 citecolor=darkgreen,
111 }
112
113 % hardcode size of all verbatim environments to be a bit smaller
114 \makeatletter
115 \g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt
116 \makeatother
117
118 % Prevent overflowing lines due to urls and other hard-to-break entities.
119 \sloppy
120
121 \begin{document}
122
123 \section{Some gun violence analysis with Wikipedia data}
124 As
125 \href{https://twitter.com/jonst0kes/status/282330530412888064}{requested
126 by John Stokes}, here are per-capita numbers for gun-related homicides,
127 relating to GDP and total homicides, so the situation in the United
128 States can be put in context relative to other nations.
129
130 main data source is UNODC (via Wikipedia
131 \href{http://en.wikipedia.org/wiki/List\_of\_countries\_by\_intentional\_homicide\_rate}{here}
132 and
133 \href{http://en.wikipedia.org/wiki/List\_of\_countries\_by\_firearm-related\_death\_rate}{here}).
134
135 GDP data from World Bank, again
136 \href{http://en.wikipedia.org/wiki/List\_of\_countries\_by\_GDP\_(PPP)\_per\_capita}{via
137 Wikipedia}.
138
139 If the numbers on Wikipedia are inaccurate, or their relationship is not
140 sound (e.g.~numbers taken from different years, during which significant
141 change occured) then obviously None of this analysis is valid.
142
143 To summarize the data, every possible way you look at it the US is lousy
144 at preventing gun violence. Even when compared to significantly more
145 violent places, gun violence in the US is a serious problem, and when
146 compared to similarly wealthy places, the US is an outstanding disaster.
147
148 \textbf{UPDATE:} the relationship of the gun data and totals does not
149 seem to be valid.
150 \href{http://www2.fbi.gov/ucr/cius2009/offenses/violent\_crime/index.html}{FBI
151 data} suggests that the relative contribution of guns to homicides in
152 the US is 47\%, but relating these two data sources gives 80\%. Internal
153 comparisons should still be fine, but `fraction' analysis has been
154 stricken.
155
156 \begin{codecell}
157 \begin{codeinput}
158 \begin{lstlisting}
159 %load_ext retina
160 %pylab inline
161 \end{lstlisting}
162 \end{codeinput}
163 \begin{codeoutput}
164 \begin{verbatim}
165 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
166 For more information, type 'help(pylab)'.
167 \end{verbatim}
168 \end{codeoutput}
169 \end{codecell}
170 \begin{codecell}
171 \begin{codeinput}
172 \begin{lstlisting}
173 from IPython.display import display
174 import pandas
175 pandas.set_option('display.notebook_repr_html', True)
176 pandas.set_option('display.precision', 2)
177 \end{lstlisting}
178 \end{codeinput}
179 \end{codecell}
180 Some utility functions for display
181
182 \begin{codecell}
183 \begin{codeinput}
184 \begin{lstlisting}
185 def plot_percent(df, limit=10):
186 df['Gun Percent'][:limit].plot()
187 plt.ylim(0,100)
188 plt.title("% Gun Homicide")
189 plt.show()
190
191 \end{lstlisting}
192 \end{codeinput}
193 \end{codecell}
194 \begin{codecell}
195 \begin{codeinput}
196 \begin{lstlisting}
197 def plot_percapita(df, limit=10):
198 df = df.ix[:,['Homicides', 'Gun Homicides']][:limit]
199 df['Total Homicides'] = df['Homicides'] - df['Gun Homicides']
200 del df['Homicides']
201 df.plot(kind='bar', stacked=True, sort_columns=True)
202 plt.ylabel("per 100k")
203 plt.show()
204
205 \end{lstlisting}
206 \end{codeinput}
207 \end{codecell}
208 \begin{codecell}
209 \begin{codeinput}
210 \begin{lstlisting}
211 def display_relevant(df, limit=10):
212 display(df.ix[:,['Homicides', 'Gun Homicides', 'Gun Data Source']][:limit])
213 \end{lstlisting}
214 \end{codeinput}
215 \end{codecell}
216 Load the data
217
218 \begin{codecell}
219 \begin{codeinput}
220 \begin{lstlisting}
221 totals = pandas.read_csv('totals.csv', '\t', index_col=0)
222 guns = pandas.read_csv('guns.csv', '\t', index_col=0)
223 gdp = pandas.read_csv('gdp.csv', '\t', index_col=1)
224 data = totals.join(guns).join(gdp)
225 data['Gun Percent'] = 100 * data['Gun Homicides'] / data['Homicides']
226 del data['Unintentional'],data['Undetermined'],data['Gun Suicides']
227 data = data.dropna()
228 \end{lstlisting}
229 \end{codeinput}
230 \end{codecell}
231 Of all sampled countries (Found data for 68 countries), the US is in the
232 top 15 in Gun Homicides per capita.
233
234 Numbers are per 100k.
235
236 \begin{codecell}
237 \begin{codeinput}
238 \begin{lstlisting}
239 data = data.sort("Gun Homicides", ascending=False)
240 display_relevant(data, 15)
241 \end{lstlisting}
242 \end{codeinput}
243 \begin{codeoutput}
244 \begin{verbatim}
245 Homicides Gun Homicides Gun Data Source
246 Country
247 El Salvador 69.2 50.4 OAS 2011[1]
248 Jamaica 52.2 47.4 OAS 2011[1]
249 Honduras 91.6 46.7 OAS 2011[1]
250 Guatemala 38.5 38.5 OAS 2011[1]
251 Colombia 33.4 27.1 UNODC 2011 [2]
252 Brazil 21.0 18.1 UNODC 2011[3]
253 Panama 21.6 12.9 OAS 2011[1]
254 Mexico 16.9 10.0 UNODC 2011[4]
255 Paraguay 11.5 7.3 UNODC 2000[11]
256 Nicaragua 13.6 7.1 OAS 2011[1]
257 United States 4.2 3.7 OAS 2012[5][6]
258 Costa Rica 10.0 3.3 UNODC 2002[7]
259 Uruguay 5.9 3.2 UNODC 2002[7]
260 Argentina 3.4 3.0 UNODC 2011[12]
261 Barbados 11.3 3.0 UNODC 2000[11]
262 \end{verbatim}
263 \end{codeoutput}
264 \end{codecell}
265 Take top 30 Countries by GDP
266
267 \begin{codecell}
268 \begin{codeinput}
269 \begin{lstlisting}
270 top = data.sort('GDP')[-30:]
271 \end{lstlisting}
272 \end{codeinput}
273 \end{codecell}
274 and rank them by Gun Homicides per capita:
275
276 \begin{codecell}
277 \begin{codeinput}
278 \begin{lstlisting}
279 top_by_guns = top.sort("Gun Homicides", ascending=False)
280 display_relevant(top_by_guns, 5)
281 plot_percapita(top_by_guns, 10)
282 \end{lstlisting}
283 \end{codeinput}
284 \begin{codeoutput}
285 \begin{verbatim}
286 Homicides Gun Homicides Gun Data Source
287 Country
288 United States 4.2 3.7 OAS 2012[5][6]
289 Israel 2.1 0.9 WHO 2012[10]
290 Canada 1.6 0.8 Krug 1998[13]
291 Luxembourg 2.5 0.6 WHO 2012[10]
292 Greece 1.5 0.6 Krug 1998[13]
293 \end{verbatim}
294 \begin{center}
295 \includegraphics[width=0.7\textwidth]{Gun_Data_orig_files/Gun_Data_orig_fig_00.png}
296 \par
297 \end{center}
298 \end{codeoutput}
299 \end{codecell}
300 \textbf{NOTE:} these bar graphs should not be interpreted as fractions
301 of a total, as the two data sources do not appear to be comparable. But
302 the red and blue bar graphs should still be internally comparable.
303
304 The US is easily \#1 of 30 wealthiest countries in Gun Homicides per
305 capita, by a factor of 4:1
306
307 Adding USA, Canada, and Mexico to all of Europe, USA is a strong \#2
308 behind Mexico in total gun homicides per-capita
309
310 \begin{codecell}
311 \begin{codeinput}
312 \begin{lstlisting}
313 index = (data['Region'] == 'Europe') + \
314 (data.index == 'United States') + \
315 (data.index == 'Canada') + \
316 (data.index == 'Mexico')
317 selected = data[index]
318
319 print "By Total Gun Homicides"
320 sys.stdout.flush()
321
322 by_guns = selected.sort("Gun Homicides", ascending=False)
323 #by_guns['Gun Homicides'].plot(kind='bar')
324 plot_percapita(by_guns, limit=25)
325 display_relevant(selected, limit=None)
326
327 \end{lstlisting}
328 \end{codeinput}
329 \begin{codeoutput}
330 \begin{verbatim}
331 By Total Gun Homicides
332 \end{verbatim}
333 \begin{center}
334 \includegraphics[width=0.7\textwidth]{Gun_Data_orig_files/Gun_Data_orig_fig_01.png}
335 \par
336 \end{center}
337 \begin{verbatim}
338 Homicides Gun Homicides Gun Data Source
339 Country
340 Mexico 16.9 10.0 UNODC 2011[4]
341 United States 4.2 3.7 OAS 2012[5][6]
342 Montenegro 3.5 2.1 WHO 2012[10]
343 Moldova 7.5 1.0 WHO 2012[10]
344 Canada 1.6 0.8 Krug 1998[13]
345 Serbia 1.2 0.6 WHO 2012[10]
346 Luxembourg 2.5 0.6 WHO 2012[10]
347 Greece 1.5 0.6 Krug 1998[13]
348 Croatia 1.4 0.6 WHO 2012[10]
349 Switzerland 0.7 0.5 OAS 2011[1]
350 Malta 1.0 0.5 WHO 2012[10]
351 Portugal 1.2 0.5 WHO 2012[10]
352 Belarus 4.9 0.4 UNODC 2002[7]
353 Ireland 1.2 0.4 WHO 2012[10]
354 Italy 0.9 0.4 WHO 2012[10]
355 Ukraine 5.2 0.3 UNODC 2000[11]
356 Estonia 5.2 0.3 WHO 2012[10]
357 Belgium 1.7 0.3 WHO 2012[10]
358 Finland 2.2 0.3 WHO 2012[10]
359 Lithuania 6.6 0.2 WHO 2012[10]
360 Bulgaria 2.0 0.2 WHO 2012[10]
361 Georgia 4.3 0.2 WHO 2012[10]
362 Denmark 0.9 0.2 WHO 2012[10]
363 France 1.1 0.2 WHO 2012[10]
364 Netherlands 1.1 0.2 WHO 2012[10]
365 Sweden 1.0 0.2 WHO 2012[10]
366 Slovakia 1.5 0.2 WHO 2012[10]
367 Austria 0.6 0.2 WHO 2012[10]
368 Latvia 3.1 0.2 WHO 2012[10]
369 Spain 0.8 0.1 WHO 2012[10]
370 Hungary 1.3 0.1 WHO 2012[10]
371 Czech Republic 1.7 0.1 WHO 2012[10]
372 Germany 0.8 0.1 WHO 2012[10]
373 Slovenia 0.7 0.1 WHO 2012[10]
374 Romania 2.0 0.0 WHO 2012[10]
375 United Kingdom 1.2 0.0 WHO2012 [10]
376 Norway 0.6 0.0 WHO 2012[10]
377 Poland 1.1 0.0 WHO 2012[10]
378 \end{verbatim}
379 \end{codeoutput}
380 \end{codecell}
381 Let's just compare US, Canada, and UK:
382
383 \begin{codecell}
384 \begin{codeinput}
385 \begin{lstlisting}
386 select = data.ix[['United States', 'Canada', 'United Kingdom']]
387 plot_percapita(select)
388 \end{lstlisting}
389 \end{codeinput}
390 \begin{codeoutput}
391 \begin{center}
392 \includegraphics[width=0.7\textwidth]{Gun_Data_orig_files/Gun_Data_orig_fig_02.png}
393 \par
394 \end{center}
395 \end{codeoutput}
396 \end{codecell}
397 Normalize to the US numbers (inverse)
398
399 \begin{codecell}
400 \begin{codeinput}
401 \begin{lstlisting}
402 select['Homicides'] = select['Homicides']['United States'] / select['Homicides']
403 select['Gun Homicides'] = select['Gun Homicides']['United States'] / select['Gun Homicides']
404 display_relevant(select)
405 \end{lstlisting}
406 \end{codeinput}
407 \begin{codeoutput}
408 \begin{verbatim}
409 Homicides Gun Homicides Gun Data Source
410 United States 1.0 1.0 OAS 2012[5][6]
411 Canada 2.6 4.9 Krug 1998[13]
412 United Kingdom 3.5 92.5 WHO2012 [10]
413 \end{verbatim}
414 \end{codeoutput}
415 \end{codecell}
416 So, you are 2.6 times more likely to be killed in the US than Canada,
417 and 3.5 times more likely than in the UK. That's bad, but not extreme.
418
419 However, you are 4.9 times more likely to be killed \emph{with a gun} in
420 the US than Canada, and almost 100 times more likely than in the UK.
421 That is pretty extreme.
422
423 Countries represented:
424
425 \begin{codecell}
426 \begin{codeinput}
427 \begin{lstlisting}
428 for country in data.index:
429 print country
430 \end{lstlisting}
431 \end{codeinput}
432 \begin{codeoutput}
433 \begin{verbatim}
434 El Salvador
435 Jamaica
436 Honduras
437 Guatemala
438 Colombia
439 Brazil
440 Panama
441 Mexico
442 Paraguay
443 Nicaragua
444 United States
445 Costa Rica
446 Uruguay
447 Argentina
448 Barbados
449 Montenegro
450 Peru
451 Moldova
452 Israel
453 India
454 Canada
455 Serbia
456 Luxembourg
457 Greece
458 Uzbekistan
459 Croatia
460 Kyrgyzstan
461 Switzerland
462 Malta
463 Portugal
464 Belarus
465 Ireland
466 Italy
467 Kuwait
468 Ukraine
469 Estonia
470 Belgium
471 Finland
472 Lithuania
473 Cyprus
474 Bulgaria
475 Georgia
476 Denmark
477 France
478 Netherlands
479 Sweden
480 Slovakia
481 Qatar
482 Austria
483 Latvia
484 New Zealand
485 Spain
486 Hungary
487 Czech Republic
488 Hong Kong
489 Australia
490 Singapore
491 Chile
492 Germany
493 Slovenia
494 Romania
495 Azerbaijan
496 South Korea
497 United Kingdom
498 Norway
499 Japan
500 Poland
501 Mauritius
502 \end{verbatim}
503 \end{codeoutput}
504 \end{codecell}
505 \end{document}
@@ -0,0 +1,460 b''
1 # XKCD plots in Matplotlib
2
3 This notebook originally appeared as a blog post at [Pythonic Perambulations](http://jakevdp.github.com/blog/2012/10/07/xkcd-style-plots-in-matplotlib/) by Jake Vanderplas.
4
5 One of the problems I've had with typical matplotlib figures is that everything in them is so precise, so perfect. For an example of what I mean, take a look at this figure:
6
7 <div class="highlight"><pre><span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">Image</span>
8 <span class="n">Image</span><span class="p">(</span><span class="s">&#39;http://jakevdp.github.com/figures/xkcd_version.png&#39;</span><span class="p">)</span>
9 </pre></div>
10
11
12 <pre>
13 <IPython.core.display.Image at 0x2fef710>
14 </pre>
15
16
17 Sometimes when showing schematic plots, this is the type of figure I want to display. But drawing it by hand is a pain: I'd rather just use matplotlib. The problem is, matplotlib is a bit too precise. Attempting to duplicate this figure in matplotlib leads to something like this:
18
19 <div class="highlight"><pre><span class="n">Image</span><span class="p">(</span><span class="s">&#39;http://jakevdp.github.com/figures/mpl_version.png&#39;</span><span class="p">)</span>
20 </pre></div>
21
22
23 <pre>
24 <IPython.core.display.Image at 0x2fef0d0>
25 </pre>
26
27
28 It just doesn't have the same effect. Matplotlib is great for scientific plots, but sometimes you don't want to be so precise.
29
30 This subject has recently come up on the matplotlib mailing list, and started some interesting discussions.
31 As near as I can tell, this started with a thread on a
32 [mathematica list](http://mathematica.stackexchange.com/questions/11350/xkcd-style-graphs)
33 which prompted a thread on the [matplotlib list](http://matplotlib.1069221.n5.nabble.com/XKCD-style-graphs-td39226.html)
34 wondering if the same could be done in matplotlib.
35
36 Damon McDougall offered a quick
37 [solution](http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg25499.html)
38 which was improved by Fernando Perez in [this notebook](http://nbviewer.ipython.org/3835181/), and
39 within a few days there was a [matplotlib pull request](https://github.com/matplotlib/matplotlib/pull/1329) offering a very general
40 way to create sketch-style plots in matplotlib. Only a few days from a cool idea to a
41 working implementation: this is one of the most incredible aspects of package development on github.
42
43 The pull request looks really nice, but will likely not be included in a released version of
44 matplotlib until at least version 1.3. In the mean-time, I wanted a way to play around with
45 these types of plots in a way that is compatible with the current release of matplotlib. To do that,
46 I created the following code:
47
48 ## The Code: XKCDify
49
50 XKCDify will take a matplotlib ``Axes`` instance, and modify the plot elements in-place to make
51 them look hand-drawn.
52 First off, we'll need to make sure we have the Humor Sans font.
53 It can be downloaded using the command below.
54
55 Next we'll create a function ``xkcd_line`` to add jitter to lines. We want this to be very general, so
56 we'll normalize the size of the lines, and use a low-pass filter to add correlated noise, perpendicular
57 to the direction of the line. There are a few parameters for this filter that can be tweaked to
58 customize the appearance of the jitter.
59
60 Finally, we'll create a function which accepts a matplotlib axis, and calls ``xkcd_line`` on
61 all lines in the axis. Additionally, we'll switch the font of all text in the axes, and add
62 some background lines for a nice effect where lines cross. We'll also draw axes, and move the
63 axes labels and titles to the appropriate location.
64
65 <div class="highlight"><pre><span class="sd">&quot;&quot;&quot;</span>
66 <span class="sd">XKCD plot generator</span>
67 <span class="sd">-------------------</span>
68 <span class="sd">Author: Jake Vanderplas</span>
69
70 <span class="sd">This is a script that will take any matplotlib line diagram, and convert it</span>
71 <span class="sd">to an XKCD-style plot. It will work for plots with line &amp; text elements,</span>
72 <span class="sd">including axes labels and titles (but not axes tick labels).</span>
73
74 <span class="sd">The idea for this comes from work by Damon McDougall</span>
75 <span class="sd"> http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg25499.html</span>
76 <span class="sd">&quot;&quot;&quot;</span>
77 <span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
78 <span class="kn">import</span> <span class="nn">pylab</span> <span class="kn">as</span> <span class="nn">pl</span>
79 <span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">interpolate</span><span class="p">,</span> <span class="n">signal</span>
80 <span class="kn">import</span> <span class="nn">matplotlib.font_manager</span> <span class="kn">as</span> <span class="nn">fm</span>
81
82
83 <span class="c"># We need a special font for the code below. It can be downloaded this way:</span>
84 <span class="kn">import</span> <span class="nn">os</span>
85 <span class="kn">import</span> <span class="nn">urllib2</span>
86 <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s">&#39;Humor-Sans.ttf&#39;</span><span class="p">):</span>
87 <span class="n">fhandle</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="s">&#39;http://antiyawn.com/uploads/Humor-Sans.ttf&#39;</span><span class="p">)</span>
88 <span class="nb">open</span><span class="p">(</span><span class="s">&#39;Humor-Sans.ttf&#39;</span><span class="p">,</span> <span class="s">&#39;wb&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fhandle</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
89
90
91 <span class="k">def</span> <span class="nf">xkcd_line</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">xlim</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">ylim</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
92 <span class="n">mag</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">f1</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">f2</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span> <span class="n">f3</span><span class="o">=</span><span class="mi">15</span><span class="p">):</span>
93 <span class="sd">&quot;&quot;&quot;</span>
94 <span class="sd"> Mimic a hand-drawn line from (x, y) data</span>
95
96 <span class="sd"> Parameters</span>
97 <span class="sd"> ----------</span>
98 <span class="sd"> x, y : array_like</span>
99 <span class="sd"> arrays to be modified</span>
100 <span class="sd"> xlim, ylim : data range</span>
101 <span class="sd"> the assumed plot range for the modification. If not specified,</span>
102 <span class="sd"> they will be guessed from the data</span>
103 <span class="sd"> mag : float</span>
104 <span class="sd"> magnitude of distortions</span>
105 <span class="sd"> f1, f2, f3 : int, float, int</span>
106 <span class="sd"> filtering parameters. f1 gives the size of the window, f2 gives</span>
107 <span class="sd"> the high-frequency cutoff, f3 gives the size of the filter</span>
108 <span class="sd"> </span>
109 <span class="sd"> Returns</span>
110 <span class="sd"> -------</span>
111 <span class="sd"> x, y : ndarrays</span>
112 <span class="sd"> The modified lines</span>
113 <span class="sd"> &quot;&quot;&quot;</span>
114 <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
115 <span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
116
117 <span class="c"># get limits for rescaling</span>
118 <span class="k">if</span> <span class="n">xlim</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
119 <span class="n">xlim</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">min</span><span class="p">(),</span> <span class="n">x</span><span class="o">.</span><span class="n">max</span><span class="p">())</span>
120 <span class="k">if</span> <span class="n">ylim</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
121 <span class="n">ylim</span> <span class="o">=</span> <span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">min</span><span class="p">(),</span> <span class="n">y</span><span class="o">.</span><span class="n">max</span><span class="p">())</span>
122
123 <span class="k">if</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
124 <span class="n">xlim</span> <span class="o">=</span> <span class="n">ylim</span>
125
126 <span class="k">if</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
127 <span class="n">ylim</span> <span class="o">=</span> <span class="n">xlim</span>
128
129 <span class="c"># scale the data</span>
130 <span class="n">x_scaled</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">*</span> <span class="mf">1.</span> <span class="o">/</span> <span class="p">(</span><span class="n">xlim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
131 <span class="n">y_scaled</span> <span class="o">=</span> <span class="p">(</span><span class="n">y</span> <span class="o">-</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">*</span> <span class="mf">1.</span> <span class="o">/</span> <span class="p">(</span><span class="n">ylim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
132
133 <span class="c"># compute the total distance along the path</span>
134 <span class="n">dx</span> <span class="o">=</span> <span class="n">x_scaled</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="o">-</span> <span class="n">x_scaled</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
135 <span class="n">dy</span> <span class="o">=</span> <span class="n">y_scaled</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="o">-</span> <span class="n">y_scaled</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
136 <span class="n">dist_tot</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">dx</span> <span class="o">*</span> <span class="n">dx</span> <span class="o">+</span> <span class="n">dy</span> <span class="o">*</span> <span class="n">dy</span><span class="p">))</span>
137
138 <span class="c"># number of interpolated points is proportional to the distance</span>
139 <span class="n">Nu</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mi">200</span> <span class="o">*</span> <span class="n">dist_tot</span><span class="p">)</span>
140 <span class="n">u</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">Nu</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mf">1.</span> <span class="o">/</span> <span class="p">(</span><span class="n">Nu</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
141
142 <span class="c"># interpolate curve at sampled points</span>
143 <span class="n">k</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
144 <span class="n">res</span> <span class="o">=</span> <span class="n">interpolate</span><span class="o">.</span><span class="n">splprep</span><span class="p">([</span><span class="n">x_scaled</span><span class="p">,</span> <span class="n">y_scaled</span><span class="p">],</span> <span class="n">s</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="n">k</span><span class="p">)</span>
145 <span class="n">x_int</span><span class="p">,</span> <span class="n">y_int</span> <span class="o">=</span> <span class="n">interpolate</span><span class="o">.</span><span class="n">splev</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">res</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
146
147 <span class="c"># we&#39;ll perturb perpendicular to the drawn line</span>
148 <span class="n">dx</span> <span class="o">=</span> <span class="n">x_int</span><span class="p">[</span><span class="mi">2</span><span class="p">:]</span> <span class="o">-</span> <span class="n">x_int</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span>
149 <span class="n">dy</span> <span class="o">=</span> <span class="n">y_int</span><span class="p">[</span><span class="mi">2</span><span class="p">:]</span> <span class="o">-</span> <span class="n">y_int</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span>
150 <span class="n">dist</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">dx</span> <span class="o">*</span> <span class="n">dx</span> <span class="o">+</span> <span class="n">dy</span> <span class="o">*</span> <span class="n">dy</span><span class="p">)</span>
151
152 <span class="c"># create a filtered perturbation</span>
153 <span class="n">coeffs</span> <span class="o">=</span> <span class="n">mag</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mf">0.01</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">x_int</span><span class="p">)</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span>
154 <span class="n">b</span> <span class="o">=</span> <span class="n">signal</span><span class="o">.</span><span class="n">firwin</span><span class="p">(</span><span class="n">f1</span><span class="p">,</span> <span class="n">f2</span> <span class="o">*</span> <span class="n">dist_tot</span><span class="p">,</span> <span class="n">window</span><span class="o">=</span><span class="p">(</span><span class="s">&#39;kaiser&#39;</span><span class="p">,</span> <span class="n">f3</span><span class="p">))</span>
155 <span class="n">response</span> <span class="o">=</span> <span class="n">signal</span><span class="o">.</span><span class="n">lfilter</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">coeffs</span><span class="p">)</span>
156
157 <span class="n">x_int</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="n">response</span> <span class="o">*</span> <span class="n">dy</span> <span class="o">/</span> <span class="n">dist</span>
158 <span class="n">y_int</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="n">response</span> <span class="o">*</span> <span class="n">dx</span> <span class="o">/</span> <span class="n">dist</span>
159
160 <span class="c"># un-scale data</span>
161 <span class="n">x_int</span> <span class="o">=</span> <span class="n">x_int</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">xlim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
162 <span class="n">y_int</span> <span class="o">=</span> <span class="n">y_int</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">ylim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
163
164 <span class="k">return</span> <span class="n">x_int</span><span class="p">,</span> <span class="n">y_int</span>
165
166
167 <span class="k">def</span> <span class="nf">XKCDify</span><span class="p">(</span><span class="n">ax</span><span class="p">,</span> <span class="n">mag</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span>
168 <span class="n">f1</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span> <span class="n">f2</span><span class="o">=</span><span class="mf">0.01</span><span class="p">,</span> <span class="n">f3</span><span class="o">=</span><span class="mi">15</span><span class="p">,</span>
169 <span class="n">bgcolor</span><span class="o">=</span><span class="s">&#39;w&#39;</span><span class="p">,</span>
170 <span class="n">xaxis_loc</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
171 <span class="n">yaxis_loc</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
172 <span class="n">xaxis_arrow</span><span class="o">=</span><span class="s">&#39;+&#39;</span><span class="p">,</span>
173 <span class="n">yaxis_arrow</span><span class="o">=</span><span class="s">&#39;+&#39;</span><span class="p">,</span>
174 <span class="n">ax_extend</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>
175 <span class="n">expand_axes</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
176 <span class="sd">&quot;&quot;&quot;Make axis look hand-drawn</span>
177
178 <span class="sd"> This adjusts all lines, text, legends, and axes in the figure to look</span>
179 <span class="sd"> like xkcd plots. Other plot elements are not modified.</span>
180 <span class="sd"> </span>
181 <span class="sd"> Parameters</span>
182 <span class="sd"> ----------</span>
183 <span class="sd"> ax : Axes instance</span>
184 <span class="sd"> the axes to be modified.</span>
185 <span class="sd"> mag : float</span>
186 <span class="sd"> the magnitude of the distortion</span>
187 <span class="sd"> f1, f2, f3 : int, float, int</span>
188 <span class="sd"> filtering parameters. f1 gives the size of the window, f2 gives</span>
189 <span class="sd"> the high-frequency cutoff, f3 gives the size of the filter</span>
190 <span class="sd"> xaxis_loc, yaxis_log : float</span>
191 <span class="sd"> The locations to draw the x and y axes. If not specified, they</span>
192 <span class="sd"> will be drawn from the bottom left of the plot</span>
193 <span class="sd"> xaxis_arrow, yaxis_arrow : str</span>
194 <span class="sd"> where to draw arrows on the x/y axes. Options are &#39;+&#39;, &#39;-&#39;, &#39;+-&#39;, or &#39;&#39;</span>
195 <span class="sd"> ax_extend : float</span>
196 <span class="sd"> How far (fractionally) to extend the drawn axes beyond the original</span>
197 <span class="sd"> axes limits</span>
198 <span class="sd"> expand_axes : bool</span>
199 <span class="sd"> if True, then expand axes to fill the figure (useful if there is only</span>
200 <span class="sd"> a single axes in the figure)</span>
201 <span class="sd"> &quot;&quot;&quot;</span>
202 <span class="c"># Get axes aspect</span>
203 <span class="n">ext</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">get_window_extent</span><span class="p">()</span><span class="o">.</span><span class="n">extents</span>
204 <span class="n">aspect</span> <span class="o">=</span> <span class="p">(</span><span class="n">ext</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">-</span> <span class="n">ext</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">/</span> <span class="p">(</span><span class="n">ext</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">-</span> <span class="n">ext</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
205
206 <span class="n">xlim</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">get_xlim</span><span class="p">()</span>
207 <span class="n">ylim</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">get_ylim</span><span class="p">()</span>
208
209 <span class="n">xspan</span> <span class="o">=</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
210 <span class="n">yspan</span> <span class="o">=</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
211
212 <span class="n">xax_lim</span> <span class="o">=</span> <span class="p">(</span><span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">ax_extend</span> <span class="o">*</span> <span class="n">xspan</span><span class="p">,</span>
213 <span class="n">xlim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">ax_extend</span> <span class="o">*</span> <span class="n">xspan</span><span class="p">)</span>
214 <span class="n">yax_lim</span> <span class="o">=</span> <span class="p">(</span><span class="n">ylim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">ax_extend</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">,</span>
215 <span class="n">ylim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">ax_extend</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">)</span>
216
217 <span class="k">if</span> <span class="n">xaxis_loc</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
218 <span class="n">xaxis_loc</span> <span class="o">=</span> <span class="n">ylim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
219
220 <span class="k">if</span> <span class="n">yaxis_loc</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
221 <span class="n">yaxis_loc</span> <span class="o">=</span> <span class="n">xlim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
222
223 <span class="c"># Draw axes</span>
224 <span class="n">xaxis</span> <span class="o">=</span> <span class="n">pl</span><span class="o">.</span><span class="n">Line2D</span><span class="p">([</span><span class="n">xax_lim</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">xax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">]],</span> <span class="p">[</span><span class="n">xaxis_loc</span><span class="p">,</span> <span class="n">xaxis_loc</span><span class="p">],</span>
225 <span class="n">linestyle</span><span class="o">=</span><span class="s">&#39;-&#39;</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s">&#39;k&#39;</span><span class="p">)</span>
226 <span class="n">yaxis</span> <span class="o">=</span> <span class="n">pl</span><span class="o">.</span><span class="n">Line2D</span><span class="p">([</span><span class="n">yaxis_loc</span><span class="p">,</span> <span class="n">yaxis_loc</span><span class="p">],</span> <span class="p">[</span><span class="n">yax_lim</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">yax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">]],</span>
227 <span class="n">linestyle</span><span class="o">=</span><span class="s">&#39;-&#39;</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s">&#39;k&#39;</span><span class="p">)</span>
228
229 <span class="c"># Label axes3, 0.5, &#39;hello&#39;, fontsize=14)</span>
230 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="n">xax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">xaxis_loc</span> <span class="o">-</span> <span class="mf">0.02</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">,</span> <span class="n">ax</span><span class="o">.</span><span class="n">get_xlabel</span><span class="p">(),</span>
231 <span class="n">fontsize</span><span class="o">=</span><span class="mi">14</span><span class="p">,</span> <span class="n">ha</span><span class="o">=</span><span class="s">&#39;right&#39;</span><span class="p">,</span> <span class="n">va</span><span class="o">=</span><span class="s">&#39;top&#39;</span><span class="p">,</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">12</span><span class="p">)</span>
232 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="n">yaxis_loc</span> <span class="o">-</span> <span class="mf">0.02</span> <span class="o">*</span> <span class="n">xspan</span><span class="p">,</span> <span class="n">yax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">ax</span><span class="o">.</span><span class="n">get_ylabel</span><span class="p">(),</span>
233 <span class="n">fontsize</span><span class="o">=</span><span class="mi">14</span><span class="p">,</span> <span class="n">ha</span><span class="o">=</span><span class="s">&#39;right&#39;</span><span class="p">,</span> <span class="n">va</span><span class="o">=</span><span class="s">&#39;top&#39;</span><span class="p">,</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">78</span><span class="p">)</span>
234 <span class="n">ax</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">)</span>
235 <span class="n">ax</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">)</span>
236
237 <span class="c"># Add title</span>
238 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">xax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">xax_lim</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">yax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
239 <span class="n">ax</span><span class="o">.</span><span class="n">get_title</span><span class="p">(),</span>
240 <span class="n">ha</span><span class="o">=</span><span class="s">&#39;center&#39;</span><span class="p">,</span> <span class="n">va</span><span class="o">=</span><span class="s">&#39;bottom&#39;</span><span class="p">,</span> <span class="n">fontsize</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>
241 <span class="n">ax</span><span class="o">.</span><span class="n">set_title</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">)</span>
242
243 <span class="n">Nlines</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">ax</span><span class="o">.</span><span class="n">lines</span><span class="p">)</span>
244 <span class="n">lines</span> <span class="o">=</span> <span class="p">[</span><span class="n">xaxis</span><span class="p">,</span> <span class="n">yaxis</span><span class="p">]</span> <span class="o">+</span> <span class="p">[</span><span class="n">ax</span><span class="o">.</span><span class="n">lines</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">Nlines</span><span class="p">)]</span>
245
246 <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
247 <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">get_data</span><span class="p">()</span>
248
249 <span class="n">x_int</span><span class="p">,</span> <span class="n">y_int</span> <span class="o">=</span> <span class="n">xkcd_line</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">xlim</span><span class="p">,</span> <span class="n">ylim</span><span class="p">,</span>
250 <span class="n">mag</span><span class="p">,</span> <span class="n">f1</span><span class="p">,</span> <span class="n">f2</span><span class="p">,</span> <span class="n">f3</span><span class="p">)</span>
251
252 <span class="c"># create foreground and background line</span>
253 <span class="n">lw</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">get_linewidth</span><span class="p">()</span>
254 <span class="n">line</span><span class="o">.</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">lw</span><span class="p">)</span>
255 <span class="n">line</span><span class="o">.</span><span class="n">set_data</span><span class="p">(</span><span class="n">x_int</span><span class="p">,</span> <span class="n">y_int</span><span class="p">)</span>
256
257 <span class="c"># don&#39;t add background line for axes</span>
258 <span class="k">if</span> <span class="p">(</span><span class="n">line</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">xaxis</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">line</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">yaxis</span><span class="p">):</span>
259 <span class="n">line_bg</span> <span class="o">=</span> <span class="n">pl</span><span class="o">.</span><span class="n">Line2D</span><span class="p">(</span><span class="n">x_int</span><span class="p">,</span> <span class="n">y_int</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="n">bgcolor</span><span class="p">,</span>
260 <span class="n">linewidth</span><span class="o">=</span><span class="mi">8</span> <span class="o">*</span> <span class="n">lw</span><span class="p">)</span>
261
262 <span class="n">ax</span><span class="o">.</span><span class="n">add_line</span><span class="p">(</span><span class="n">line_bg</span><span class="p">)</span>
263 <span class="n">ax</span><span class="o">.</span><span class="n">add_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
264
265 <span class="c"># Draw arrow-heads at the end of axes lines</span>
266 <span class="n">arr1</span> <span class="o">=</span> <span class="mf">0.03</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">])</span>
267 <span class="n">arr2</span> <span class="o">=</span> <span class="mf">0.02</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
268
269 <span class="n">arr1</span><span class="p">[::</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mf">0.005</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
270 <span class="n">arr2</span><span class="p">[::</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mf">0.005</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
271
272 <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">xaxis</span><span class="o">.</span><span class="n">get_data</span><span class="p">()</span>
273 <span class="k">if</span> <span class="s">&#39;+&#39;</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">xaxis_arrow</span><span class="p">):</span>
274 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">arr1</span> <span class="o">*</span> <span class="n">xspan</span> <span class="o">*</span> <span class="n">aspect</span><span class="p">,</span>
275 <span class="n">y</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">arr2</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">,</span>
276 <span class="n">color</span><span class="o">=</span><span class="s">&#39;k&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
277 <span class="k">if</span> <span class="s">&#39;-&#39;</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">xaxis_arrow</span><span class="p">):</span>
278 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">arr1</span> <span class="o">*</span> <span class="n">xspan</span> <span class="o">*</span> <span class="n">aspect</span><span class="p">,</span>
279 <span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">arr2</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">,</span>
280 <span class="n">color</span><span class="o">=</span><span class="s">&#39;k&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
281
282 <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">yaxis</span><span class="o">.</span><span class="n">get_data</span><span class="p">()</span>
283 <span class="k">if</span> <span class="s">&#39;+&#39;</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">yaxis_arrow</span><span class="p">):</span>
284 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">arr2</span> <span class="o">*</span> <span class="n">xspan</span> <span class="o">*</span> <span class="n">aspect</span><span class="p">,</span>
285 <span class="n">y</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">arr1</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">,</span>
286 <span class="n">color</span><span class="o">=</span><span class="s">&#39;k&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
287 <span class="k">if</span> <span class="s">&#39;-&#39;</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">yaxis_arrow</span><span class="p">):</span>
288 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">arr2</span> <span class="o">*</span> <span class="n">xspan</span> <span class="o">*</span> <span class="n">aspect</span><span class="p">,</span>
289 <span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">arr1</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">,</span>
290 <span class="n">color</span><span class="o">=</span><span class="s">&#39;k&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
291
292 <span class="c"># Change all the fonts to humor-sans.</span>
293 <span class="n">prop</span> <span class="o">=</span> <span class="n">fm</span><span class="o">.</span><span class="n">FontProperties</span><span class="p">(</span><span class="n">fname</span><span class="o">=</span><span class="s">&#39;Humor-Sans.ttf&#39;</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>
294 <span class="k">for</span> <span class="n">text</span> <span class="ow">in</span> <span class="n">ax</span><span class="o">.</span><span class="n">texts</span><span class="p">:</span>
295 <span class="n">text</span><span class="o">.</span><span class="n">set_fontproperties</span><span class="p">(</span><span class="n">prop</span><span class="p">)</span>
296
297 <span class="c"># modify legend</span>
298 <span class="n">leg</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">get_legend</span><span class="p">()</span>
299 <span class="k">if</span> <span class="n">leg</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
300 <span class="n">leg</span><span class="o">.</span><span class="n">set_frame_on</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
301
302 <span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">leg</span><span class="o">.</span><span class="n">get_children</span><span class="p">():</span>
303 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">child</span><span class="p">,</span> <span class="n">pl</span><span class="o">.</span><span class="n">Line2D</span><span class="p">):</span>
304 <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">child</span><span class="o">.</span><span class="n">get_data</span><span class="p">()</span>
305 <span class="n">child</span><span class="o">.</span><span class="n">set_data</span><span class="p">(</span><span class="n">xkcd_line</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">mag</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">f1</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">f2</span><span class="o">=</span><span class="mf">0.001</span><span class="p">))</span>
306 <span class="n">child</span><span class="o">.</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">child</span><span class="o">.</span><span class="n">get_linewidth</span><span class="p">())</span>
307 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">child</span><span class="p">,</span> <span class="n">pl</span><span class="o">.</span><span class="n">Text</span><span class="p">):</span>
308 <span class="n">child</span><span class="o">.</span><span class="n">set_fontproperties</span><span class="p">(</span><span class="n">prop</span><span class="p">)</span>
309
310 <span class="c"># Set the axis limits</span>
311 <span class="n">ax</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="n">xax_lim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="mf">0.1</span> <span class="o">*</span> <span class="n">xspan</span><span class="p">,</span>
312 <span class="n">xax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mf">0.1</span> <span class="o">*</span> <span class="n">xspan</span><span class="p">)</span>
313 <span class="n">ax</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="n">yax_lim</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="mf">0.1</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">,</span>
314 <span class="n">yax_lim</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mf">0.1</span> <span class="o">*</span> <span class="n">yspan</span><span class="p">)</span>
315
316 <span class="c"># adjust the axes</span>
317 <span class="n">ax</span><span class="o">.</span><span class="n">set_xticks</span><span class="p">([])</span>
318 <span class="n">ax</span><span class="o">.</span><span class="n">set_yticks</span><span class="p">([])</span>
319
320 <span class="k">if</span> <span class="n">expand_axes</span><span class="p">:</span>
321 <span class="n">ax</span><span class="o">.</span><span class="n">figure</span><span class="o">.</span><span class="n">set_facecolor</span><span class="p">(</span><span class="n">bgcolor</span><span class="p">)</span>
322 <span class="n">ax</span><span class="o">.</span><span class="n">set_axis_off</span><span class="p">()</span>
323 <span class="n">ax</span><span class="o">.</span><span class="n">set_position</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
324
325 <span class="k">return</span> <span class="n">ax</span>
326 </pre></div>
327
328
329
330 ## Testing it Out
331
332 Let's test this out with a simple plot. We'll plot two curves, add some labels,
333 and then call ``XKCDify`` on the axis. I think the results are pretty nice!
334
335 <div class="highlight"><pre><span class="o">%</span><span class="k">pylab</span> <span class="n">inline</span>
336 </pre></div>
337
338
339
340 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
341 For more information, type 'help(pylab)'.
342
343
344 <div class="highlight"><pre><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
345
346 <span class="n">ax</span> <span class="o">=</span> <span class="n">pylab</span><span class="o">.</span><span class="n">axes</span><span class="p">()</span>
347
348 <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
349 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="mf">0.1</span> <span class="o">*</span> <span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="mi">5</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span><span class="p">),</span> <span class="s">&#39;b&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&#39;damped sine&#39;</span><span class="p">)</span>
350 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">cos</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="mf">0.1</span> <span class="o">*</span> <span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="mi">5</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span><span class="p">),</span> <span class="s">&#39;r&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">&#39;damped cosine&#39;</span><span class="p">)</span>
351
352 <span class="n">ax</span><span class="o">.</span><span class="n">set_title</span><span class="p">(</span><span class="s">&#39;check it out!&#39;</span><span class="p">)</span>
353 <span class="n">ax</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s">&#39;x label&#39;</span><span class="p">)</span>
354 <span class="n">ax</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s">&#39;y label&#39;</span><span class="p">)</span>
355
356 <span class="n">ax</span><span class="o">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="s">&#39;lower right&#39;</span><span class="p">)</span>
357
358 <span class="n">ax</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
359 <span class="n">ax</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="o">-</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span>
360
361 <span class="c">#XKCDify the axes -- this operates in-place</span>
362 <span class="n">XKCDify</span><span class="p">(</span><span class="n">ax</span><span class="p">,</span> <span class="n">xaxis_loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">yaxis_loc</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span>
363 <span class="n">xaxis_arrow</span><span class="o">=</span><span class="s">&#39;+-&#39;</span><span class="p">,</span> <span class="n">yaxis_arrow</span><span class="o">=</span><span class="s">&#39;+-&#39;</span><span class="p">,</span>
364 <span class="n">expand_axes</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
365 </pre></div>
366
367
368 <pre>
369 <matplotlib.axes.AxesSubplot at 0x2fecbd0>
370 </pre>
371
372
373 ![](tests/ipynbref/XKCD_plots_orig_files/XKCD_plots_orig_fig_00.png)
374
375
376 ## Duplicating an XKCD Comic
377
378 Now let's see if we can use this to replicated an XKCD comic in matplotlib.
379 This is a good one:
380
381 <div class="highlight"><pre><span class="n">Image</span><span class="p">(</span><span class="s">&#39;http://imgs.xkcd.com/comics/front_door.png&#39;</span><span class="p">)</span>
382 </pre></div>
383
384
385 <pre>
386 <IPython.core.display.Image at 0x2ff4a10>
387 </pre>
388
389
390 With the new ``XKCDify`` function, this is relatively easy to replicate. The results
391 are not exactly identical, but I think it definitely gets the point across!
392
393 <div class="highlight"><pre><span class="c"># Some helper functions</span>
394 <span class="k">def</span> <span class="nf">norm</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">sigma</span><span class="p">):</span>
395 <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="n">x0</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">/</span> <span class="n">sigma</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span>
396
397 <span class="k">def</span> <span class="nf">sigmoid</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">x0</span><span class="p">,</span> <span class="n">alpha</span><span class="p">):</span>
398 <span class="k">return</span> <span class="mf">1.</span> <span class="o">/</span> <span class="p">(</span><span class="mf">1.</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span> <span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="n">x0</span><span class="p">)</span> <span class="o">/</span> <span class="n">alpha</span><span class="p">))</span>
399
400 <span class="c"># define the curves</span>
401 <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
402 <span class="n">y1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">norm</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mf">0.7</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">))</span> <span class="o">+</span> <span class="mf">0.2</span> <span class="o">*</span> <span class="p">(</span><span class="mf">1.5</span> <span class="o">-</span> <span class="n">sigmoid</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">))</span>
403
404 <span class="n">y2</span> <span class="o">=</span> <span class="mf">0.2</span> <span class="o">*</span> <span class="n">norm</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">)</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">norm</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mf">0.6</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">))</span> <span class="o">+</span> <span class="mf">0.1</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">sigmoid</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mf">0.75</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">))</span>
405
406 <span class="n">y3</span> <span class="o">=</span> <span class="mf">0.05</span> <span class="o">+</span> <span class="mf">1.4</span> <span class="o">*</span> <span class="n">norm</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mf">0.85</span><span class="p">,</span> <span class="mf">0.08</span><span class="p">)</span>
407 <span class="n">y3</span><span class="p">[</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mf">0.85</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.05</span> <span class="o">+</span> <span class="mf">1.4</span> <span class="o">*</span> <span class="n">norm</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mf">0.85</span><span class="p">],</span> <span class="mf">0.85</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">)</span>
408
409 <span class="c"># draw the curves</span>
410 <span class="n">ax</span> <span class="o">=</span> <span class="n">pl</span><span class="o">.</span><span class="n">axes</span><span class="p">()</span>
411 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y1</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="s">&#39;gray&#39;</span><span class="p">)</span>
412 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y2</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="s">&#39;blue&#39;</span><span class="p">)</span>
413 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y3</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="s">&#39;red&#39;</span><span class="p">)</span>
414
415 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.1</span><span class="p">,</span> <span class="s">&quot;Yard&quot;</span><span class="p">)</span>
416 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.1</span><span class="p">,</span> <span class="s">&quot;Steps&quot;</span><span class="p">)</span>
417 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.7</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.1</span><span class="p">,</span> <span class="s">&quot;Door&quot;</span><span class="p">)</span>
418 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.9</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.1</span><span class="p">,</span> <span class="s">&quot;Inside&quot;</span><span class="p">)</span>
419
420 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.05</span><span class="p">,</span> <span class="mf">1.1</span><span class="p">,</span> <span class="s">&quot;fear that</span><span class="se">\n</span><span class="s">there&#39;s</span><span class="se">\n</span><span class="s">something</span><span class="se">\n</span><span class="s">behind me&quot;</span><span class="p">)</span>
421 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">([</span><span class="mf">0.15</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">],</span> <span class="p">[</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">],</span> <span class="s">&#39;-k&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span>
422
423 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.25</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">,</span> <span class="s">&quot;forward</span><span class="se">\n</span><span class="s">speed&quot;</span><span class="p">)</span>
424 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">([</span><span class="mf">0.32</span><span class="p">,</span> <span class="mf">0.35</span><span class="p">],</span> <span class="p">[</span><span class="mf">0.75</span><span class="p">,</span> <span class="mf">0.35</span><span class="p">],</span> <span class="s">&#39;-k&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span>
425
426 <span class="n">ax</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="mf">0.9</span><span class="p">,</span> <span class="mf">0.4</span><span class="p">,</span> <span class="s">&quot;embarrassment&quot;</span><span class="p">)</span>
427 <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">([</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">],</span> <span class="p">[</span><span class="mf">0.55</span><span class="p">,</span> <span class="mf">1.05</span><span class="p">],</span> <span class="s">&#39;-k&#39;</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span>
428
429 <span class="n">ax</span><span class="o">.</span><span class="n">set_title</span><span class="p">(</span><span class="s">&quot;Walking back to my</span><span class="se">\n</span><span class="s">front door at night:&quot;</span><span class="p">)</span>
430
431 <span class="n">ax</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
432 <span class="n">ax</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mf">1.5</span><span class="p">)</span>
433
434 <span class="c"># modify all the axes elements in-place</span>
435 <span class="n">XKCDify</span><span class="p">(</span><span class="n">ax</span><span class="p">,</span> <span class="n">expand_axes</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
436 </pre></div>
437
438
439 <pre>
440 <matplotlib.axes.AxesSubplot at 0x2fef210>
441 </pre>
442
443
444 ![](tests/ipynbref/XKCD_plots_orig_files/XKCD_plots_orig_fig_01.png)
445
446
447 Pretty good for a couple hours's work!
448
449 I think the possibilities here are pretty limitless: this is going to be a hugely
450 useful and popular feature in matplotlib, especially when the sketch artist PR is mature
451 and part of the main package. I imagine using this style of plot for schematic figures
452 in presentations where the normal crisp matplotlib lines look a bit too "scientific".
453 I'm giving a few talks at the end of the month... maybe I'll even use some of
454 this code there.
455
456 This post was written entirely in an IPython Notebook: the notebook file is available for
457 download [here](http://jakevdp.github.com/downloads/notebooks/XKCD_plots.ipynb).
458 For more information on blogging with notebooks in octopress, see my
459 [previous post](http://jakevdp.github.com/blog/2012/10/04/blogging-with-ipython/)
460 on the subject.
This diff has been collapsed as it changes many lines, (626 lines changed) Show them Hide them
@@ -0,0 +1,626 b''
1 %% This file was auto-generated by IPython.
2 %% Conversion from the original notebook file:
3 %% tests/ipynbref/XKCD_plots.orig.ipynb
4 %%
5 \documentclass[11pt,english]{article}
6
7 %% This is the automatic preamble used by IPython. Note that it does *not*
8 %% include a documentclass declaration, that is added at runtime to the overall
9 %% document.
10
11 \usepackage{amsmath}
12 \usepackage{amssymb}
13 \usepackage{graphicx}
14 \usepackage{ucs}
15 \usepackage[utf8x]{inputenc}
16
17 % needed for markdown enumerations to work
18 \usepackage{enumerate}
19
20 % Slightly bigger margins than the latex defaults
21 \usepackage{geometry}
22 \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm}
23
24 % Define a few colors for use in code, links and cell shading
25 \usepackage{color}
26 \definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
27 \definecolor{darkorange}{rgb}{.71,0.21,0.01}
28 \definecolor{darkgreen}{rgb}{.12,.54,.11}
29 \definecolor{myteal}{rgb}{.26, .44, .56}
30 \definecolor{gray}{gray}{0.45}
31 \definecolor{lightgray}{gray}{.95}
32 \definecolor{mediumgray}{gray}{.8}
33 \definecolor{inputbackground}{rgb}{.95, .95, .85}
34 \definecolor{outputbackground}{rgb}{.95, .95, .95}
35 \definecolor{traceback}{rgb}{1, .95, .95}
36
37 % Framed environments for code cells (inputs, outputs, errors, ...). The
38 % various uses of \unskip (or not) at the end were fine-tuned by hand, so don't
39 % randomly change them unless you're sure of the effect it will have.
40 \usepackage{framed}
41
42 % remove extraneous vertical space in boxes
43 \setlength\fboxsep{0pt}
44
45 % codecell is the whole input+output set of blocks that a Code cell can
46 % generate.
47
48 % TODO: unfortunately, it seems that using a framed codecell environment breaks
49 % the ability of the frames inside of it to be broken across pages. This
50 % causes at least the problem of having lots of empty space at the bottom of
51 % pages as new frames are moved to the next page, and if a single frame is too
52 % long to fit on a page, will completely stop latex from compiling the
53 % document. So unless we figure out a solution to this, we'll have to instead
54 % leave the codecell env. as empty. I'm keeping the original codecell
55 % definition here (a thin vertical bar) for reference, in case we find a
56 % solution to the page break issue.
57
58 %% \newenvironment{codecell}{%
59 %% \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}%
60 %% \MakeFramed{\vspace{-0.5em}}}
61 %% {\unskip\endMakeFramed}
62
63 % For now, make this a no-op...
64 \newenvironment{codecell}{}
65
66 \newenvironment{codeinput}{%
67 \def\FrameCommand{\colorbox{inputbackground}}%
68 \MakeFramed{\advance\hsize-\width \FrameRestore}}
69 {\unskip\endMakeFramed}
70
71 \newenvironment{codeoutput}{%
72 \def\FrameCommand{\colorbox{outputbackground}}%
73 \vspace{-1.4em}
74 \MakeFramed{\advance\hsize-\width \FrameRestore}}
75 {\unskip\medskip\endMakeFramed}
76
77 \newenvironment{traceback}{%
78 \def\FrameCommand{\colorbox{traceback}}%
79 \MakeFramed{\advance\hsize-\width \FrameRestore}}
80 {\endMakeFramed}
81
82 % Use and configure listings package for nicely formatted code
83 \usepackage{listingsutf8}
84 \lstset{
85 language=python,
86 inputencoding=utf8x,
87 extendedchars=\true,
88 aboveskip=\smallskipamount,
89 belowskip=\smallskipamount,
90 xleftmargin=2mm,
91 breaklines=true,
92 basicstyle=\small \ttfamily,
93 showstringspaces=false,
94 keywordstyle=\color{blue}\bfseries,
95 commentstyle=\color{myteal},
96 stringstyle=\color{darkgreen},
97 identifierstyle=\color{darkorange},
98 columns=fullflexible, % tighter character kerning, like verb
99 }
100
101 % The hyperref package gives us a pdf with properly built
102 % internal navigation ('pdf bookmarks' for the table of contents,
103 % internal cross-reference links, web links for URLs, etc.)
104 \usepackage{hyperref}
105 \hypersetup{
106 breaklinks=true, % so long urls are correctly broken across lines
107 colorlinks=true,
108 urlcolor=blue,
109 linkcolor=darkorange,
110 citecolor=darkgreen,
111 }
112
113 % hardcode size of all verbatim environments to be a bit smaller
114 \makeatletter
115 \g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt
116 \makeatother
117
118 % Prevent overflowing lines due to urls and other hard-to-break entities.
119 \sloppy
120
121 \begin{document}
122
123 \section{XKCD plots in Matplotlib}
124 This notebook originally appeared as a blog post at
125 \href{http://jakevdp.github.com/blog/2012/10/07/xkcd-style-plots-in-matplotlib/}{Pythonic
126 Perambulations} by Jake Vanderplas.
127
128 One of the problems I've had with typical matplotlib figures is that
129 everything in them is so precise, so perfect. For an example of what I
130 mean, take a look at this figure:
131
132 \begin{codecell}
133 \begin{codeinput}
134 \begin{lstlisting}
135 from IPython.display import Image
136 Image('http://jakevdp.github.com/figures/xkcd_version.png')
137 \end{lstlisting}
138 \end{codeinput}
139 \begin{codeoutput}
140 \begin{verbatim}
141 <IPython.core.display.Image at 0x2fef710>
142 \end{verbatim}
143 \end{codeoutput}
144 \end{codecell}
145 Sometimes when showing schematic plots, this is the type of figure I
146 want to display. But drawing it by hand is a pain: I'd rather just use
147 matplotlib. The problem is, matplotlib is a bit too precise. Attempting
148 to duplicate this figure in matplotlib leads to something like this:
149
150 \begin{codecell}
151 \begin{codeinput}
152 \begin{lstlisting}
153 Image('http://jakevdp.github.com/figures/mpl_version.png')
154 \end{lstlisting}
155 \end{codeinput}
156 \begin{codeoutput}
157 \begin{verbatim}
158 <IPython.core.display.Image at 0x2fef0d0>
159 \end{verbatim}
160 \end{codeoutput}
161 \end{codecell}
162 It just doesn't have the same effect. Matplotlib is great for scientific
163 plots, but sometimes you don't want to be so precise.
164
165 This subject has recently come up on the matplotlib mailing list, and
166 started some interesting discussions. As near as I can tell, this
167 started with a thread on a
168 \href{http://mathematica.stackexchange.com/questions/11350/xkcd-style-graphs}{mathematica
169 list} which prompted a thread on the
170 \href{http://matplotlib.1069221.n5.nabble.com/XKCD-style-graphs-td39226.html}{matplotlib
171 list} wondering if the same could be done in matplotlib.
172
173 Damon McDougall offered a quick
174 \href{http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg25499.html}{solution}
175 which was improved by Fernando Perez in
176 \href{http://nbviewer.ipython.org/3835181/}{this notebook}, and within a
177 few days there was a
178 \href{https://github.com/matplotlib/matplotlib/pull/1329}{matplotlib
179 pull request} offering a very general way to create sketch-style plots
180 in matplotlib. Only a few days from a cool idea to a working
181 implementation: this is one of the most incredible aspects of package
182 development on github.
183
184 The pull request looks really nice, but will likely not be included in a
185 released version of matplotlib until at least version 1.3. In the
186 mean-time, I wanted a way to play around with these types of plots in a
187 way that is compatible with the current release of matplotlib. To do
188 that, I created the following code:
189
190 \subsection{The Code: XKCDify}
191 XKCDify will take a matplotlib \texttt{Axes} instance, and modify the
192 plot elements in-place to make them look hand-drawn. First off, we'll
193 need to make sure we have the Humor Sans font. It can be downloaded
194 using the command below.
195
196 Next we'll create a function \texttt{xkcd\_line} to add jitter to lines.
197 We want this to be very general, so we'll normalize the size of the
198 lines, and use a low-pass filter to add correlated noise, perpendicular
199 to the direction of the line. There are a few parameters for this filter
200 that can be tweaked to customize the appearance of the jitter.
201
202 Finally, we'll create a function which accepts a matplotlib axis, and
203 calls \texttt{xkcd\_line} on all lines in the axis. Additionally, we'll
204 switch the font of all text in the axes, and add some background lines
205 for a nice effect where lines cross. We'll also draw axes, and move the
206 axes labels and titles to the appropriate location.
207
208 \begin{codecell}
209 \begin{codeinput}
210 \begin{lstlisting}
211 """
212 XKCD plot generator
213 -------------------
214 Author: Jake Vanderplas
215
216 This is a script that will take any matplotlib line diagram, and convert it
217 to an XKCD-style plot. It will work for plots with line & text elements,
218 including axes labels and titles (but not axes tick labels).
219
220 The idea for this comes from work by Damon McDougall
221 http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg25499.html
222 """
223 import numpy as np
224 import pylab as pl
225 from scipy import interpolate, signal
226 import matplotlib.font_manager as fm
227
228
229 # We need a special font for the code below. It can be downloaded this way:
230 import os
231 import urllib2
232 if not os.path.exists('Humor-Sans.ttf'):
233 fhandle = urllib2.urlopen('http://antiyawn.com/uploads/Humor-Sans.ttf')
234 open('Humor-Sans.ttf', 'wb').write(fhandle.read())
235
236
237 def xkcd_line(x, y, xlim=None, ylim=None,
238 mag=1.0, f1=30, f2=0.05, f3=15):
239 """
240 Mimic a hand-drawn line from (x, y) data
241
242 Parameters
243 ----------
244 x, y : array_like
245 arrays to be modified
246 xlim, ylim : data range
247 the assumed plot range for the modification. If not specified,
248 they will be guessed from the data
249 mag : float
250 magnitude of distortions
251 f1, f2, f3 : int, float, int
252 filtering parameters. f1 gives the size of the window, f2 gives
253 the high-frequency cutoff, f3 gives the size of the filter
254
255 Returns
256 -------
257 x, y : ndarrays
258 The modified lines
259 """
260 x = np.asarray(x)
261 y = np.asarray(y)
262
263 # get limits for rescaling
264 if xlim is None:
265 xlim = (x.min(), x.max())
266 if ylim is None:
267 ylim = (y.min(), y.max())
268
269 if xlim[1] == xlim[0]:
270 xlim = ylim
271
272 if ylim[1] == ylim[0]:
273 ylim = xlim
274
275 # scale the data
276 x_scaled = (x - xlim[0]) * 1. / (xlim[1] - xlim[0])
277 y_scaled = (y - ylim[0]) * 1. / (ylim[1] - ylim[0])
278
279 # compute the total distance along the path
280 dx = x_scaled[1:] - x_scaled[:-1]
281 dy = y_scaled[1:] - y_scaled[:-1]
282 dist_tot = np.sum(np.sqrt(dx * dx + dy * dy))
283
284 # number of interpolated points is proportional to the distance
285 Nu = int(200 * dist_tot)
286 u = np.arange(-1, Nu + 1) * 1. / (Nu - 1)
287
288 # interpolate curve at sampled points
289 k = min(3, len(x) - 1)
290 res = interpolate.splprep([x_scaled, y_scaled], s=0, k=k)
291 x_int, y_int = interpolate.splev(u, res[0])
292
293 # we'll perturb perpendicular to the drawn line
294 dx = x_int[2:] - x_int[:-2]
295 dy = y_int[2:] - y_int[:-2]
296 dist = np.sqrt(dx * dx + dy * dy)
297
298 # create a filtered perturbation
299 coeffs = mag * np.random.normal(0, 0.01, len(x_int) - 2)
300 b = signal.firwin(f1, f2 * dist_tot, window=('kaiser', f3))
301 response = signal.lfilter(b, 1, coeffs)
302
303 x_int[1:-1] += response * dy / dist
304 y_int[1:-1] += response * dx / dist
305
306 # un-scale data
307 x_int = x_int[1:-1] * (xlim[1] - xlim[0]) + xlim[0]
308 y_int = y_int[1:-1] * (ylim[1] - ylim[0]) + ylim[0]
309
310 return x_int, y_int
311
312
313 def XKCDify(ax, mag=1.0,
314 f1=50, f2=0.01, f3=15,
315 bgcolor='w',
316 xaxis_loc=None,
317 yaxis_loc=None,
318 xaxis_arrow='+',
319 yaxis_arrow='+',
320 ax_extend=0.1,
321 expand_axes=False):
322 """Make axis look hand-drawn
323
324 This adjusts all lines, text, legends, and axes in the figure to look
325 like xkcd plots. Other plot elements are not modified.
326
327 Parameters
328 ----------
329 ax : Axes instance
330 the axes to be modified.
331 mag : float
332 the magnitude of the distortion
333 f1, f2, f3 : int, float, int
334 filtering parameters. f1 gives the size of the window, f2 gives
335 the high-frequency cutoff, f3 gives the size of the filter
336 xaxis_loc, yaxis_log : float
337 The locations to draw the x and y axes. If not specified, they
338 will be drawn from the bottom left of the plot
339 xaxis_arrow, yaxis_arrow : str
340 where to draw arrows on the x/y axes. Options are '+', '-', '+-', or ''
341 ax_extend : float
342 How far (fractionally) to extend the drawn axes beyond the original
343 axes limits
344 expand_axes : bool
345 if True, then expand axes to fill the figure (useful if there is only
346 a single axes in the figure)
347 """
348 # Get axes aspect
349 ext = ax.get_window_extent().extents
350 aspect = (ext[3] - ext[1]) / (ext[2] - ext[0])
351
352 xlim = ax.get_xlim()
353 ylim = ax.get_ylim()
354
355 xspan = xlim[1] - xlim[0]
356 yspan = ylim[1] - xlim[0]
357
358 xax_lim = (xlim[0] - ax_extend * xspan,
359 xlim[1] + ax_extend * xspan)
360 yax_lim = (ylim[0] - ax_extend * yspan,
361 ylim[1] + ax_extend * yspan)
362
363 if xaxis_loc is None:
364 xaxis_loc = ylim[0]
365
366 if yaxis_loc is None:
367 yaxis_loc = xlim[0]
368
369 # Draw axes
370 xaxis = pl.Line2D([xax_lim[0], xax_lim[1]], [xaxis_loc, xaxis_loc],
371 linestyle='-', color='k')
372 yaxis = pl.Line2D([yaxis_loc, yaxis_loc], [yax_lim[0], yax_lim[1]],
373 linestyle='-', color='k')
374
375 # Label axes3, 0.5, 'hello', fontsize=14)
376 ax.text(xax_lim[1], xaxis_loc - 0.02 * yspan, ax.get_xlabel(),
377 fontsize=14, ha='right', va='top', rotation=12)
378 ax.text(yaxis_loc - 0.02 * xspan, yax_lim[1], ax.get_ylabel(),
379 fontsize=14, ha='right', va='top', rotation=78)
380 ax.set_xlabel('')
381 ax.set_ylabel('')
382
383 # Add title
384 ax.text(0.5 * (xax_lim[1] + xax_lim[0]), yax_lim[1],
385 ax.get_title(),
386 ha='center', va='bottom', fontsize=16)
387 ax.set_title('')
388
389 Nlines = len(ax.lines)
390 lines = [xaxis, yaxis] + [ax.lines.pop(0) for i in range(Nlines)]
391
392 for line in lines:
393 x, y = line.get_data()
394
395 x_int, y_int = xkcd_line(x, y, xlim, ylim,
396 mag, f1, f2, f3)
397
398 # create foreground and background line
399 lw = line.get_linewidth()
400 line.set_linewidth(2 * lw)
401 line.set_data(x_int, y_int)
402
403 # don't add background line for axes
404 if (line is not xaxis) and (line is not yaxis):
405 line_bg = pl.Line2D(x_int, y_int, color=bgcolor,
406 linewidth=8 * lw)
407
408 ax.add_line(line_bg)
409 ax.add_line(line)
410
411 # Draw arrow-heads at the end of axes lines
412 arr1 = 0.03 * np.array([-1, 0, -1])
413 arr2 = 0.02 * np.array([-1, 0, 1])
414
415 arr1[::2] += np.random.normal(0, 0.005, 2)
416 arr2[::2] += np.random.normal(0, 0.005, 2)
417
418 x, y = xaxis.get_data()
419 if '+' in str(xaxis_arrow):
420 ax.plot(x[-1] + arr1 * xspan * aspect,
421 y[-1] + arr2 * yspan,
422 color='k', lw=2)
423 if '-' in str(xaxis_arrow):
424 ax.plot(x[0] - arr1 * xspan * aspect,
425 y[0] - arr2 * yspan,
426 color='k', lw=2)
427
428 x, y = yaxis.get_data()
429 if '+' in str(yaxis_arrow):
430 ax.plot(x[-1] + arr2 * xspan * aspect,
431 y[-1] + arr1 * yspan,
432 color='k', lw=2)
433 if '-' in str(yaxis_arrow):
434 ax.plot(x[0] - arr2 * xspan * aspect,
435 y[0] - arr1 * yspan,
436 color='k', lw=2)
437
438 # Change all the fonts to humor-sans.
439 prop = fm.FontProperties(fname='Humor-Sans.ttf', size=16)
440 for text in ax.texts:
441 text.set_fontproperties(prop)
442
443 # modify legend
444 leg = ax.get_legend()
445 if leg is not None:
446 leg.set_frame_on(False)
447
448 for child in leg.get_children():
449 if isinstance(child, pl.Line2D):
450 x, y = child.get_data()
451 child.set_data(xkcd_line(x, y, mag=10, f1=100, f2=0.001))
452 child.set_linewidth(2 * child.get_linewidth())
453 if isinstance(child, pl.Text):
454 child.set_fontproperties(prop)
455
456 # Set the axis limits
457 ax.set_xlim(xax_lim[0] - 0.1 * xspan,
458 xax_lim[1] + 0.1 * xspan)
459 ax.set_ylim(yax_lim[0] - 0.1 * yspan,
460 yax_lim[1] + 0.1 * yspan)
461
462 # adjust the axes
463 ax.set_xticks([])
464 ax.set_yticks([])
465
466 if expand_axes:
467 ax.figure.set_facecolor(bgcolor)
468 ax.set_axis_off()
469 ax.set_position([0, 0, 1, 1])
470
471 return ax
472 \end{lstlisting}
473 \end{codeinput}
474 \end{codecell}
475 \subsection{Testing it Out}
476 Let's test this out with a simple plot. We'll plot two curves, add some
477 labels, and then call \texttt{XKCDify} on the axis. I think the results
478 are pretty nice!
479
480 \begin{codecell}
481 \begin{codeinput}
482 \begin{lstlisting}
483 %pylab inline
484 \end{lstlisting}
485 \end{codeinput}
486 \begin{codeoutput}
487 \begin{verbatim}
488 Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
489 For more information, type 'help(pylab)'.
490 \end{verbatim}
491 \end{codeoutput}
492 \end{codecell}
493 \begin{codecell}
494 \begin{codeinput}
495 \begin{lstlisting}
496 np.random.seed(0)
497
498 ax = pylab.axes()
499
500 x = np.linspace(0, 10, 100)
501 ax.plot(x, np.sin(x) * np.exp(-0.1 * (x - 5) ** 2), 'b', lw=1, label='damped sine')
502 ax.plot(x, -np.cos(x) * np.exp(-0.1 * (x - 5) ** 2), 'r', lw=1, label='damped cosine')
503
504 ax.set_title('check it out!')
505 ax.set_xlabel('x label')
506 ax.set_ylabel('y label')
507
508 ax.legend(loc='lower right')
509
510 ax.set_xlim(0, 10)
511 ax.set_ylim(-1.0, 1.0)
512
513 #XKCDify the axes -- this operates in-place
514 XKCDify(ax, xaxis_loc=0.0, yaxis_loc=1.0,
515 xaxis_arrow='+-', yaxis_arrow='+-',
516 expand_axes=True)
517
518 \end{lstlisting}
519 \end{codeinput}
520 \begin{codeoutput}
521 \begin{verbatim}
522 <matplotlib.axes.AxesSubplot at 0x2fecbd0>
523 \end{verbatim}
524 \begin{center}
525 \includegraphics[width=0.7\textwidth]{XKCD_plots_orig_files/XKCD_plots_orig_fig_00.png}
526 \par
527 \end{center}
528 \end{codeoutput}
529 \end{codecell}
530 \subsection{Duplicating an XKCD Comic}
531 Now let's see if we can use this to replicated an XKCD comic in
532 matplotlib. This is a good one:
533
534 \begin{codecell}
535 \begin{codeinput}
536 \begin{lstlisting}
537 Image('http://imgs.xkcd.com/comics/front_door.png')
538 \end{lstlisting}
539 \end{codeinput}
540 \begin{codeoutput}
541 \begin{verbatim}
542 <IPython.core.display.Image at 0x2ff4a10>
543 \end{verbatim}
544 \end{codeoutput}
545 \end{codecell}
546 With the new \texttt{XKCDify} function, this is relatively easy to
547 replicate. The results are not exactly identical, but I think it
548 definitely gets the point across!
549
550 \begin{codecell}
551 \begin{codeinput}
552 \begin{lstlisting}
553 # Some helper functions
554 def norm(x, x0, sigma):
555 return np.exp(-0.5 * (x - x0) ** 2 / sigma ** 2)
556
557 def sigmoid(x, x0, alpha):
558 return 1. / (1. + np.exp(- (x - x0) / alpha))
559
560 # define the curves
561 x = np.linspace(0, 1, 100)
562 y1 = np.sqrt(norm(x, 0.7, 0.05)) + 0.2 * (1.5 - sigmoid(x, 0.8, 0.05))
563
564 y2 = 0.2 * norm(x, 0.5, 0.2) + np.sqrt(norm(x, 0.6, 0.05)) + 0.1 * (1 - sigmoid(x, 0.75, 0.05))
565
566 y3 = 0.05 + 1.4 * norm(x, 0.85, 0.08)
567 y3[x > 0.85] = 0.05 + 1.4 * norm(x[x > 0.85], 0.85, 0.3)
568
569 # draw the curves
570 ax = pl.axes()
571 ax.plot(x, y1, c='gray')
572 ax.plot(x, y2, c='blue')
573 ax.plot(x, y3, c='red')
574
575 ax.text(0.3, -0.1, "Yard")
576 ax.text(0.5, -0.1, "Steps")
577 ax.text(0.7, -0.1, "Door")
578 ax.text(0.9, -0.1, "Inside")
579
580 ax.text(0.05, 1.1, "fear that\nthere's\nsomething\nbehind me")
581 ax.plot([0.15, 0.2], [1.0, 0.2], '-k', lw=0.5)
582
583 ax.text(0.25, 0.8, "forward\nspeed")
584 ax.plot([0.32, 0.35], [0.75, 0.35], '-k', lw=0.5)
585
586 ax.text(0.9, 0.4, "embarrassment")
587 ax.plot([1.0, 0.8], [0.55, 1.05], '-k', lw=0.5)
588
589 ax.set_title("Walking back to my\nfront door at night:")
590
591 ax.set_xlim(0, 1)
592 ax.set_ylim(0, 1.5)
593
594 # modify all the axes elements in-place
595 XKCDify(ax, expand_axes=True)
596
597 \end{lstlisting}
598 \end{codeinput}
599 \begin{codeoutput}
600 \begin{verbatim}
601 <matplotlib.axes.AxesSubplot at 0x2fef210>
602 \end{verbatim}
603 \begin{center}
604 \includegraphics[width=0.7\textwidth]{XKCD_plots_orig_files/XKCD_plots_orig_fig_01.png}
605 \par
606 \end{center}
607 \end{codeoutput}
608 \end{codecell}
609 Pretty good for a couple hours's work!
610
611 I think the possibilities here are pretty limitless: this is going to be
612 a hugely useful and popular feature in matplotlib, especially when the
613 sketch artist PR is mature and part of the main package. I imagine using
614 this style of plot for schematic figures in presentations where the
615 normal crisp matplotlib lines look a bit too ``scientific''. I'm giving
616 a few talks at the end of the month\ldots{} maybe I'll even use some of
617 this code there.
618
619 This post was written entirely in an IPython Notebook: the notebook file
620 is available for download
621 \href{http://jakevdp.github.com/downloads/notebooks/XKCD\_plots.ipynb}{here}.
622 For more information on blogging with notebooks in octopress, see my
623 \href{http://jakevdp.github.com/blog/2012/10/04/blogging-with-ipython/}{previous
624 post} on the subject.
625
626 \end{document}
@@ -0,0 +1,69 b''
1 <div class="highlight"><pre><span class="c">#! /usr/bin/env python</span>
2 <span class="sd">&#39;&#39;&#39;</span>
3 <span class="sd">github_team_calendar.py</span>
4 <span class="sd">Python program to scrape friends github to build team calendar for github</span>
5 <span class="sd">&#39;&#39;&#39;</span>
6
7
8 <span class="kn">import</span> <span class="nn">json</span>
9 <span class="kn">import</span> <span class="nn">requests</span>
10 <span class="kn">import</span> <span class="nn">pandas</span> <span class="kn">as</span> <span class="nn">pd</span>
11
12
13 <span class="k">def</span> <span class="nf">line_draw_target</span><span class="p">(</span><span class="n">target</span><span class="p">):</span>
14 <span class="n">github_url</span> <span class="o">=</span> <span class="s">&#39;https://github.com/users/</span><span class="si">%s</span><span class="s">/contributions_calendar_data&#39;</span>
15 <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">github_url</span> <span class="o">%</span> <span class="n">target</span><span class="p">)</span>
16 <span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
17 <span class="n">dates</span><span class="p">,</span> <span class="n">contributions</span> <span class="o">=</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">data</span><span class="p">)</span>
18 <span class="n">ts</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">Series</span><span class="p">(</span><span class="n">contributions</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="n">dates</span><span class="p">)</span>
19 <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ts</span><span class="p">)</span>
20 </pre></div>
21
22
23
24 <div class="highlight"><pre><span class="n">target</span> <span class="o">=</span> <span class="s">&quot;mikedewar&quot;</span>
25 <span class="n">line_draw_target</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
26
27 </pre></div>
28
29
30
31 ![](tests/ipynbref/data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_00.png)
32
33
34 <div class="highlight"><pre><span class="n">target</span> <span class="o">=</span> <span class="s">&quot;drewconway&quot;</span>
35 <span class="n">line_draw_target</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
36 </pre></div>
37
38
39
40 ![](tests/ipynbref/data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_01.png)
41
42
43 <div class="highlight"><pre><span class="n">target</span> <span class="o">=</span> <span class="s">&quot;hmason&quot;</span>
44 <span class="n">line_draw_target</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
45 </pre></div>
46
47
48
49 ![](tests/ipynbref/data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_02.png)
50
51
52 <div class="highlight"><pre><span class="n">target</span> <span class="o">=</span> <span class="s">&quot;mbostock&quot;</span>
53 <span class="n">line_draw_target</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
54 </pre></div>
55
56
57
58 ![](tests/ipynbref/data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_03.png)
59
60
61 <div class="highlight"><pre><span class="n">target</span> <span class="o">=</span> <span class="s">&quot;amueller&quot;</span>
62 <span class="n">line_draw_target</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
63 </pre></div>
64
65
66
67 ![](tests/ipynbref/data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_04.png)
68
69
@@ -0,0 +1,220 b''
1 %% This file was auto-generated by IPython.
2 %% Conversion from the original notebook file:
3 %% tests/ipynbref/data_geeks_team_calendar.orig.ipynb
4 %%
5 \documentclass[11pt,english]{article}
6
7 %% This is the automatic preamble used by IPython. Note that it does *not*
8 %% include a documentclass declaration, that is added at runtime to the overall
9 %% document.
10
11 \usepackage{amsmath}
12 \usepackage{amssymb}
13 \usepackage{graphicx}
14 \usepackage{ucs}
15 \usepackage[utf8x]{inputenc}
16
17 % needed for markdown enumerations to work
18 \usepackage{enumerate}
19
20 % Slightly bigger margins than the latex defaults
21 \usepackage{geometry}
22 \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm}
23
24 % Define a few colors for use in code, links and cell shading
25 \usepackage{color}
26 \definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
27 \definecolor{darkorange}{rgb}{.71,0.21,0.01}
28 \definecolor{darkgreen}{rgb}{.12,.54,.11}
29 \definecolor{myteal}{rgb}{.26, .44, .56}
30 \definecolor{gray}{gray}{0.45}
31 \definecolor{lightgray}{gray}{.95}
32 \definecolor{mediumgray}{gray}{.8}
33 \definecolor{inputbackground}{rgb}{.95, .95, .85}
34 \definecolor{outputbackground}{rgb}{.95, .95, .95}
35 \definecolor{traceback}{rgb}{1, .95, .95}
36
37 % Framed environments for code cells (inputs, outputs, errors, ...). The
38 % various uses of \unskip (or not) at the end were fine-tuned by hand, so don't
39 % randomly change them unless you're sure of the effect it will have.
40 \usepackage{framed}
41
42 % remove extraneous vertical space in boxes
43 \setlength\fboxsep{0pt}
44
45 % codecell is the whole input+output set of blocks that a Code cell can
46 % generate.
47
48 % TODO: unfortunately, it seems that using a framed codecell environment breaks
49 % the ability of the frames inside of it to be broken across pages. This
50 % causes at least the problem of having lots of empty space at the bottom of
51 % pages as new frames are moved to the next page, and if a single frame is too
52 % long to fit on a page, will completely stop latex from compiling the
53 % document. So unless we figure out a solution to this, we'll have to instead
54 % leave the codecell env. as empty. I'm keeping the original codecell
55 % definition here (a thin vertical bar) for reference, in case we find a
56 % solution to the page break issue.
57
58 %% \newenvironment{codecell}{%
59 %% \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}%
60 %% \MakeFramed{\vspace{-0.5em}}}
61 %% {\unskip\endMakeFramed}
62
63 % For now, make this a no-op...
64 \newenvironment{codecell}{}
65
66 \newenvironment{codeinput}{%
67 \def\FrameCommand{\colorbox{inputbackground}}%
68 \MakeFramed{\advance\hsize-\width \FrameRestore}}
69 {\unskip\endMakeFramed}
70
71 \newenvironment{codeoutput}{%
72 \def\FrameCommand{\colorbox{outputbackground}}%
73 \vspace{-1.4em}
74 \MakeFramed{\advance\hsize-\width \FrameRestore}}
75 {\unskip\medskip\endMakeFramed}
76
77 \newenvironment{traceback}{%
78 \def\FrameCommand{\colorbox{traceback}}%
79 \MakeFramed{\advance\hsize-\width \FrameRestore}}
80 {\endMakeFramed}
81
82 % Use and configure listings package for nicely formatted code
83 \usepackage{listingsutf8}
84 \lstset{
85 language=python,
86 inputencoding=utf8x,
87 extendedchars=\true,
88 aboveskip=\smallskipamount,
89 belowskip=\smallskipamount,
90 xleftmargin=2mm,
91 breaklines=true,
92 basicstyle=\small \ttfamily,
93 showstringspaces=false,
94 keywordstyle=\color{blue}\bfseries,
95 commentstyle=\color{myteal},
96 stringstyle=\color{darkgreen},
97 identifierstyle=\color{darkorange},
98 columns=fullflexible, % tighter character kerning, like verb
99 }
100
101 % The hyperref package gives us a pdf with properly built
102 % internal navigation ('pdf bookmarks' for the table of contents,
103 % internal cross-reference links, web links for URLs, etc.)
104 \usepackage{hyperref}
105 \hypersetup{
106 breaklinks=true, % so long urls are correctly broken across lines
107 colorlinks=true,
108 urlcolor=blue,
109 linkcolor=darkorange,
110 citecolor=darkgreen,
111 }
112
113 % hardcode size of all verbatim environments to be a bit smaller
114 \makeatletter
115 \g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt
116 \makeatother
117
118 % Prevent overflowing lines due to urls and other hard-to-break entities.
119 \sloppy
120
121 \begin{document}
122
123 \begin{codecell}
124 \begin{codeinput}
125 \begin{lstlisting}
126 #! /usr/bin/env python
127 '''
128 github_team_calendar.py
129 Python program to scrape friends github to build team calendar for github
130 '''
131
132
133 import json
134 import requests
135 import pandas as pd
136
137
138 def line_draw_target(target):
139 github_url = 'https://github.com/users/%s/contributions_calendar_data'
140 r = requests.get(github_url % target)
141 data = json.loads(r.text)
142 dates, contributions = zip(*data)
143 ts = pd.Series(contributions, index=dates)
144 plt.plot(ts)
145 \end{lstlisting}
146 \end{codeinput}
147 \end{codecell}
148 \begin{codecell}
149 \begin{codeinput}
150 \begin{lstlisting}
151 target = "mikedewar"
152 line_draw_target(target)
153
154 \end{lstlisting}
155 \end{codeinput}
156 \begin{codeoutput}
157 \begin{center}
158 \includegraphics[width=0.7\textwidth]{data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_00.png}
159 \par
160 \end{center}
161 \end{codeoutput}
162 \end{codecell}
163 \begin{codecell}
164 \begin{codeinput}
165 \begin{lstlisting}
166 target = "drewconway"
167 line_draw_target(target)
168 \end{lstlisting}
169 \end{codeinput}
170 \begin{codeoutput}
171 \begin{center}
172 \includegraphics[width=0.7\textwidth]{data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_01.png}
173 \par
174 \end{center}
175 \end{codeoutput}
176 \end{codecell}
177 \begin{codecell}
178 \begin{codeinput}
179 \begin{lstlisting}
180 target = "hmason"
181 line_draw_target(target)
182 \end{lstlisting}
183 \end{codeinput}
184 \begin{codeoutput}
185 \begin{center}
186 \includegraphics[width=0.7\textwidth]{data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_02.png}
187 \par
188 \end{center}
189 \end{codeoutput}
190 \end{codecell}
191 \begin{codecell}
192 \begin{codeinput}
193 \begin{lstlisting}
194 target = "mbostock"
195 line_draw_target(target)
196 \end{lstlisting}
197 \end{codeinput}
198 \begin{codeoutput}
199 \begin{center}
200 \includegraphics[width=0.7\textwidth]{data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_03.png}
201 \par
202 \end{center}
203 \end{codeoutput}
204 \end{codecell}
205 \begin{codecell}
206 \begin{codeinput}
207 \begin{lstlisting}
208 target = "amueller"
209 line_draw_target(target)
210 \end{lstlisting}
211 \end{codeinput}
212 \begin{codeoutput}
213 \begin{center}
214 \includegraphics[width=0.7\textwidth]{data_geeks_team_calendar_orig_files/data_geeks_team_calendar_orig_fig_04.png}
215 \par
216 \end{center}
217 \end{codeoutput}
218 \end{codecell}
219
220 \end{document}
General Comments 0
You need to be logged in to leave comments. Login now