Skip to content

Commit f0aa48a

Browse files
committed
Added Wealth of Nations example
1 parent 485831d commit f0aa48a

File tree

2 files changed

+385
-0
lines changed

2 files changed

+385
-0
lines changed

examples/Wealth of Nations.ipynb

+384
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"This is a `bqplot` recreation of Mike Bostock's [Wealth of Nations](https://bost.ocks.org/mike/nations/). This was also done by [Gapminder](http://www.gapminder.org/world/#$majorMode=chart$is;shi=t;ly=2003;lb=f;il=t;fs=11;al=30;stl=t;st=t;nsl=t;se=t$wst;tts=C$ts;sp=5.59290322580644;ti=2013$zpv;v=0$inc_x;mmid=XCOORDS;iid=phAwcNAVuyj1jiMAkmq1iMg;by=ind$inc_y;mmid=YCOORDS;iid=phAwcNAVuyj2tPLxKvvnNPA;by=ind$inc_s;uniValue=8.21;iid=phAwcNAVuyj0XOoBL_n5tAQ;by=ind$inc_c;uniValue=255;gid=CATID0;by=grp$map_x;scale=log;dataMin=194;dataMax=96846$map_y;scale=lin;dataMin=23;dataMax=86$map_s;sma=49;smi=2.65$cd;bd=0$inds=;modified=60). It is originally based on a TED Talk by [Hans Rosling](http://www.ted.com/talks/hans_rosling_shows_the_best_stats_you_ve_ever_seen)."
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"#### Required imports"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": null,
20+
"metadata": {
21+
"collapsed": true
22+
},
23+
"outputs": [],
24+
"source": [
25+
"import pandas as pd\n",
26+
"from bqplot import (LogScale, LinearScale, OrdinalColorScale, ColorAxis, Axis, Scatter, CATEGORY10,\n",
27+
" Figure)\n",
28+
"from bqplot.default_tooltip import Tooltip\n",
29+
"from ipywidgets import VBox, IntSlider, Button\n",
30+
"from IPython.display import display\n",
31+
"import os\n",
32+
"import numpy as np\n",
33+
"from time import sleep"
34+
]
35+
},
36+
{
37+
"cell_type": "markdown",
38+
"metadata": {},
39+
"source": [
40+
"### Cleaning and Formatting JSON Data"
41+
]
42+
},
43+
{
44+
"cell_type": "code",
45+
"execution_count": null,
46+
"metadata": {
47+
"collapsed": false,
48+
"scrolled": false
49+
},
50+
"outputs": [],
51+
"source": [
52+
"data = pd.read_json(os.path.abspath('data_files/nations.json'))"
53+
]
54+
},
55+
{
56+
"cell_type": "code",
57+
"execution_count": null,
58+
"metadata": {
59+
"collapsed": true
60+
},
61+
"outputs": [],
62+
"source": [
63+
"def clean_data(data):\n",
64+
" for i in [0, 1, 3]:\n",
65+
" data = data.drop(data[data.ix[:, i].apply(len) <= 4].index)\n",
66+
" return data\n",
67+
"\n",
68+
"def extrap_data(data):\n",
69+
" for i in [0, 1, 3]:\n",
70+
" data.ix[:, i] = data.ix[:, i].apply(extrap_interp)\n",
71+
" return data"
72+
]
73+
},
74+
{
75+
"cell_type": "code",
76+
"execution_count": null,
77+
"metadata": {
78+
"collapsed": true
79+
},
80+
"outputs": [],
81+
"source": [
82+
"def extrap_interp(data):\n",
83+
" data = np.array(data)\n",
84+
" x_range = np.arange(1800, 2009, 1.)\n",
85+
" y_range = np.interp(x_range, data[:, 0], data[:, 1])\n",
86+
" return y_range"
87+
]
88+
},
89+
{
90+
"cell_type": "code",
91+
"execution_count": null,
92+
"metadata": {
93+
"collapsed": true
94+
},
95+
"outputs": [],
96+
"source": [
97+
"data = clean_data(data)\n",
98+
"data = extrap_data(data)"
99+
]
100+
},
101+
{
102+
"cell_type": "code",
103+
"execution_count": null,
104+
"metadata": {
105+
"collapsed": false,
106+
"scrolled": true
107+
},
108+
"outputs": [],
109+
"source": [
110+
"income_min, income_max = np.min(data.ix[:, 0].apply(np.min)), np.max(data.ix[:, 0].apply(np.max))\n",
111+
"life_exp_min, life_exp_max = np.min(data.ix[:, 1].apply(np.min)), np.max(data.ix[:, 1].apply(np.max))\n",
112+
"pop_min, pop_max = np.min(data.ix[:, 3].apply(np.min)), np.max(data.ix[:, 3].apply(np.max))"
113+
]
114+
},
115+
{
116+
"cell_type": "markdown",
117+
"metadata": {},
118+
"source": [
119+
"### Defining Scales"
120+
]
121+
},
122+
{
123+
"cell_type": "code",
124+
"execution_count": null,
125+
"metadata": {
126+
"collapsed": false
127+
},
128+
"outputs": [],
129+
"source": [
130+
"x_sc = LogScale(min=income_min, max=income_max)\n",
131+
"y_sc = LinearScale(min=life_exp_min, max=life_exp_max)\n",
132+
"c_sc = OrdinalColorScale(domain=data['region'].unique().tolist(), colors=CATEGORY10[:6])\n",
133+
"size_sc = LinearScale(min=pop_min, max=pop_max)"
134+
]
135+
},
136+
{
137+
"cell_type": "markdown",
138+
"metadata": {},
139+
"source": [
140+
"### Defining the Axes"
141+
]
142+
},
143+
{
144+
"cell_type": "code",
145+
"execution_count": null,
146+
"metadata": {
147+
"collapsed": true
148+
},
149+
"outputs": [],
150+
"source": [
151+
"ax_y = Axis(label='Life Expectancy', scale=y_sc, orientation='vertical', side='left')\n",
152+
"ax_x = Axis(label='Income per Capita', scale=x_sc)"
153+
]
154+
},
155+
{
156+
"cell_type": "markdown",
157+
"metadata": {},
158+
"source": [
159+
"### Creating a Slider for the years"
160+
]
161+
},
162+
{
163+
"cell_type": "code",
164+
"execution_count": null,
165+
"metadata": {
166+
"collapsed": false
167+
},
168+
"outputs": [],
169+
"source": [
170+
"year_slider = IntSlider(min=1800, max=2008, step=1, description='Year', value=1800)"
171+
]
172+
},
173+
{
174+
"cell_type": "markdown",
175+
"metadata": {},
176+
"source": [
177+
"### Creating a Button for the animation"
178+
]
179+
},
180+
{
181+
"cell_type": "code",
182+
"execution_count": null,
183+
"metadata": {
184+
"collapsed": true
185+
},
186+
"outputs": [],
187+
"source": [
188+
"animate_button = Button(description='Play', background_color='MediumSeaGreen', color='Black', icon='fa-play')"
189+
]
190+
},
191+
{
192+
"cell_type": "markdown",
193+
"metadata": {},
194+
"source": [
195+
"#### Helper functions for parsing the data"
196+
]
197+
},
198+
{
199+
"cell_type": "code",
200+
"execution_count": null,
201+
"metadata": {
202+
"collapsed": true
203+
},
204+
"outputs": [],
205+
"source": [
206+
"def _get_index_data(data, index=0):\n",
207+
" return data[index]"
208+
]
209+
},
210+
{
211+
"cell_type": "code",
212+
"execution_count": null,
213+
"metadata": {
214+
"collapsed": false
215+
},
216+
"outputs": [],
217+
"source": [
218+
"def get_data():\n",
219+
" income = data.ix[:, 0].apply(lambda x: _get_index_data(x, year_slider.value-1800))\n",
220+
" life_exp = data.ix[:, 1].apply(lambda x: _get_index_data(x, year_slider.value-1800))\n",
221+
" pop = data.ix[:, 3].apply(lambda x: _get_index_data(x, year_slider.value-1800))\n",
222+
" return income, life_exp, pop"
223+
]
224+
},
225+
{
226+
"cell_type": "code",
227+
"execution_count": null,
228+
"metadata": {
229+
"collapsed": true
230+
},
231+
"outputs": [],
232+
"source": [
233+
"cap_income, life_exp, pop = get_data()"
234+
]
235+
},
236+
{
237+
"cell_type": "markdown",
238+
"metadata": {},
239+
"source": [
240+
"### Creating the Tooltip to display the required fields"
241+
]
242+
},
243+
{
244+
"cell_type": "code",
245+
"execution_count": null,
246+
"metadata": {
247+
"collapsed": true
248+
},
249+
"outputs": [],
250+
"source": [
251+
"tt = Tooltip(fields=['name', 'x', 'y'], labels=['Country Name', 'Income per Capita', 'Life Expectancy'])"
252+
]
253+
},
254+
{
255+
"cell_type": "markdown",
256+
"metadata": {},
257+
"source": [
258+
"### Creating the Scatter Mark with the appropriate size and color parameters passed"
259+
]
260+
},
261+
{
262+
"cell_type": "code",
263+
"execution_count": null,
264+
"metadata": {
265+
"collapsed": false
266+
},
267+
"outputs": [],
268+
"source": [
269+
"wealth_scat = Scatter(x=cap_income, y=life_exp, color=data['region'], size=pop, names=data['name'],\n",
270+
" display_names=False, scales={'x': x_sc, 'y': y_sc, 'color': c_sc, 'size': size_sc},\n",
271+
" default_size=4112, tooltip=tt, animate=True, stroke='Black')"
272+
]
273+
},
274+
{
275+
"cell_type": "markdown",
276+
"metadata": {},
277+
"source": [
278+
"### Creating the Figure"
279+
]
280+
},
281+
{
282+
"cell_type": "code",
283+
"execution_count": null,
284+
"metadata": {
285+
"collapsed": false
286+
},
287+
"outputs": [],
288+
"source": [
289+
"fig = Figure(marks=[wealth_scat], axes=[ax_x, ax_y], title='Health and Wealth of Nations', fig_color='White',\n",
290+
" animation_duration=100)"
291+
]
292+
},
293+
{
294+
"cell_type": "markdown",
295+
"metadata": {},
296+
"source": [
297+
"### Defining the callback for the slider"
298+
]
299+
},
300+
{
301+
"cell_type": "code",
302+
"execution_count": null,
303+
"metadata": {
304+
"collapsed": false
305+
},
306+
"outputs": [],
307+
"source": [
308+
"def year_changed(new):\n",
309+
" wealth_scat.x, wealth_scat.y, wealth_scat.size = get_data()\n",
310+
" \n",
311+
"year_slider.observe(year_changed, 'value')"
312+
]
313+
},
314+
{
315+
"cell_type": "markdown",
316+
"metadata": {},
317+
"source": [
318+
"### Defining the callback for the button"
319+
]
320+
},
321+
{
322+
"cell_type": "code",
323+
"execution_count": null,
324+
"metadata": {
325+
"collapsed": true
326+
},
327+
"outputs": [],
328+
"source": [
329+
"def button_clicked(value):\n",
330+
" animate_button.visible = False\n",
331+
" for i in range(1800, 2009, 1):\n",
332+
" year_slider.value = i\n",
333+
" sleep(0.05)\n",
334+
" animate_button.visible = True\n",
335+
"\n",
336+
"animate_button.on_click(button_clicked)"
337+
]
338+
},
339+
{
340+
"cell_type": "markdown",
341+
"metadata": {},
342+
"source": [
343+
"### Displaying the GUI"
344+
]
345+
},
346+
{
347+
"cell_type": "code",
348+
"execution_count": null,
349+
"metadata": {
350+
"collapsed": false,
351+
"scrolled": true
352+
},
353+
"outputs": [],
354+
"source": [
355+
"display(VBox([animate_button, fig, year_slider]))"
356+
]
357+
}
358+
],
359+
"metadata": {
360+
"kernelspec": {
361+
"display_name": "Python 2",
362+
"language": "python",
363+
"name": "python2"
364+
},
365+
"language_info": {
366+
"codemirror_mode": {
367+
"name": "ipython",
368+
"version": 2
369+
},
370+
"file_extension": ".py",
371+
"mimetype": "text/x-python",
372+
"name": "python",
373+
"nbconvert_exporter": "python",
374+
"pygments_lexer": "ipython2",
375+
"version": "2.7.11"
376+
},
377+
"widgets": {
378+
"state": {},
379+
"version": "2.0.0-dev"
380+
}
381+
},
382+
"nbformat": 4,
383+
"nbformat_minor": 0
384+
}

examples/data_files/nations.json

+1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)