Hi Community,
I’m attempting to use Bokeh to create plots annotated with tooltip chemical structures in Jupyter notebooks. Because the number of plot elements can be extremely high, and molecular structure generation from a chemical description (SMILES) is expensive, I would like to implement this on-demand, in a JavaScript function that is called on hover.
As an example, this is the desired functionality, but it requires all SVGs to be pre-computed, here by calling the function make_svg in Python.
from bokeh.plotting import ColumnDataSource, figure, show
from rdkit.Chem import MolFromSmiles
from rdkit.Chem.Draw import rdMolDraw2D
def make_svg(smiles: str): # return SVG str from SMILES str
x = rdMolDraw2D.MolDraw2DSVG(100, 100)
x.DrawMolecule(MolFromSmiles(smiles))
x.FinishDrawing()
return x.GetDrawingText()
source = ColumnDataSource({'X':[1], 'Y':[1],
'smiles':['c1ccccc1'],
'svg':[make_svg('c1ccccc1')]})
p = figure(tooltips="@svg")
p.circle('X', 'Y', size=10, source=source)
show(p)
What I really want is for the browser to compute that structure instead of Python. To that end, I tried to put together a call with an external tool instead, shown below.
<div>
<img data-smiles="c1ccccc1"
data-smiles-options="{'width':100,'height':100 }"/>
<script> type="text/javascript" src="https://unpkg.com/[email protected]/dist/smiles-drawer.min.js"></script>
<script>SmiDrawer.apply()</script>
</div>
And this produces the expected benzene ring in Jupyter. However, when I plug it into the tooltip string (either directly, or substituting @smiles for the dummy “c1cccccc1”) I only get an empty box on hover.
Unfortunately JavaScript and HTML are foreign to me, so I’m not sure if I need to debug or if I’m doing something fundamentally incorrect. Because I don’t get the expected benzene ring on hover even without @smiles substitution, I suspect that I can’t src scripts in this context, or I’m misunderstanding something else. Before I get too far into learning JS fundamentals, I’d appreciate any sanity or feasibility checks from the community. Thanks!