Comparison interfaces#

Comparing the plotting and models interfaces.

Importing libraries and packages#

 1# Warnings
 2import warnings
 3
 4# Mathematical operations and data manipulation
 5import pandas as pd
 6import numpy as np
 7
 8# Visualisation
 9from bokeh.plotting import figure
10from bokeh.io import show
11from bokeh.models.grids import Grid
12from bokeh.models.plots import Plot
13from bokeh.models.axes import LinearAxis
14from bokeh.models.ranges import Range1d
15from bokeh.models.glyphs import Line, Cross
16from bokeh.models.sources import ColumnDataSource
17from bokeh.models.tickers import SingleIntervalTicker
18from bokeh.models.annotations import Title, Legend, LegendItem
19
20# Output
21from bokeh.io import output_notebook
22
23output_notebook()
24warnings.filterwarnings("ignore")
Loading BokehJS ...

Set paths#

1# Path to datasets directory
2data_path = "./datasets"
3# Path to assets directory (for saving results to)
4assets_path = "./assets"

Loading dataset#

1dataset = pd.read_csv(f"{data_path}/world_population.csv", index_col=0)

Exploring dataset#

1# Shape of the dataset
2print("Shape of the dataset: ", dataset.shape)
3# Head
4dataset.head()
Shape of the dataset:  (264, 60)
Country Code Indicator Name Indicator Code 1960 1961 1962 1963 1964 1965 1966 ... 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
Country Name
Aruba ABW Population density (people per sq. km of land ... EN.POP.DNST NaN 307.972222 312.366667 314.983333 316.827778 318.666667 320.622222 ... 562.322222 563.011111 563.422222 564.427778 566.311111 568.850000 571.783333 574.672222 577.161111 NaN
Andorra AND Population density (people per sq. km of land ... EN.POP.DNST NaN 30.587234 32.714894 34.914894 37.170213 39.470213 41.800000 ... 180.591489 182.161702 181.859574 179.614894 175.161702 168.757447 161.493617 154.863830 149.942553 NaN
Afghanistan AFG Population density (people per sq. km of land ... EN.POP.DNST NaN 14.038148 14.312061 14.599692 14.901579 15.218206 15.545203 ... 39.637202 40.634655 41.674005 42.830327 44.127634 45.533197 46.997059 48.444546 49.821649 NaN
Angola AGO Population density (people per sq. km of land ... EN.POP.DNST NaN 4.305195 4.384299 4.464433 4.544558 4.624228 4.703271 ... 15.387749 15.915819 16.459536 17.020898 17.600302 18.196544 18.808215 19.433323 20.070565 NaN
Albania ALB Population density (people per sq. km of land ... EN.POP.DNST NaN 60.576642 62.456898 64.329234 66.209307 68.058066 69.874927 ... 108.394781 107.566204 106.843759 106.314635 106.013869 105.848431 105.717226 105.607810 105.444051 NaN

5 rows × 60 columns

Visualisation#

 1# Taking the mean population density for each year and compare its
 2# growth to the one of Japan
 3years = [year for year in dataset.columns if not year[0].isalpha()]
 4mean_pop_vals = [np.mean(dataset[year]) for year in years]
 5jp_vals = [dataset.loc[["Japan"]][year] for year in years]
 6
 7# Plotting the global population density change and the one for Japan
 8plot = figure(
 9    title="Global Mean Population Density compared to Japan",
10    x_axis_label="Year",
11    y_axis_label="Population Density",
12)
13
14plot.line(years, mean_pop_vals, line_width=2, legend_label="Global Mean")
15plot.cross(years, jp_vals, legend_label="Japan", line_color="red")
16
17plot.legend.location = "bottom_right"
18
19show(plot)
 1# Defining the range for the x and y-axis
 2extracted_mean_pop_vals = [
 3    val
 4    for i, val in enumerate(mean_pop_vals)
 5    if i not in [0, len(mean_pop_vals) - 1]
 6]
 7extracted_jp_vals = [
 8    jp_val["Japan"]
 9    for i, jp_val in enumerate(jp_vals)
10    if i not in [0, len(jp_vals) - 1]
11]
12
13min_pop_density = min(extracted_mean_pop_vals)
14min_jp_densitiy = min(extracted_jp_vals)
15min_y = int(min(min_pop_density, min_jp_densitiy))
16
17max_pop_density = max(extracted_mean_pop_vals)
18max_jp_densitiy = max(extracted_jp_vals)
19max_y = int(max(max_jp_densitiy, max_pop_density))
20
21xdr = Range1d(int(years[0]), int(years[-1]))
22ydr = Range1d(min_y, max_y)
23
24# Creating the axes
25axis_def = dict(
26    axis_line_color="#222222",
27    axis_line_width=1,
28    major_tick_line_color="#222222",
29    major_label_text_color="#222222",
30    major_tick_line_width=1,
31)
32
33x_axis = LinearAxis(
34    ticker=SingleIntervalTicker(interval=10), axis_label="Year", **axis_def
35)
36
37y_axis = LinearAxis(
38    ticker=SingleIntervalTicker(interval=50),
39    axis_label="Population Density",
40    **axis_def,
41)
42
43# Creating the plot object
44title = Title(
45    align="left", text="Global Mean Population Density compared to Japan"
46)
47
48plot = Plot(
49    x_range=xdr, y_range=ydr, plot_width=650, plot_height=600, title=title
50)
51
52# creating the data display
53line_source = ColumnDataSource(dict(x=years, y=mean_pop_vals))
54
55line_glyph = Line(x="x", y="y", line_color="#2678b2", line_width=2)
56
57cross_source = ColumnDataSource(dict(x=years, y=jp_vals))
58
59cross_glyph = Cross(x="x", y="y", line_color="#fc1d26")
60
61# Assembling the plot
62plot.add_layout(x_axis, "below")
63plot.add_layout(y_axis, "left")
64
65line_renderer = plot.add_glyph(line_source, line_glyph)
66cross_renderer = plot.add_glyph(cross_source, cross_glyph)
67
68# Creating the legend
69legend_items = [
70    LegendItem(label="Global Mean", renderers=[line_renderer]),
71    LegendItem(label="Japan", renderers=[cross_renderer]),
72]
73
74legend = Legend(items=legend_items, location="bottom_right")
75
76# Creating the grid
77x_grid = Grid(dimension=0, ticker=x_axis.ticker)
78y_grid = Grid(dimension=1, ticker=y_axis.ticker)
79
80# Adding the legend and grids to the plot
81plot.add_layout(legend)
82plot.add_layout(x_grid)
83plot.add_layout(y_grid)
84
85show(plot)

Nearly the same result. The models interface is not very convenient to build simple plots like these, but in some cases elements for interactions from the models interface can be handy.