Created
January 22, 2015 22:30
-
-
Save chriddyp/9827cb5086cfab8da092 to your computer and use it in GitHub Desktop.
A Collection of Plotly and IPython Widgets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "", | |
"signature": "sha256:16a7b25b07032860a7b987719d76b9790e995e9be05ba090513f0eeae0ef9fd4" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Exploring NYC 311 Calls\n", | |
"#### Plotly and IPython Widgets" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"from IPython.display import Image\n", | |
"Image(url='http://i.imgur.com/h5GLIHc.gif')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"<img src=\"http://i.imgur.com/h5GLIHc.gif\"/>" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 14, | |
"text": [ | |
"<IPython.core.display.Image at 0x10bcd8390>" | |
] | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import pandas as pd\n", | |
"import datetime\n", | |
"\n", | |
"from IPython.html import widgets \n", | |
"from IPython.display import display, clear_output\n", | |
"\n", | |
"import plotly.plotly as py\n", | |
"from plotly.graph_objs import *\n", | |
"import plotly\n", | |
"from plotly.widgets import GraphWidget" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stderr", | |
"text": [ | |
"/Users/chris/anaconda/lib/python2.7/site-packages/pandas/computation/expressions.py:21: UserWarning: The installed version of numexpr 2.0.1 is not supported in pandas and will be not be used\n", | |
"The minimum supported version is 2.1\n", | |
"\n", | |
" \"version is 2.1\\n\".format(ver=ver), UserWarning)\n" | |
] | |
}, | |
{ | |
"javascript": [ | |
"window.genUID = function() {\n", | |
" return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n", | |
" var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);\n", | |
" return v.toString(16);\n", | |
" });\n", | |
"};\n", | |
"\n", | |
"require([\"widgets/js/widget\"], function(WidgetManager){\n", | |
"\n", | |
" var GraphView = IPython.DOMWidgetView.extend({\n", | |
" render: function(){\n", | |
"\n", | |
" console.log('render!');\n", | |
"\n", | |
" var that = this;\n", | |
"\n", | |
" var graphId = window.genUID();\n", | |
" var loadingId = 'loading-'+graphId;\n", | |
"\n", | |
"\n", | |
" var _graph_url = that.model.get('_graph_url');\n", | |
"\n", | |
" // variable plotlyDomain in the case of enterprise\n", | |
" var url_parts = _graph_url.split('/');\n", | |
" var plotlyDomain = url_parts[0] + '//' + url_parts[2];\n", | |
"\n", | |
" if(!('plotlyDomains' in window)){\n", | |
" window.plotlyDomains = {};\n", | |
" }\n", | |
" window.plotlyDomains[graphId] = plotlyDomain;\n", | |
"\n", | |
" // Place IFrame in output cell div `$el`\n", | |
" that.$el.css('width', '100%');\n", | |
" that.$graph = $(['<iframe id=\"'+graphId+'\"',\n", | |
" 'src=\"'+_graph_url+'.embed\"',\n", | |
" 'seamless',\n", | |
" 'style=\"border: none;\"',\n", | |
" 'width=\"100%\"',\n", | |
" 'height=\"600\">',\n", | |
" '</iframe>'].join(' '));\n", | |
" that.$graph.appendTo(that.$el);\n", | |
"\n", | |
" that.$loading = $('<div id=\"'+loadingId+'\">Initializing...</div>')\n", | |
" .appendTo(that.$el);\n", | |
"\n", | |
" // initialize communication with the iframe\n", | |
" if(!('pingers' in window)){\n", | |
" window.pingers = {};\n", | |
" }\n", | |
"\n", | |
" window.pingers[graphId] = setInterval(function() {\n", | |
" that.graphContentWindow = $('#'+graphId)[0].contentWindow;\n", | |
" console.log('posting ping: ', plotlyDomain);\n", | |
" that.graphContentWindow.postMessage({task: 'ping'}, plotlyDomain);\n", | |
" }, 200);\n", | |
"\n", | |
" // Assign a message listener to the 'message' events\n", | |
" // from iframe's postMessage protocol.\n", | |
" // Filter the messages by iframe src so that the right message\n", | |
" // gets passed to the right widget\n", | |
" if(!('messageListeners' in window)){\n", | |
" window.messageListeners = {};\n", | |
" }\n", | |
"\n", | |
" window.messageListeners[graphId] = function(e) {\n", | |
" console.log('message: ', e.data);\n", | |
" if(_graph_url.indexOf(e.origin)>-1) {\n", | |
" var frame = document.getElementById(graphId);\n", | |
"\n", | |
" if(frame === null){\n", | |
" // frame doesn't exist in the dom anymore, clean up it's old event listener\n", | |
" window.removeEventListener('message', window.messageListeners[graphId]);\n", | |
" clearInterval(window.pingers[graphId]);\n", | |
" } else if(frame.contentWindow === e.source) {\n", | |
" // TODO: Stop event propagation, so each frame doesn't listen and filter\n", | |
" var frameContentWindow = $('#'+graphId)[0].contentWindow;\n", | |
" var message = e.data;\n", | |
"\n", | |
" if('pong' in message && message.pong) {\n", | |
" $('#loading-'+graphId).hide();\n", | |
" clearInterval(window.pingers[graphId]);\n", | |
" that.send({event: 'pong', graphId: graphId});\n", | |
" } else if (message.type==='hover' ||\n", | |
" message.type==='zoom' ||\n", | |
" message.type==='click' ||\n", | |
" message.type==='unhover') {\n", | |
"\n", | |
" // click and hover events contain all of the data in the traces,\n", | |
" // which can be a very large object and may take a ton of time\n", | |
" // to pass to the python backend. Strip out the data, and require\n", | |
" // the user to call get_figure if they need trace information\n", | |
" if(message.type !== 'zoom') {\n", | |
" for(var i in message.points) {\n", | |
" delete message.points[i].data;\n", | |
" }\n", | |
" }\n", | |
" that.send({event: message.type, message: message, graphId: graphId});\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
" };\n", | |
"\n", | |
" window.removeEventListener('message', window.messageListeners[graphId]);\n", | |
" window.addEventListener('message', window.messageListeners[graphId]);\n", | |
"\n", | |
" },\n", | |
"\n", | |
" update: function() {\n", | |
" // Listen for messages from the graph widget in python\n", | |
" var jmessage = this.model.get('_message');\n", | |
" var message = JSON.parse(jmessage);\n", | |
"\n", | |
" // check for duplicate messages\n", | |
" if(!('messageIds' in window)){\n", | |
" window.messageIds = {};\n", | |
" }\n", | |
"\n", | |
" if(!(message.uid in window.messageIds)){\n", | |
" // message hasn't been received yet, do stuff\n", | |
" window.messageIds[message.uid] = true;\n", | |
"\n", | |
" var plot = $('#'+message.graphId)[0].contentWindow;\n", | |
" plot.postMessage(message, window.plotlyDomains[message.graphId]);\n", | |
" }\n", | |
"\n", | |
" return GraphView.__super__.update.apply(this);\n", | |
" }\n", | |
" });\n", | |
"\n", | |
" // Register the GraphView with the widget manager.\n", | |
" WidgetManager.register_widget_view('GraphView', GraphView);\n", | |
"});\n", | |
"\n", | |
"//@ sourceURL=graphWidget.js\n" | |
], | |
"metadata": {}, | |
"output_type": "display_data", | |
"text": [ | |
"<IPython.core.display.Javascript at 0x107776c50>" | |
] | |
} | |
], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"df = pd.read_csv('https://raw.githubusercontent.com/plotly/widgets/master/ipython-examples/311_150k.csv', parse_dates=True, index_col=1)\n", | |
"df = df\n", | |
"df.head()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stderr", | |
"text": [ | |
"/Users/chris/anaconda/lib/python2.7/site-packages/pandas/io/parsers.py:1154: DtypeWarning:\n", | |
"\n", | |
"Columns (8,39,46,47,48) have mixed types. Specify dtype option on import or set low_memory=False.\n", | |
"\n" | |
] | |
}, | |
{ | |
"html": [ | |
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>Unique Key</th>\n", | |
" <th>Closed Date</th>\n", | |
" <th>Agency</th>\n", | |
" <th>Agency Name</th>\n", | |
" <th>Complaint Type</th>\n", | |
" <th>Descriptor</th>\n", | |
" <th>Location Type</th>\n", | |
" <th>Incident Zip</th>\n", | |
" <th>Incident Address</th>\n", | |
" <th>Street Name</th>\n", | |
" <th>...</th>\n", | |
" <th>Bridge Highway Name</th>\n", | |
" <th>Bridge Highway Direction</th>\n", | |
" <th>Road Ramp</th>\n", | |
" <th>Bridge Highway Segment</th>\n", | |
" <th>Garage Lot Name</th>\n", | |
" <th>Ferry Direction</th>\n", | |
" <th>Ferry Terminal Name</th>\n", | |
" <th>Latitude</th>\n", | |
" <th>Longitude</th>\n", | |
" <th>Location</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>Created Date</th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" <th></th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>2014-11-16 23:46:00</th>\n", | |
" <td> 29300358</td>\n", | |
" <td> 11/16/2014 11:46:00 PM</td>\n", | |
" <td> DSNY</td>\n", | |
" <td> BCC - Queens East</td>\n", | |
" <td> Derelict Vehicles</td>\n", | |
" <td> 14 Derelict Vehicles</td>\n", | |
" <td> Street</td>\n", | |
" <td> 11432</td>\n", | |
" <td> 80-25 PARSONS BOULEVARD</td>\n", | |
" <td> PARSONS BOULEVARD</td>\n", | |
" <td>...</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> 40.719411</td>\n", | |
" <td>-73.808882</td>\n", | |
" <td> (40.719410639341916, -73.80888158860446)</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2014-11-16 02:24:35</th>\n", | |
" <td> 29299837</td>\n", | |
" <td> 11/16/2014 02:24:35 AM</td>\n", | |
" <td> DOB</td>\n", | |
" <td> Department of Buildings</td>\n", | |
" <td> Building/Use</td>\n", | |
" <td> Illegal Conversion Of Residential Building/Space</td>\n", | |
" <td> NaN</td>\n", | |
" <td> 10465</td>\n", | |
" <td> 938 HUNTINGTON AVENUE</td>\n", | |
" <td> HUNTINGTON AVENUE</td>\n", | |
" <td>...</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> 40.827862</td>\n", | |
" <td>-73.830641</td>\n", | |
" <td> (40.827862046105416, -73.83064067165407)</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2014-11-16 02:17:12</th>\n", | |
" <td> 29297857</td>\n", | |
" <td> 11/16/2014 02:50:48 AM</td>\n", | |
" <td> NYPD</td>\n", | |
" <td> New York City Police Department</td>\n", | |
" <td> Illegal Parking</td>\n", | |
" <td> Blocked Sidewalk</td>\n", | |
" <td> Street/Sidewalk</td>\n", | |
" <td> 11201</td>\n", | |
" <td> 229 DUFFIELD STREET</td>\n", | |
" <td> DUFFIELD STREET</td>\n", | |
" <td>...</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> 40.691248</td>\n", | |
" <td>-73.984375</td>\n", | |
" <td> (40.69124772858873, -73.98437529459297)</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2014-11-16 02:15:13</th>\n", | |
" <td> 29294647</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NYPD</td>\n", | |
" <td> New York City Police Department</td>\n", | |
" <td> Noise - Street/Sidewalk</td>\n", | |
" <td> Loud Music/Party</td>\n", | |
" <td> Street/Sidewalk</td>\n", | |
" <td> 10040</td>\n", | |
" <td> 128 NAGLE AVENUE</td>\n", | |
" <td> NAGLE AVENUE</td>\n", | |
" <td>...</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> 40.861248</td>\n", | |
" <td>-73.926308</td>\n", | |
" <td> (40.861247930170535, -73.92630783362215)</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2014-11-16 02:14:01</th>\n", | |
" <td> 29300211</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NYPD</td>\n", | |
" <td> New York City Police Department</td>\n", | |
" <td> Illegal Parking</td>\n", | |
" <td> Commercial Overnight Parking</td>\n", | |
" <td> Street/Sidewalk</td>\n", | |
" <td> 10306</td>\n", | |
" <td> 625 LINCOLN AVENUE</td>\n", | |
" <td> LINCOLN AVENUE</td>\n", | |
" <td>...</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> NaN</td>\n", | |
" <td> 40.570565</td>\n", | |
" <td>-74.092229</td>\n", | |
" <td> (40.57056460126485, -74.09222907551542)</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows \u00d7 51 columns</p>\n", | |
"</div>" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 2, | |
"text": [ | |
" Unique Key Closed Date Agency \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 29300358 11/16/2014 11:46:00 PM DSNY \n", | |
"2014-11-16 02:24:35 29299837 11/16/2014 02:24:35 AM DOB \n", | |
"2014-11-16 02:17:12 29297857 11/16/2014 02:50:48 AM NYPD \n", | |
"2014-11-16 02:15:13 29294647 NaN NYPD \n", | |
"2014-11-16 02:14:01 29300211 NaN NYPD \n", | |
"\n", | |
" Agency Name Complaint Type \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 BCC - Queens East Derelict Vehicles \n", | |
"2014-11-16 02:24:35 Department of Buildings Building/Use \n", | |
"2014-11-16 02:17:12 New York City Police Department Illegal Parking \n", | |
"2014-11-16 02:15:13 New York City Police Department Noise - Street/Sidewalk \n", | |
"2014-11-16 02:14:01 New York City Police Department Illegal Parking \n", | |
"\n", | |
" Descriptor \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 14 Derelict Vehicles \n", | |
"2014-11-16 02:24:35 Illegal Conversion Of Residential Building/Space \n", | |
"2014-11-16 02:17:12 Blocked Sidewalk \n", | |
"2014-11-16 02:15:13 Loud Music/Party \n", | |
"2014-11-16 02:14:01 Commercial Overnight Parking \n", | |
"\n", | |
" Location Type Incident Zip Incident Address \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 Street 11432 80-25 PARSONS BOULEVARD \n", | |
"2014-11-16 02:24:35 NaN 10465 938 HUNTINGTON AVENUE \n", | |
"2014-11-16 02:17:12 Street/Sidewalk 11201 229 DUFFIELD STREET \n", | |
"2014-11-16 02:15:13 Street/Sidewalk 10040 128 NAGLE AVENUE \n", | |
"2014-11-16 02:14:01 Street/Sidewalk 10306 625 LINCOLN AVENUE \n", | |
"\n", | |
" Street Name \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 PARSONS BOULEVARD \n", | |
"2014-11-16 02:24:35 HUNTINGTON AVENUE \n", | |
"2014-11-16 02:17:12 DUFFIELD STREET \n", | |
"2014-11-16 02:15:13 NAGLE AVENUE \n", | |
"2014-11-16 02:14:01 LINCOLN AVENUE \n", | |
"\n", | |
" ... \\\n", | |
"Created Date ... \n", | |
"2014-11-16 23:46:00 ... \n", | |
"2014-11-16 02:24:35 ... \n", | |
"2014-11-16 02:17:12 ... \n", | |
"2014-11-16 02:15:13 ... \n", | |
"2014-11-16 02:14:01 ... \n", | |
"\n", | |
" Bridge Highway Name Bridge Highway Direction Road Ramp \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 NaN NaN NaN \n", | |
"2014-11-16 02:24:35 NaN NaN NaN \n", | |
"2014-11-16 02:17:12 NaN NaN NaN \n", | |
"2014-11-16 02:15:13 NaN NaN NaN \n", | |
"2014-11-16 02:14:01 NaN NaN NaN \n", | |
"\n", | |
" Bridge Highway Segment Garage Lot Name Ferry Direction \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 NaN NaN NaN \n", | |
"2014-11-16 02:24:35 NaN NaN NaN \n", | |
"2014-11-16 02:17:12 NaN NaN NaN \n", | |
"2014-11-16 02:15:13 NaN NaN NaN \n", | |
"2014-11-16 02:14:01 NaN NaN NaN \n", | |
"\n", | |
" Ferry Terminal Name Latitude Longitude \\\n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 NaN 40.719411 -73.808882 \n", | |
"2014-11-16 02:24:35 NaN 40.827862 -73.830641 \n", | |
"2014-11-16 02:17:12 NaN 40.691248 -73.984375 \n", | |
"2014-11-16 02:15:13 NaN 40.861248 -73.926308 \n", | |
"2014-11-16 02:14:01 NaN 40.570565 -74.092229 \n", | |
"\n", | |
" Location \n", | |
"Created Date \n", | |
"2014-11-16 23:46:00 (40.719410639341916, -73.80888158860446) \n", | |
"2014-11-16 02:24:35 (40.827862046105416, -73.83064067165407) \n", | |
"2014-11-16 02:17:12 (40.69124772858873, -73.98437529459297) \n", | |
"2014-11-16 02:15:13 (40.861247930170535, -73.92630783362215) \n", | |
"2014-11-16 02:14:01 (40.57056460126485, -74.09222907551542) \n", | |
"\n", | |
"[5 rows x 51 columns]" | |
] | |
} | |
], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"grouped = df.resample('24H', how='count')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"slider = widgets.IntSliderWidget()\n", | |
"slider.min = 1\n", | |
"slider.value=24\n", | |
"slider.description = 'Window length (hours)'" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"column_headers_dropdown = widgets.DropdownWidget()\n", | |
"column_headers_dropdown.values = {column: column for column in df.columns}\n", | |
"column_headers_dropdown.value = 'Complaint Type'\n", | |
"column_headers_dropdown.description = 'Select which column to graph (e.g. Tree)'\n", | |
"\n", | |
"\n", | |
"search_complaints_text_input = widgets.TextWidget()\n", | |
"search_complaints_text_input.description = 'Search complaint types'" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"graph_time_series_agg = GraphWidget('https://plot.ly/~chris/4103')\n", | |
"graph_time_series_agg.ranges = {'x': [1413648000000, 1416157200000], 'y': [0, 7744.210526315789]}\n", | |
"graph_complaints = GraphWidget('https://plot.ly/~chris/4103')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def replot(on_zoom=False):\n", | |
" search_text = search_complaints_text_input.value\n", | |
" slider_val = slider.value\n", | |
" column_name = column_headers_dropdown.value\n", | |
"\n", | |
" # Time window that we're looking at\n", | |
" ranges = graph_time_series_agg.ranges\n", | |
" xr = ranges['x']\n", | |
" x1 = datetime.datetime.fromtimestamp(int(xr[0]/1000.))\n", | |
" x2 = datetime.datetime.fromtimestamp(int(xr[1]/1000.))\n", | |
"\n", | |
" # Text value that we're looking at\n", | |
" search_idx = df['Complaint Type'].str.contains(search_complaints_text_input.value).fillna(False)\n", | |
" windowed_idx = search_idx & (df.index>x1) & (df.index<x2)\n", | |
"\n", | |
" if not on_zoom:\n", | |
" # Replot the time series aggregate on input change\n", | |
" grouped = df[search_idx].resample('{}H'.format(slider_val), how='count')\n", | |
"\n", | |
" graph_time_series_agg.restyle({\n", | |
" 'x': [grouped['Complaint Type'].index],\n", | |
" 'y': [grouped['Complaint Type']],\n", | |
" 'type': 'bar'\n", | |
" })\n", | |
"\n", | |
" \n", | |
" # Replot the value counts aggregate\n", | |
" vc = df[windowed_idx][column_name].value_counts()\n", | |
" \n", | |
" graph_complaints.restyle({'x': [vc.index], 'y': [vc.values], 'type': 'bar'})\n", | |
"\n", | |
"def on_trait_change():\n", | |
" replot()\n", | |
"\n", | |
"search_complaints_text_input.on_trait_change(on_trait_change, 'value')\n", | |
"column_headers_dropdown.on_trait_change(on_trait_change, 'value')\n", | |
"slider.on_trait_change(on_trait_change, 'value')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def replot_complaints_on_zoom(_, ranges):\n", | |
" graph_time_series_agg.ranges = ranges\n", | |
"\n", | |
" replot(True)\n", | |
"\n", | |
"graph_time_series_agg.on_zoom(replot_complaints_on_zoom)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"display(slider)\n", | |
"display(search_complaints_text_input)\n", | |
"display(column_headers_dropdown)\n", | |
"\n", | |
"display(graph_time_series_agg)\n", | |
"display(graph_complaints)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 9 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"replot()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"graph_time_series_agg.relayout({'title': 'Number of complaints over time'})\n", | |
"graph_complaints.relayout({'yaxis.title': 'Number of events'})" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 13 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# CSS styling within IPython notebook - feel free to re-use\n", | |
"from IPython.core.display import HTML\n", | |
"import urllib2\n", | |
"\n", | |
"HTML(urllib2.urlopen('http://bit.ly/1Bf5Hft').read())" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"<style>\n", | |
"\n", | |
"html {\n", | |
" font-size: 62.5% !important; }\n", | |
"body {\n", | |
" font-size: 1.5em !important; /* currently ems cause chrome bug misinterpreting rems on body element */\n", | |
" line-height: 1.6 !important;\n", | |
" font-weight: 400 !important;\n", | |
" font-family: \"Raleway\", \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif !important;\n", | |
" color: #222 !important; }\n", | |
"\n", | |
"div{ border-radius: 0px !important; }\n", | |
"div.CodeMirror-sizer{ background: rgb(244, 244, 248) !important; }\n", | |
"div.input_area{ background: rgb(244, 244, 248) !important; }\n", | |
"\n", | |
"div.out_prompt_overlay:hover{ background: rgb(244, 244, 248) !important; }\n", | |
"div.input_prompt:hover{ background: rgb(244, 244, 248) !important; }\n", | |
"\n", | |
"h1, h2, h3, h4, h5, h6 {\n", | |
" color: #333 !important;\n", | |
" margin-top: 0 !important;\n", | |
" margin-bottom: 2rem !important;\n", | |
" font-weight: 300 !important; }\n", | |
"h1 { font-size: 4.0rem !important; line-height: 1.2 !important; letter-spacing: -.1rem !important;}\n", | |
"h2 { font-size: 3.6rem !important; line-height: 1.25 !important; letter-spacing: -.1rem !important; }\n", | |
"h3 { font-size: 3.0rem !important; line-height: 1.3 !important; letter-spacing: -.1rem !important; }\n", | |
"h4 { font-size: 2.4rem !important; line-height: 1.35 !important; letter-spacing: -.08rem !important; }\n", | |
"h5 { font-size: 1.8rem !important; line-height: 1.5 !important; letter-spacing: -.05rem !important; }\n", | |
"h6 { font-size: 1.5rem !important; line-height: 1.6 !important; letter-spacing: 0 !important; }\n", | |
"\n", | |
"@media (min-width: 550px) {\n", | |
" h1 { font-size: 5.0rem !important; }\n", | |
" h2 { font-size: 4.2rem !important; }\n", | |
" h3 { font-size: 3.6rem !important; }\n", | |
" h4 { font-size: 3.0rem !important; }\n", | |
" h5 { font-size: 2.4rem !important; }\n", | |
" h6 { font-size: 1.5rem !important; }\n", | |
"}\n", | |
"\n", | |
"p {\n", | |
" margin-top: 0 !important; }\n", | |
" \n", | |
"a {\n", | |
" color: #1EAEDB !important; }\n", | |
"a:hover {\n", | |
" color: #0FA0CE !important; }\n", | |
" \n", | |
"code {\n", | |
" padding: .2rem .5rem !important;\n", | |
" margin: 0 .2rem !important;\n", | |
" font-size: 90% !important;\n", | |
" white-space: nowrap !important;\n", | |
" background: #F1F1F1 !important;\n", | |
" border: 1px solid #E1E1E1 !important;\n", | |
" border-radius: 4px !important; }\n", | |
"pre > code {\n", | |
" display: block !important;\n", | |
" padding: 1rem 1.5rem !important;\n", | |
" white-space: pre !important; }\n", | |
" \n", | |
"button{ border-radius: 0px !important; }\n", | |
".navbar-inner{ background-image: none !important; }\n", | |
"select, textarea{ border-radius: 0px !important; }\n", | |
"\n", | |
"</style>" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 2, | |
"text": [ | |
"<IPython.core.display.HTML at 0x1046c3650>" | |
] | |
} | |
], | |
"prompt_number": 2 | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment