In [1]:
from bokeh.plotting import *
from bokeh.objects import HoverTool, ColumnDataSource
from bokeh.sampledata import periodic_table
from collections import OrderedDict

elements = periodic_table.elements[periodic_table.elements['group'] != "-"]

group_range = [str(x) for x in range(1,19)]
period_range = [str(x) for x in reversed(sorted(set(elements['period'])))]

output_file("periodic.html")

colormap = {
    'alkali metal'         : "#a6cee3",
    'alkaline earth metal' : "#1f78b4",
    'halogen'              : "#fdbf6f",
    'metal'                : "#b2df8a",
    'metalloid'            : "#33a02c",
    'noble gas'            : "#bbbb88",
    'nonmetal'             : "#baa2a6",
    'transition metal'     : "#e08e79",
}

source = ColumnDataSource(
    data=dict(
        group=[str(x) for x in elements['group']],
        period=[str(y) for y in elements['period']],
        symx=[str(x)+":0.1" for x in elements['group']],
        numbery=[str(x)+":0.8" for x in elements['period']],
        massy=[str(x)+":0.15" for x in elements['period']],
        namey=[str(x)+":0.3" for x in elements['period']],
        sym=elements['symbol'],
        name=elements['name'],
        cpk=elements['CPK'],
        atomic_number=elements['atomic number'],
        electronic=elements['electronic configuration'],
        mass=elements['atomic mass'],
        type=elements['metal'],
        type_color=[colormap[x] for x in elements['metal']],
    )
)

hold()

rect("group", "period", 0.9, 0.9, source=source,
     x_range=group_range, y_range=period_range,
     fill_alpha=0.6, color="type_color",
     tools="resize,hover,previewsave", title="Periodic Table",
     plot_width=1200)

text_props = {
    "source": source,
    "angle": 0,
    "color": "black",
    "text_align": "left",
    "text_baseline": "middle"
}

text(x=dict(field="symx", units="data"),
     y=dict(field="period", units="data"),
     text=dict(field="sym", units="data"),
     text_font_style="bold", text_font_size="15pt", **text_props)

text(x=dict(field="symx", units="data"),
     y=dict(field="numbery", units="data"),
     text=dict(field="atomic_number", units="data"),
     text_font_size="9pt", **text_props)

text(x=dict(field="symx", units="data"),
     y=dict(field="namey", units="data"),
     text=dict(field="name", units="data"),
     text_font_size="6pt", **text_props)

text(x=dict(field="symx", units="data"),
     y=dict(field="massy", units="data"),
     text=dict(field="mass", units="data"),
     text_font_size="5pt", **text_props)

grid().grid_line_color = None

hover = [t for t in curplot().tools if isinstance(t, HoverTool)][0]
hover.tooltips = OrderedDict([
    ("name", "@name"),
    ("atomic number", "@atomic_number"),
    ("type", "@type"),
    ("atomic mass", "@mass"),
    ("CPK color", "$color[hex, swatch]:cpk"),
    ("electronic configuration", "@electronic"),
])

show()

In [1]:
from __future__ import division

import numpy as np
from six.moves import zip
from collections import OrderedDict
from bokeh.plotting import *
from bokeh.objects import HoverTool

# Create a set of tools to use
TOOLS="pan,wheel_zoom,box_zoom,reset,hover"

xx, yy = np.meshgrid(xrange(0,101,4), xrange(0,101,4))
x = xx.flatten()
y = yy.flatten()
N = len(x)
inds = [str(i) for i in np.arange(N)]
radii = np.random.random(size=N)*0.4 + 1.7
colors = [
    "#%02x%02x%02x" % (r, g, 150) for r, g in zip(np.floor(50+2*x), np.floor(30+2*y))
]

# EXERCISE: create a new data field for the hover tool to interrogate. It can be
# anything you like, but it needs to have the same length as x, y, etc.
foo = list(itertools.permutations("abcdef"))[:N]
bar = np.random.normal(size=N)

# We need to put these data into a ColumnDataSource
source = ColumnDataSource(
    data=dict(
        x=x,
        y=y,
        radius=radii,
        colors=colors,
        foo=foo,
        bar=bar,
    )
)

# EXERCISE: output static HTML file
output_file("scatter.html")

hold()

# This is identical to the scatter exercise, but adds the 'source' parameter
circle(x, y, radius=radii, source=source, tools=TOOLS,
       fill_color=colors, fill_alpha=0.6,
       line_color=None, Title="Hoverful Scatter")

# EXERCISE (optional) add a `text` renderer to display the index of each circle
# inside the circle
text(x, y, text=inds, alpha=0.5, text_font_size="5pt",
     text_baseline="middle", text_align="center", angle=0)

# EXERCISE: try other "marker-like" renderers besides `circle`

# We want to add some fields for the hover tool to interrogate, but first we
# have to get ahold of the tool. This will be made easier in future releases.
hover = [t for t in curplot().tools if isinstance(t, HoverTool)][0]

# EXERCISE: add some new tooltip (name, value) pairs. Variables from the
# data source are available with a "@" prefix, e.g., "@x" will display the
# x value under the cursor. There are also some special known values that
# start with "$" symbol:
#   - $index     index of selected point in the data source
#   - $x, $y     "data" coordinates under cursor
#   - $sx, $sy   canvas coordinates under cursor
#   - $color     color data from data source, syntax: $color[options]:field_name
# NOTE: we use an OrderedDict to preserve the order in the displayed tooltip
hover.tooltips = OrderedDict([
    # add to this
    ("index", "$index"),
    ("(x,y)", "($x, $y)"),
    ("radius", "@radius"),
    ("fill color", "$color[hex, swatch]:fill_color"),
    ("foo", "@foo"),
    ("bar", "@bar"),
])

show()  # open a browser


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-82fbe9fd271e> in <module>()
     10 TOOLS="pan,wheel_zoom,box_zoom,reset,hover"
     11 
---> 12 xx, yy = np.meshgrid(xrange(0,101,4), xrange(0,101,4))
     13 x = xx.flatten()
     14 y = yy.flatten()

NameError: name 'xrange' is not defined

In [ ]: