You can check out our preprint at https://github.com/KitchinHUB/kitchingroup-51 . We are going to adapt the code to make Figure 6a in the manuscript interactive. The code needed a somewhat surprising amount of adaptation. Apparently the ase database interface has changed a lot since we write that paper, so the code here looks a bit different than what we published. The biggest difference is due to name-mangling so each key that started with a number now starts with _, and and periods are replaced by _ also. The rest of the script is nearly unchanged. At the end is the very small bit of mpld3 code that generates the figure for html. We will add tooltips onto datapoints to indicate what the name associated with each data point is. Here is the code.
import matplotlib.pyplot as plt
from ase.db import connect
# loads the ASE database and select certain keywords
db = connect('~/Desktop/cappa/kitchingroup-51/supporting-information/data.json')
keys = ['bcc', 'GS', '_54atom', 'ensam']
CLS, IMP, labels = [], [], []
for k in db.select(keys + ['_1cl']):
name = k.keywords[-2]
Cu0 = db.select('bcc,GS,_72atom,_0cl,_1_00Cu').next().energy
Cu1 = db.select('bcc,GS,_72atom,_1cl,_1_00Cu').next().energy
x0 = db.select(','.join(keys + [name, '_0cl'])).next().energy
x1 = k.energy
cls0 = x0 - Cu0
cls1 = x1 - Cu1
IMP.append(int(name[1]))
CLS.append(cls1 - cls0)
labels += ['{0} ({1}, {2})'.format(name, int(name[1]), cls1 - cls0)]
Cu0 = db.select(','.join(['bcc', 'GS', '_72atom',
'_0cl', '_1_00Cu'])).next().energy
Cu1 = db.select(','.join(['bcc', 'GS', '_72atom',
'_1cl', '_1_00Cu'])).next().energy
x0 = db.select(','.join(['bcc', 'GS', '_54atom',
'_0cl', '_1'])).next().energy
x1 = db.select(','.join(['bcc', 'GS', '_54atom',
'_1cl', '_1'])).next().energy
cls0 = x0 - Cu0
cls1 = x1 - Cu1
IMP.append(1)
CLS.append(cls1 - cls0)
labels += ['(1, {0})'.format(cls1 - cls0)]
Cu0 = db.select(','.join(['bcc', 'GS', '_72atom',
'_0cl', '_1_00Cu'])).next().energy
Cu1 = db.select(','.join(['bcc', 'GS', '_72atom',
'_1cl', '_1_00Cu'])).next().energy
x0 = db.select(','.join(['bcc', 'GS', '_54atom',
'_0cl', '_0'])).next().energy
x1 = db.select(','.join(['bcc', 'GS', '_54atom',
'_1cl', '_0'])).next().energy
cls0 = x0 - Cu0
cls1 = x1 - Cu1
IMP.append(0)
CLS.append(cls1 - cls0)
labels += ['(0, {0})'.format(cls1 - cls0)]
fig = plt.figure()
p = plt.scatter(IMP, CLS, c='g', marker='o', s=25)
ax1 = plt.gca()
ax1.set_ylim(-1.15, -0.6)
ax1.set_xlim(-0.1, 5.1)
ax1.set_xlabel('# Cu Nearest neighbors')
ax1.set_ylabel('Cu 2p(3/2) Core Level Shift (eV)')
ax1.set_title('Hover over a point to see the calculation name')
# Now the mpld3 stuff.
import mpld3
from mpld3 import plugins
tooltip = plugins.PointHTMLTooltip(p, labels, voffset=0, hoffset=10)
plugins.connect(fig, tooltip)
print mpld3.fig_to_html(fig)
I like this workflow pretty well. It seems less functional than plotly and Bokeh (e.g. it does not look like it you can export the data from the html here), but it is well integrated with Matplotlib, with my blogging style, and does not require a server, oran account. The code outputs html that is self-contained in the body of the html. The smooth integration with Matplotlib means I could have static images in org-mode, and dynamic images in HTML potentially. Overall, this is a nice tool for making interactive plots in blog posts.