In [1]:
import pandas as pd
import numpy as np

from IPython.core.display import HTML, display

from bokeh.embed import file_html
from bokeh.models import ColumnDataSource, Patches, HoverTool, TapTool, Plot, Range1d, Slider
from bokeh.palettes import Blues9
from bokeh.plotting import vplot
from bokeh.resources import Resources

from constants import PLOT_FORMATS

map_data = pd.read_hdf('data/province_map_data.hdf', 'df')
map_data.sort('alpha', inplace=True)
data = pd.read_csv('data/sample_data_by_year.csv')
all_data = map_data.merge(data)

def color_data(data, columns_to_colorify, data_min=None, data_max=None, palette=Blues9):
    # data - the data frame which you are adding colored values to
    # columns_to_colorify - a list of strings which select the columns
    
    if data_min is None:
        num_only = data[columns_to_colorify]
        global_min = num_only.min().min()
        data_min = np.floor(global_min)

    if data_max is None:
        num_only = data[columns_to_colorify]
        global_max = num_only.max().max()
        data_max = np.ceil(global_max)
    
    data_range = data_max - data_min
    bin_factor = data_range / len(palette)
    
    def _get_color(value, palette):
        index = int(value / bin_factor)
        return palette[index - 1]

    for column_name in columns_to_colorify:
        color_name = '%s_color' % column_name
        data[color_name] = data['%s' % column_name].apply(_get_color, args=([palette]))
    return data

colored_data = color_data(all_data, [str(x) for x in range(1990, 2015)])
source = ColumnDataSource(colored_data)

def setup_china_map_plot(start_time, plot_width=600, x_range=[70, 140], y_range=[10, 60], title=""):
    aspect_ratio = (x_range[1] - x_range[0]) / (y_range[1] - y_range[0])
    plot_height = int(plot_width / aspect_ratio)
    x_range = Range1d(x_range[0], x_range[1])
    y_range = Range1d(y_range[0], y_range[1])
    plot = Plot(
        x_range=x_range, 
        y_range=y_range, 
        title=title, 
        plot_width=plot_width, 
        plot_height=plot_height, 
        **PLOT_FORMATS)
    
    countries = Patches(
        xs='xs', 
        ys='ys',
        fill_color='%s_color' % start_time,
        line_color=Blues9[0]
    )    

    plot.add_glyph(source, countries)
        
    tooltips = "<span class='tooltip-text year'>%s</span>" % start_time                   
    tooltips += "<span class='tooltip-text country'>@name_en</span>"               
    tooltips += "<span class='tooltip-text value'>@%s</span>" % start_time                                    
    plot.add_tools(HoverTool(tooltips=tooltips))
    
    return plot

In [2]:
PLOT_WIDTH = 900
TITLE = 'Random data'
START_TIME = '1990'

map_box = setup_china_map_plot(START_TIME, plot_width=PLOT_WIDTH, title=TITLE)

css = """
.bk-plot-wrapper table tr td, 
table, td, tr {
  border: none !important;
  padding: 0 !important;
  margin: 0 !important;
}

.bk-canvas {
  clear: both;
  position: absolute;
}
.bk-canvas-wrapper {
  position: relative;
  float: left;
}
.bk-tooltip {
  position: absolute;
  padding: 5px;
  border: 1px solid #1e4b6c;
  background-color: #1e4b6c;
  border-radius: 5px;
  pointer-events: none;
}
.bk-tooltip.bk-left::before {
  position: absolute;
  margin: -7px 0 0 0;
  top: 50%;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 7px 0 7px 0;
  border-color: transparent;
  content: " ";
  display: block;
  left: -10px;
  border-right-width: 10px;
  border-right-color: #1e4b6c;
}
.bk-tooltip.bk-right::after {
  position: absolute;
  margin: -7px 0 0 0;
  top: 50%;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 7px 0 7px 0;
  border-color: transparent;
  content: " ";
  display: block;
  right: -10px;
  border-left-width: 10px;
  border-left-color: #1e4b6c;
}
.bk-tooltip.bk-tooltip-custom.bk-left::before {
  border-right-color: black;
}
.bk-tooltip.bk-tooltip-custom.bk-right::after {
  border-left-color: black;
}
.bk-tooltip.bk-tooltip-custom {
  border-color: black;
  background-color: white;
}


/* MY CUSTOM STYLING */
.bk-tooltip.bk-tooltip-custom {
    background-color: black !important;
    opacity: 0.9;
    color: white;
    font-size: 0.8em;
    padding: 0.5em 1.5em;
}

.bk-tooltip.bk-tooltip-custom:before {
    border: none !important;
}

.bk-tooltip.bk-tooltip-custom:after {
    border: none !important;
}

.tooltip-text {
    clear: both;
    float: left;
}
.tooltip-text.country {
    font-weight: bold;
}
.tooltip-text.value {
    font-size: 1.2em;
    font-weight: bold;
    color: #FFA500;
}
"""
HTML('<style>{}</style>'.format(css))


Out[2]:

In [3]:
resources = Resources(mode='server', root_url='/tree/')
html = file_html(map_box, resources, "")
display(HTML(html))


Bokeh Plot

In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]: