I use cytsocape and cytoscape.js when I would like to draw molecular network. Molecular network can be made from similarity, matched molecular pair etc. In cytoscape there is a plug in for drawing chemical structures named ‘chemviz‘. There is no plugin for cytoscape.js. So it is needed for drawing function which draw chemical structures as node.
Recent version of RDKit provides SVG rendering function of chemical structure. Today I tried to molecular network which shows structures as nodes.
For convenience, I used cyjupyter which is an interactive network visualizer for Jupyter notebook. Referred the discussion, cytoscape.js can render the node with SVG as background-image. I used parse.quote function instead of encodeURLComponent because I wrote the code with python. ;)
Let’s try!
At first, I imported some libraries for drawing network and read sample data which got from rdkit/contrib/mmpa/data.
import networkx as nx from networkx.readwrite import cytoscape_data from rdkit import Chem from rdkit.Chem import RDConfig from rdkit.Chem import AllChem from rdkit.Chem import DataStructs from rdkit.Chem import rdChemReactions from rdkit.Chem.Draw import rdMolDraw2D import cyjupyter from cyjupyter import Cytoscape import os from urllib import parse mmp_path = os.path.join(RDConfig.RDContribDir, "mmpa/data/sample_mmps_default.csv") lines = [] with open(mmp_path, 'r') as f: for line in f: lines.append(line.rstrip().split(',')) nodes = set() for line in lines: nodes.add(line[0]) nodes.add(line[1]) nodes = list(nodes) print(str(len(nodes))+' mols')
Data format of sample_mmps_default.csv is molA, molB, id_mol_A, id_mol_B, transform. So I used molA and molB for input.
Next I defined the converter which transform SMIELS to image. Default setting of parse.quote is safe=”/”. I used safe=”” because I would like to escape the option.
def smi2svg(smi): mol = Chem.MolFromSmiles(smi) try: Chem.rdmolops.Kekulize(mol) except: pass drawer = rdMolDraw2D.MolDraw2DSVG(400, 200) AllChem.Compute2DCoords(mol) drawer.DrawMolecule(mol) drawer.FinishDrawing() svg = drawer.GetDrawingText().replace("svg:", "") return svg def smi2image(smi): svg_string = smi2svg(smi) impath = 'data:image/svg+xml;charset=utf-8,' + parse.quote(svg_string, safe="") return impath
Next, make MMP network with networkx and convert the data to cytoscape readable format. It is very simple. Please see below.
g = nx.Graph() for node in nodes: g.add_node(node, img=smi2image(node)) for line in lines: g.add_edge(line[0], line[1]) cy_g = cytoscape_data(g)
Now almost there. Define style settings. Key point of the part is setting of background-image of nodes. It can get each node img attribute with ‘data(img)’.
stobj=[ {'style': [{'css': { 'background-color': 'blue', 'shape' : 'rectangle', 'width':800, 'height':400, 'border-color': 'rgb(0,0,0)', 'border-opacity': 1.0, 'border-width': 0.0, 'color': '#4579e8', 'background-image':'data(img)', 'background-fit':'contain' }, 'selector': 'node'}, {'css': { 'width': 20.0, }, 'selector': 'edge'} ], }]
OK let’s draw network!
cyobj=Cytoscape(data=cy_g, visual_style=stobj[0]['style'], layout_name='cose') cyobj

It worked fine. The example is very simple and small. Network can have many attribute on not only nodes but also edges. And use can set many style settings.
Rendering structure on the fly and visualize it as node is useful and interesting tips I think.
I uploaded the code above on my github repo.
https://nbviewer.jupyter.org/github/iwatobipen/playground/blob/master/cytoscapejs_py.ipynb
Hi iwatobi-san,
Thanks for the tip. I managed to use this with the addition of incorporating Tanimoto coefficient like in you did in previous cyjupyter post. I’m wondering if you know how to display the names of the chemicals in the network as well? That would be even more useful.
Hi Yossa,
Thank you for your comment.
I think you should use set ‘context’ in styles. I will show you an example about it.