Make MMP network and send to cytoscape #chemoinfo

Recently I use cytoscape in my laboratory. You know Cytoscape is nice tool for network visualization.
I often make data with python and import data from cytoscape. The work flow is not so bad but I am thinking that it will be nice if python can communicate with cytoscape.
Fortunately cytocape has REST plugin called cyREST and also python has py2cytoscape to do it!
It sounds nice. I tried to use these libraries.
At first I installed cyREST to my cytoscape (v3.5.1). appmanager => cyREST >
And also I installed chemviz for drawing chemical structure in cytoscape.
Then install py2cytoscape via pip. ;-)
You can access localhost:1234/v1 from web blowser when cytoscape launched if cyREST is successfully installed.

Ready.
I drew simple MMP network. Code is below.
First, I made MMP from SMILES file by using RDKit MMP script.

$ cat testdata.smi
Oc1ccccc1 phenol
Oc1ccccc1O catechol
Oc1ccccc1N 2-aminophenol
Oc1ccccc1Cl 2-chlorophenol
Nc1ccccc1N o-phenylenediamine
Nc1cc(O)ccc1N amidol
Oc1cc(O)ccc1O hydroxyquinol
Nc1ccccc1 phenylamine
C1CCCC1N cyclopentanol
$ python rfrag.py < testdata.smi> testdata.frag
$ python indexing.py < testdata.frag > testmmp.txt -r 0.2
$ cat testmmp.txt
Oc1ccccc1,Nc1ccccc1,phenol,phenylamine,O[*:1]>>N[*:1],c1ccc(cc1)[*:1]
Nc1cc(O)ccc1N,Nc1ccccc1N,amidol,o-phenylenediamine,O[*:1]>>[*:1][H],Nc1ccc(cc1N)[*:1]
Oc1ccccc1N,Nc1ccccc1N,2-aminophenol,o-phenylenediamine,O[*:1]>>N[*:1],Nc1ccccc1[*:1]
Oc1ccccc1N,Nc1ccccc1,2-aminophenol,phenylamine,O[*:1]>>[*:1][H],Nc1ccccc1[*:1]
Nc1ccccc1N,Nc1ccccc1,o-phenylenediamine,phenylamine,N[*:1]>>[*:1][H],Nc1ccccc1[*:1]
Oc1ccccc1O,Oc1ccccc1N,catechol,2-aminophenol,O[*:1]>>N[*:1],Oc1ccccc1[*:1]
Oc1ccccc1O,Oc1ccccc1Cl,catechol,2-chlorophenol,O[*:1]>>Cl[*:1],Oc1ccccc1[*:1]
Oc1ccccc1O,Oc1ccccc1,catechol,phenol,O[*:1]>>[*:1][H],Oc1ccccc1[*:1]
Oc1ccccc1N,Oc1ccccc1Cl,2-aminophenol,2-chlorophenol,N[*:1]>>Cl[*:1],Oc1ccccc1[*:1]
Oc1ccccc1N,Oc1ccccc1,2-aminophenol,phenol,N[*:1]>>[*:1][H],Oc1ccccc1[*:1]
Oc1ccccc1Cl,Oc1ccccc1,2-chlorophenol,phenol,Cl[*:1]>>[*:1][H],Oc1ccccc1[*:1]
Oc1cc(O)ccc1O,Oc1ccccc1O,hydroxyquinol,catechol,O[*:1]>>[*:1][H],Oc1ccc(cc1O)[*:1]

Now I got MMP data I used the data to make edge of my network and testdata.smi is used to make node data.

Next code is example for communication between python and cytoscape.
At first, import CyRestClient and make connection. Default URL is localhost and port is 1234. But if user would like to use another IP and Port, user can modify from cytoscape.
Edit => Preferences => add => rest.url xxxxx, rest.port xxxx

I used python-igraph for making graph but py2cytoscape handle data generated by networkx, geohi and something.

import igraph
from py2cytoscape.data.cyrest_client import CyRestClient
import py2cytoscape

cy = CyRestClient()
cy.session.delete()
G = igraph.Graph()

with open('testdata.smi', 'r') as vertexis:
    for v in vertexis:
        G.add_vertex(v.split(' ')[0], molname=v.split(' ')[1])

with open("testmmp.txt", "r") as edges:
    for edge in edges:
        G.add_edge(edge.split(",")[0], edge.split(",")[1], transform=edge.split(",")[4])

After making network, go to next step.
network_create_from_igraph method receives data from igraph and send to cytoscape.
Then I set network layout ‘force-directed’.
Finally I set some view style and update the graph settings.

g_cy = cy.network.create_from_igraph(G)
cy.layout.apply(name='force-directed', network=g_cy)

mystyle = cy.style.create('mystyle')

defaults = {
    'NODE_HIGHT': 100,
    'NODE_WIDTH': 100,
    'NODE_FILL_COLOR': "#87CEFA",
    'NODE_BORDER_WIDTH': 5,
    'NODE_BORDER_PAINT': '#FFFFFF',
    'NODE_LABEL_FONT_SIZE': 14,
    'NODE_LABEL_COLOR': '#555555',
    'EDGE_TRANSPARENCY': 100,
    'EDGE_WIDTH': 20,
    'EDGE_STROKE_UNSELECTED_PAINT': '#FFFFFF',
    'NETWORK_BACKGROUND_PAINT': '#3B426F'
}

mystyle.update_defaults(defaults)
cy.style.apply(mystyle, network=g_cy)

View screenshots.
Before run the code, there is no network in cytoscape.

After run the code I could see MMP network without chemical structure.

Finally I set chemviz setting and run paint structure from menu, I could see structure on each node.

And also each node and edge has their own attribute that is set by igraph.
It interesting and useful because all work is done by using only python!

This example is one way python => cytoscape. But the library can send data in both directions.
There are nice documents written in Japanese such like a following URL.
https://qiita.com/keiono/items/ed796643107bd03aff64
Enjoy!

Advertisements

Cytoscape and MMP

I posted an example about cytoscape.js using molecular similarity.
Cytoscape.js is cool but not good for lots of data. I tried to make network that has 1000 nodes. My PC freeze….
So I go back to cytoscape.
Today I made network from mmpa data for example.
If you had rdkit, make mmp is very easy.
First, I got sample data from Chembl (Jak3 inh.) as tsv.
For rdkit, file format must be, smiles id.
Let’s make it.
I used PANDAS for do it.

import pandas as pd
datatab = pd.read_table("bioactivity-14_7-19-38.txt", header=0)
datatab.columns
smi = datatab[[u'CANONICAL_SMILES', u'CMPD_CHEMBLID']]
smi.to_csv("smiles.smi", header=False, index=False)

Then make fragment file from smiles.
MMPA scripts are $RDBASE/Contrib/mmp .

iwatobipen$ wc bioactivity-14_7-19-38.txt 
     829   51884  448065 bioactivity-14_7-19-38.txt # 829 mols in this file.
iwatobipen$ time python ../rfrag.py < smiles.smi > frag.smi

real	3m50.721s
user	3m49.754s
sys	0m0.388s

iwatobipen$ wc frag.smi 
   42031   42031 6558703 frag.smi # 42031 frags made!

Next, make pair.

iwatobipen$ time python ../indexing.py < frag.smi > jak3_mmp.csv

real	0m31.788s
user	0m31.074s

sys	0m0.120s
iwatobipen$ wc jak3_mmp.csv 
    8466    8466 1729873 jak3_mmp.csv # Just done!

I got pair files jak3_mmp.csv.
This file has some field, SMILES_OF_LEFT_MMP,SMILES_OF_RIGHT_MMP,ID_OF_LEFT_MMP,ID_OF_RIGHT_MMP,SMIRKS_OF_TRANSFORMATION,SMILES_OF_CONTEXT.

I got mmp-csv file. Cytoscape can read this file.
So , from cytoscape, new network from file and SMILES_OF_LEFT_MMP as source, SMILES_OF_RIGHT_MMP as target.
Then layout set organic.
I used ChemViz to convert smiles to structure.
Screen Shot 2014-09-15 at 10.09.58 PM

Screen Shot 2014-09-15 at 10.11.08 PM

It’s easy to add node attribute(ex, activity, target, mol prop. etc…) and make your custom view using vizmapper.
I upload sample file to github. https://github.com/iwatobipen/mmp_example.
Be careful, this example code is incomplete, because this code ignore molecule that has no pair (singletone).

similarity network using cytoscape.js.

Lots of relationships are presented as graph.
For example, if I set molecule as node, and similarity as edge, I could make molecular networks.
Cytoscape.js is one of the good tool.
It is an open-source JavaScript graph theory library for analysis and visualisation. And works on server side. So, Not depend on client machine.
I wrote some examples.
If you interested in it, please read following ;-).

At first, I get sample data from Chembl.(Cyclin-dependent kinase 2)
Then load data and make network structure as json.

from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem import PandasTools
import pandas as pd
from rdkit.Chem import DataStructs
import json

df=pd.read_table( "bioactivity-14_6-07-32.txt", header=0 )
PandasTools.AddMoleculeColumnToFrame( df, smilesCol="CANONICAL_SMILES",molCol="ROMol" )
fps = [ AllChem.GetMorganFingerprintAsBitVect(mol,2) for mol in df.ROMol ]
nodes = []
edges = []

# make nodes
for i in range( len( fps [:100] ) ):
    cmp_id = df.CMPD_CHEMBLID[i]
    smi = df.CANONICAL_SMILES[i]
    node = { "data":{ "cmp_id":cmp_id, "smi":smi }}
    nodes.append(node)

# make edges
for i in range(len(fps[:100])):
    for j in range(i):
        tc = DataStructs.TanimotoSimilarity(fps[i],fps[j])
        if tc >= 0.6:
            source = df.CMPD_CHEMBLID[i]
            target = df.CMPD_CHEMBLID[j]
            edge = { "data": { "source":source, "target":target }}
            edges.append(edge)

# make json format data
data = { "nodes":nodes, "edges":edges}  

# write network to text
f = open("mols.json","w")
f.write(json.dumps(data))
f.close()

Now I got network data.
Then, let’s make the site using flask.

First, I wrote app.py.

from flask import Flask, url_for
from flask import render_template
from flask_bootstrap import Bootstrap
app  = Flask(__name__)
Bootstrap( app )
@app.route('/mol_network/')
def mol_network():
    return render_template("mol_network.html")
if __name__ =="__main__":
    app.run(debug = True)

Next, wrote template.html and mol_network.html.
Follwing code, links and any actions are blank.

temple.html

{% extends "bootstrap/base.html" %}
{% block title %} This is an example {% endblock %}
{% block navbar %}
{% block scripts %}
{{ super() }}
// set your placed folder following code.
<script src="{{url_for('static', filename='cytoscape/build/cytoscape.js')}}"></script>
{% endblock %}

<nav class="navbar navbar-default" role="navigation">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Brand</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
            <li class="divider"></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <form class="navbar-form navbar-left" role="search">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
{% endblock %}

{% block content %}
 <h1> hello, bootstrap </h1>
{% endblock %}

OK, now Make mol_network.html
Hmm, too long..

{% extends "temple.html" %}
{% block title %}network{% endblock title %}

{% block content %}
<style id="jsbin-css">

body { 
  font: 14px helvetica neue, helvetica, arial, sans-serif;
}

#cy {
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  top: 0;
}

#info {
  color: #c88;
  font-size: 1em;
  position: absolute;
  z-index: -1;
  left: 1em;
  top: 1em;
}
</style>

<script src="{{ url_for("static", filename="node_modules/cytoscape/lib/arbor.js") }}"></script>
</head>
  <body>     


<script>

var cy3json = {"nodes": [{"data": {"id": "CHEMBL186120", "smi": "CC(C)c1cnc(NC(=O)Oc2ccccc2)s1"}}, {"data": {"id": "CHEMBL362369", "smi": "CC(=O)c1cnc(NC(=O)Cc2ccccc2)s1"}}, {"data": {"id": "CHEMBL2347577", "smi": "CC[C@@H](Nc1nc(NCc2cc(F)ccc2O)c3ncn(C(C)C)c3n1)C(C)O"}}, {"data": {"id": "CHEMBL428690", "smi": "CN1CC[C@@H]([C@H](O)C1)c2c(O)cc(O)c3C(=O)C=C(Oc23)c4ccccc4Cl"}}, {"data": {"id": "CHEMBL186371", "smi": "O=C(Nc1cccc2[nH]nnc12)Nc3ncc(s3)C4CCC4"}}, {"data": {"id": "CHEMBL186898", "smi": "O=C(Cc1ccc2[nH]cnc2c1)Nc3ncc(s3)C4CCC4"}}, {"data": {"id": "CHEMBL593683", "smi": "CC(C)(C)c1cc2c(N\\N=C\\c3ccc(cc3)C(=O)O)ncnc2s1"}}, {"data": {"id": "CHEMBL2335928", "smi": "CCCn1cnc2c(NC(=N)N)nc(N)nc12"}}, {"data": {"id": "CHEMBL64758", "smi": "Brc1ccc2c(c1)[nH]c3c4[nH]c5ccccc5c4c6C(=O)NC(=O)c6c23"}}, {"data": {"id": "CHEMBL3115672", "smi": "Clc1ccc2C[C@@H](Cc2c1)NCc3cc(NC(=O)Nc4cccc5C(=O)N6CCCC6c45)n[nH]3"}}, {"data": {"id": "CHEMBL1094408", "smi": "COc1ccc(cc1Nc2ncc3CCc4c(nn(C)c4c3n2)C(=O)N)N5CCN(C)CC5"}}, {"data": {"id": "CHEMBL1952028", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(F)cc23"}}, {"data": {"id": "CHEMBL180341", "smi": "Oc1ccc2cnc(Nc3ccc(cc3)N4CCOCC4)nc2c1C5CCCC5"}}, {"data": {"id": "CHEMBL363711", "smi": "CC(C)C(=O)Nc1ncc(s1)C(C)C"}}, {"data": {"id": "CHEMBL1098686", "smi": "O\\N=C\\1/C(=C\\2/C(=O)Nc3ccc(Cl)cc23)/Nc4ccc(O)cc14"}}, {"data": {"id": "CHEMBL1086811", "smi": "O\\N=C\\1/C(=C\\2/C(=O)Nc3ccc(cc23)[N+](=O)[O-])/Nc4ccc(Cl)cc14"}}, {"data": {"id": "CHEMBL1087075", "smi": "O\\N=C\\1/C(=C\\2/C(=O)Nc3ccc(F)cc23)/Nc4ccc(F)cc14"}}, {"data": {"id": "CHEMBL1086701", "smi": "Cc1ccc2N\\C(=C\\3/C(=O)Nc4ccc(cc34)[N+](=O)[O-])\\C(=N/O)\\c2c1"}}, {"data": {"id": "CHEMBL369303", "smi": "Oc1[nH]c2ccc(cc2c1c3[nH]c4ccccc4c3N=O)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL2058161", "smi": "COc1ccc(cc1)c2nn(cc2CNc3ccc(Br)cc3)c4ccccc4"}}, {"data": {"id": "CHEMBL182325", "smi": "COc1ccc2cnc(Nc3ccc(cc3)N4CCN(CC4)C(=O)C)nc2c1C(C)C"}}, {"data": {"id": "CHEMBL2069718", "smi": "FCCNS(=O)(=O)c1cc(cs1)c2nc3ccccc3s2"}}, {"data": {"id": "CHEMBL2069719", "smi": "O=S(=O)(Nc1nccs1)c2cc(cs2)c3nc4ccccc4s3"}}, {"data": {"id": "CHEMBL2058160", "smi": "COc1ccc(cc1)c2nn(cc2CNc3ccc(Cl)cc3)c4ccccc4"}}, {"data": {"id": "CHEMBL2069717", "smi": "ONS(=O)(=O)c1cc(cs1)c2nc3ccccc3s2"}}, {"data": {"id": "CHEMBL2347581", "smi": "CC(C)n1cnc2c(NCc3ccccc3N)nc(NCCC(C)(C)O)nc12"}}, {"data": {"id": "CHEMBL187256", "smi": "O=C(Nc1cccc2ncccc12)Nc3ncc(s3)C4CCC4"}}, {"data": {"id": "CHEMBL2425654", "smi": "O[C@@H]1CC[C@H](CC1)Nc2nccc(n2)n3nnc4ccccc34"}}, {"data": {"id": "CHEMBL2403099", "smi": "CC(C)(O)CNc1nc(NCc2ccc(nc2)c3occc3)c4ncn(C5CCCC5)c4n1"}}, {"data": {"id": "CHEMBL182641", "smi": "COc1ccc2cnc(Nc3ccc(cc3)N4CCNCC4)nc2c1C(C)C"}}, {"data": {"id": "CHEMBL181834", "smi": "COc1ccc2cnc(Nc3ccc(cc3)N4CCN(CC4)C(=O)C)nc2c1C5CCCC5"}}, {"data": {"id": "CHEMBL1952200", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N4CC[C@H](O)C4)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL1952203", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N4CCCC(CO)C4)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL182011", "smi": "COc1ccc2cnc(Nc3ccc(cc3)N4CCOCC4)nc2c1C(C)C"}}, {"data": {"id": "CHEMBL1086662", "smi": "O\\N=C\\1/C(=C\\2/C(=O)Nc3ccc(F)cc23)/Nc4ccc(O)cc14"}}, {"data": {"id": "CHEMBL1164457", "smi": "CC(C)CN(C)C(=O)c1ccc2cc([nH]c2c1)c3cc(Cc4ccccc4)[nH]n3"}}, {"data": {"id": "CHEMBL1952027", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccccc23"}}, {"data": {"id": "CHEMBL182498", "smi": "COc1ccc2cnc(Nc3ccc(N4CCNCC4)c(F)c3)nc2c1C(C)C"}}, {"data": {"id": "CHEMBL133712", "smi": "CC(=O)c1cnc2oc3ccc(O)cc3c2c1c4ccccc4"}}, {"data": {"id": "CHEMBL434917", "smi": "CC(C)c1cnc(NC(=O)C(=O)c2ccccc2)s1"}}, {"data": {"id": "CHEMBL3093062", "smi": "C(Nc1oc(nn1)c2c[nH]c3ncccc23)c4ccccc4"}}, {"data": {"id": "CHEMBL3093056", "smi": "Fc1cc2cc(ccc2cn1)c3oc(NCc4ccccc4)nn3"}}, {"data": {"id": "CHEMBL2347584", "smi": "CC(C)CNc1nc(NCc2ccccc2O)c3ncn(C(C)C)c3n1"}}, {"data": {"id": "CHEMBL2336384", "smi": "CC(C)n1cnc2c(NC(=N)N)nc(NC3CC3)nc12"}}, {"data": {"id": "CHEMBL2425652", "smi": "N[C@@H]1CC[C@H](CC1)Nc2nccc(n2)n3nnc4ccccc34"}}, {"data": {"id": "CHEMBL595023", "smi": "CN(CCO)Cc1ccc(\\C=N\\Nc2ncnc3sc(cc23)C(C)(C)C)cc1"}}, {"data": {"id": "CHEMBL597754", "smi": "CNC(=O)c1nn(C)c2c1CCc3cnc(NC4CCN(CC4)C(=O)C5CCN(CC5)S(=O)(=O)C)nc23"}}, {"data": {"id": "CHEMBL2336375", "smi": "CC(C)n1cnc2c(NC(=N)N)nc(NCCCCCCO)nc12"}}, {"data": {"id": "CHEMBL2336374", "smi": "CC(C)n1cnc2c(NC(=N)N)nc(NCCCO)nc12"}}, {"data": {"id": "CHEMBL2347585", "smi": "CC(C)n1cnc2c(NCc3ccc(O)cc3)nc(nc12)N4CCNCC4"}}, {"data": {"id": "CHEMBL186932", "smi": "CCCCCc1cnc(NC(=O)Cc2ccccc2)s1"}}, {"data": {"id": "CHEMBL14762", "smi": "CC[C@H](CO)Nc1nc(NCc2ccccc2)c3ncn(C(C)C)c3n1"}}, {"data": {"id": "CHEMBL183511", "smi": "COc1ccc2cnc(Nc3ccc(cc3)N4CCC(N)C4)nc2c1C(C)C"}}, {"data": {"id": "CHEMBL185734", "smi": "CSc1cnc(NC(=O)Cc2ccccc2)s1"}}, {"data": {"id": "CHEMBL1086683", "smi": "O\\N=C\\1/C(=C\\2/C(=O)Nc3ccc(OC(F)(F)F)cc23)/Nc4ccc(O)cc14"}}, {"data": {"id": "CHEMBL1087073", "smi": "O\\N=C\\1/C(=C\\2/C(=O)Nc3ccc(cc23)[N+](=O)[O-])/Nc4ccc(F)cc14"}}, {"data": {"id": "CHEMBL1087074", "smi": "O\\N=C\\1/C(=C\\2/C(=O)Nc3ccc(Cl)cc23)/Nc4ccc(F)cc14"}}, {"data": {"id": "CHEMBL1087740", "smi": "COc1ccc2N\\C(=C\\3/C(=O)Nc4ccc(OC(F)(F)F)cc34)\\C(=N/O)\\c2c1"}}, {"data": {"id": "CHEMBL1922223", "smi": "CC[C@@H](Nc1nc(NCc2ccccc2)c3ncn(C(C)C)c3n1)C(=O)O"}}, {"data": {"id": "CHEMBL1738742", "smi": "CC[C@H](CO)Nc1nc(NCc2ccccc2)c3[nH]nc(C(C)C)c3n1"}}, {"data": {"id": "CHEMBL2069712", "smi": "NS(=O)(=O)c1cc(cs1)c2nc3ccc(F)cc3s2"}}, {"data": {"id": "CHEMBL2069724", "smi": "Oc1cccnc1NS(=O)(=O)c2cc(cs2)c3nc4ccccc4s3"}}, {"data": {"id": "CHEMBL2069728", "smi": "NS(=O)(=O)c1cc(cs1)c2nc3cccc(c4ccc(F)cc4)c3s2"}}, {"data": {"id": "CHEMBL2057888", "smi": "Cc1ccc(cc1)c2nn(cc2CNc3ccc(Cl)cc3)c4ccccc4"}}, {"data": {"id": "CHEMBL2336376", "smi": "CC[C@@H](N)COc1nc(NC(=N)N)c2ncn(C(C)C)c2n1"}}, {"data": {"id": "CHEMBL2349192", "smi": "CC(C)n1cnc2c(NCc3cc(Cl)ccc3O)nc(NC4CCC(O)CC4)nc12"}}, {"data": {"id": "CHEMBL361987", "smi": "Oc1ccc2cnc(Nc3ccc(N4CCNCC4)c(F)c3)nc2c1C5CCCC5"}}, {"data": {"id": "CHEMBL1922123", "smi": "CC[C@@H](Nc1nc(NCc2cccnc2)c3ncn(C(C)C)c3n1)C(C)(C)O"}}, {"data": {"id": "CHEMBL1922201", "smi": "CC[C@@H](Nc1nc(NCc2ccccc2)c3ncn(C(C)C)c3n1)C(O)C(C)C"}}, {"data": {"id": "CHEMBL1922204", "smi": "CC[C@H](Nc1nc(NCc2ccccn2)c3ncn(C(C)C)c3n1)C(C)O"}}, {"data": {"id": "CHEMBL1922207", "smi": "CC[C@H](Nc1nc(NCc2ccccn2)c3ncn(C(C)C)c3n1)C(O)C(C)(C)C"}}, {"data": {"id": "CHEMBL1952029", "smi": "COc1ccc2NC(=O)\\C(=C/c3[nH]ccc3OC)\\c2c1"}}, {"data": {"id": "CHEMBL1952032", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N4CCNC(C4)C(=O)N)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL1952208", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N4CC[C@@H](N)C4)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL2402946", "smi": "NC1CCC(CC1)Nc2nc(NCc3ccc(nc3)c4ccccc4O)c5ncn(C6CCCC6)c5n2"}}, {"data": {"id": "CHEMBL1922120", "smi": "CCC(O)[C@@H](CC)Nc1nc(NCc2cccnc2)c3ncn(C(C)C)c3n1"}}, {"data": {"id": "CHEMBL360250", "smi": "COc1ccc2cnc(Nc3ccc(cc3)N4CCN(CC4)C(=O)CN)nc2c1C(C)C"}}, {"data": {"id": "CHEMBL1164353", "smi": "CC(C)CN(C)C(=O)c1ccc2cc([nH]c2c1)c3n[nH]cc3c4ccccc4"}}, {"data": {"id": "CHEMBL1774056", "smi": "C[C@H](Nc1nc(Nc2cc(C)[nH]n2)c(F)cc1C#N)c3ccc(F)cn3"}}, {"data": {"id": "CHEMBL1952202", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N4CCC(O)CC4)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL1952209", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N4CC[C@H](C4)NC=O)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL361537", "smi": "CCOc1cnc2oc3ccc(O)cc3c2c1c4ccccc4"}}, {"data": {"id": "CHEMBL3093066", "smi": "C(Nc1oc(nn1)c2c[nH]c3ncccc23)c4ccccn4"}}, {"data": {"id": "CHEMBL3093060", "smi": "O=C1Nc2ccc(cc2O1)c3oc(NCc4ccccc4)nn3"}}, {"data": {"id": "CHEMBL3093055", "smi": "C(Nc1oc(nn1)c2ccc3cnccc3c2)c4ccccc4"}}, {"data": {"id": "CHEMBL1922217", "smi": "CC[C@H](Nc1nc(NCc2ccccc2)c3ncn(C(C)C)c3n1)C(C)(C)O"}}, {"data": {"id": "CHEMBL1952033", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N4CCCC(C4)C(=O)N)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL1949699", "smi": "COc1cc[nH]c1\\C=C\\2/C(=O)Nc3ccc(c(N[C@H]4CC[C@H](N)C4)c23)[N+](=O)[O-]"}}, {"data": {"id": "CHEMBL3093079", "smi": "Fc1ccc2c(c[nH]c2n1)c3oc(N[C@H](C4CC4)c5cccnc5F)nn3"}}, {"data": {"id": "CHEMBL2347586", "smi": "COc1ccc(CNc2nc(nc3c2ncn3C(C)C)N4CCNCC4)cc1"}}, {"data": {"id": "CHEMBL2347579", "smi": "CC[C@H](CO)Nc1nc(NCc2ccc(N)cc2)c3ncn(C(C)C)c3n1"}}, {"data": {"id": "CHEMBL2001835", "smi": "Nc1ccc2C(=S)c3ccccc3Nc2c1"}}, {"data": {"id": "CHEMBL2402947", "smi": "NC1CCC(CC1)Nc2nc(NCc3cc(Cl)ccc3O)c4ncn(C5CCCC5)c4n2"}}, {"data": {"id": "CHEMBL186934", "smi": "O=C(Cc1ccccc1)Nc2ncc(s2)c3ccccc3"}}, {"data": {"id": "CHEMBL183408", "smi": "COc1cnc2oc3ccc(O)cc3c2c1c4ccccc4"}}, {"data": {"id": "CHEMBL2425656", "smi": "C1CCC(CC1)Nc2nccc(n2)n3nnc4ccccc34"}}, {"data": {"id": "CHEMBL361565", "smi": "Oc1ccc2oc3ncc(Cl)c(c4ccccc4)c3c2c1"}}, {"data": {"id": "CHEMBL607544", "smi": "CC(C)(C)c1cc2c(N\\N=C\\c3ccc(CO)cc3)ncnc2s1"}}, {"data": {"id": "CHEMBL599428", "smi": "Cn1nc(C(=O)N)c2CCc3cnc(NC4CCN(CC4)C(=O)c5ccccc5)nc3c12"}}, {"data": {"id": "CHEMBL2336381", "smi": "CC(C)[C@H](CO)Nc1nc(NC(=N)N)c2ncn(C(C)C)c2n1"}}], "edges": [{"data": {"source": "CHEMBL1086811", "target": "CHEMBL1098686"}}, {"data": {"source": "CHEMBL1087075", "target": "CHEMBL1098686"}}, {"data": {"source": "CHEMBL1086701", "target": "CHEMBL1086811"}}, {"data": {"source": "CHEMBL2069719", "target": "CHEMBL2069718"}}, {"data": {"source": "CHEMBL2058160", "target": "CHEMBL2058161"}}, {"data": {"source": "CHEMBL2069717", "target": "CHEMBL2069718"}}, {"data": {"source": "CHEMBL2069717", "target": "CHEMBL2069719"}}, {"data": {"source": "CHEMBL182641", "target": "CHEMBL182325"}}, {"data": {"source": "CHEMBL181834", "target": "CHEMBL182325"}}, {"data": {"source": "CHEMBL1952203", "target": "CHEMBL1952200"}}, {"data": {"source": "CHEMBL182011", "target": "CHEMBL182325"}}, {"data": {"source": "CHEMBL182011", "target": "CHEMBL182641"}}, {"data": {"source": "CHEMBL1086662", "target": "CHEMBL1098686"}}, {"data": {"source": "CHEMBL1086662", "target": "CHEMBL1087075"}}, {"data": {"source": "CHEMBL1952027", "target": "CHEMBL1952028"}}, {"data": {"source": "CHEMBL182498", "target": "CHEMBL182641"}}, {"data": {"source": "CHEMBL434917", "target": "CHEMBL186120"}}, {"data": {"source": "CHEMBL2425652", "target": "CHEMBL2425654"}}, {"data": {"source": "CHEMBL595023", "target": "CHEMBL593683"}}, {"data": {"source": "CHEMBL2336375", "target": "CHEMBL2336384"}}, {"data": {"source": "CHEMBL2336374", "target": "CHEMBL2336384"}}, {"data": {"source": "CHEMBL2336374", "target": "CHEMBL2336375"}}, {"data": {"source": "CHEMBL186932", "target": "CHEMBL362369"}}, {"data": {"source": "CHEMBL183511", "target": "CHEMBL182325"}}, {"data": {"source": "CHEMBL183511", "target": "CHEMBL182641"}}, {"data": {"source": "CHEMBL183511", "target": "CHEMBL182011"}}, {"data": {"source": "CHEMBL185734", "target": "CHEMBL362369"}}, {"data": {"source": "CHEMBL1086683", "target": "CHEMBL1098686"}}, {"data": {"source": "CHEMBL1086683", "target": "CHEMBL1087075"}}, {"data": {"source": "CHEMBL1086683", "target": "CHEMBL1086662"}}, {"data": {"source": "CHEMBL1087073", "target": "CHEMBL1086811"}}, {"data": {"source": "CHEMBL1087073", "target": "CHEMBL1087075"}}, {"data": {"source": "CHEMBL1087073", "target": "CHEMBL1086701"}}, {"data": {"source": "CHEMBL1087073", "target": "CHEMBL1086662"}}, {"data": {"source": "CHEMBL1087074", "target": "CHEMBL1098686"}}, {"data": {"source": "CHEMBL1087074", "target": "CHEMBL1086811"}}, {"data": {"source": "CHEMBL1087074", "target": "CHEMBL1087075"}}, {"data": {"source": "CHEMBL1087074", "target": "CHEMBL1086662"}}, {"data": {"source": "CHEMBL1087074", "target": "CHEMBL1087073"}}, {"data": {"source": "CHEMBL1087740", "target": "CHEMBL1087075"}}, {"data": {"source": "CHEMBL1087740", "target": "CHEMBL1086683"}}, {"data": {"source": "CHEMBL1922223", "target": "CHEMBL14762"}}, {"data": {"source": "CHEMBL2069724", "target": "CHEMBL2069719"}}, {"data": {"source": "CHEMBL2069724", "target": "CHEMBL2069717"}}, {"data": {"source": "CHEMBL2069728", "target": "CHEMBL2069712"}}, {"data": {"source": "CHEMBL2057888", "target": "CHEMBL2058161"}}, {"data": {"source": "CHEMBL2057888", "target": "CHEMBL2058160"}}, {"data": {"source": "CHEMBL1922201", "target": "CHEMBL14762"}}, {"data": {"source": "CHEMBL1922201", "target": "CHEMBL1922223"}}, {"data": {"source": "CHEMBL1922204", "target": "CHEMBL2347577"}}, {"data": {"source": "CHEMBL1922204", "target": "CHEMBL1922201"}}, {"data": {"source": "CHEMBL1922207", "target": "CHEMBL1922201"}}, {"data": {"source": "CHEMBL1922207", "target": "CHEMBL1922204"}}, {"data": {"source": "CHEMBL1952029", "target": "CHEMBL1952028"}}, {"data": {"source": "CHEMBL1952029", "target": "CHEMBL1952027"}}, {"data": {"source": "CHEMBL1952032", "target": "CHEMBL1952200"}}, {"data": {"source": "CHEMBL1952032", "target": "CHEMBL1952203"}}, {"data": {"source": "CHEMBL1952208", "target": "CHEMBL1952200"}}, {"data": {"source": "CHEMBL1952208", "target": "CHEMBL1952203"}}, {"data": {"source": "CHEMBL1952208", "target": "CHEMBL1952032"}}, {"data": {"source": "CHEMBL1922120", "target": "CHEMBL14762"}}, {"data": {"source": "CHEMBL1922120", "target": "CHEMBL1922123"}}, {"data": {"source": "CHEMBL1922120", "target": "CHEMBL1922201"}}, {"data": {"source": "CHEMBL1922120", "target": "CHEMBL1922204"}}, {"data": {"source": "CHEMBL360250", "target": "CHEMBL182325"}}, {"data": {"source": "CHEMBL360250", "target": "CHEMBL182641"}}, {"data": {"source": "CHEMBL360250", "target": "CHEMBL182011"}}, {"data": {"source": "CHEMBL360250", "target": "CHEMBL183511"}}, {"data": {"source": "CHEMBL1164353", "target": "CHEMBL1164457"}}, {"data": {"source": "CHEMBL1952202", "target": "CHEMBL1952200"}}, {"data": {"source": "CHEMBL1952202", "target": "CHEMBL1952203"}}, {"data": {"source": "CHEMBL1952202", "target": "CHEMBL1952032"}}, {"data": {"source": "CHEMBL1952202", "target": "CHEMBL1952208"}}, {"data": {"source": "CHEMBL1952209", "target": "CHEMBL1952200"}}, {"data": {"source": "CHEMBL1952209", "target": "CHEMBL1952203"}}, {"data": {"source": "CHEMBL1952209", "target": "CHEMBL1952032"}}, {"data": {"source": "CHEMBL1952209", "target": "CHEMBL1952208"}}, {"data": {"source": "CHEMBL1952209", "target": "CHEMBL1952202"}}, {"data": {"source": "CHEMBL361537", "target": "CHEMBL133712"}}, {"data": {"source": "CHEMBL3093066", "target": "CHEMBL3093062"}}, {"data": {"source": "CHEMBL3093055", "target": "CHEMBL3093056"}}, {"data": {"source": "CHEMBL1922217", "target": "CHEMBL14762"}}, {"data": {"source": "CHEMBL1922217", "target": "CHEMBL1922223"}}, {"data": {"source": "CHEMBL1922217", "target": "CHEMBL1922123"}}, {"data": {"source": "CHEMBL1922217", "target": "CHEMBL1922201"}}, {"data": {"source": "CHEMBL1952033", "target": "CHEMBL1952200"}}, {"data": {"source": "CHEMBL1952033", "target": "CHEMBL1952203"}}, {"data": {"source": "CHEMBL1952033", "target": "CHEMBL1952032"}}, {"data": {"source": "CHEMBL1952033", "target": "CHEMBL1952208"}}, {"data": {"source": "CHEMBL1952033", "target": "CHEMBL1952202"}}, {"data": {"source": "CHEMBL1952033", "target": "CHEMBL1952209"}}, {"data": {"source": "CHEMBL1949699", "target": "CHEMBL1952200"}}, {"data": {"source": "CHEMBL1949699", "target": "CHEMBL1952208"}}, {"data": {"source": "CHEMBL1949699", "target": "CHEMBL1952202"}}, {"data": {"source": "CHEMBL2347586", "target": "CHEMBL2347585"}}, {"data": {"source": "CHEMBL2347579", "target": "CHEMBL14762"}}, {"data": {"source": "CHEMBL2347579", "target": "CHEMBL1922223"}}, {"data": {"source": "CHEMBL2347579", "target": "CHEMBL1922201"}}, {"data": {"source": "CHEMBL2347579", "target": "CHEMBL1922217"}}, {"data": {"source": "CHEMBL2402947", "target": "CHEMBL2349192"}}, {"data": {"source": "CHEMBL2402947", "target": "CHEMBL2402946"}}, {"data": {"source": "CHEMBL186934", "target": "CHEMBL362369"}}, {"data": {"source": "CHEMBL186934", "target": "CHEMBL185734"}}, {"data": {"source": "CHEMBL183408", "target": "CHEMBL133712"}}, {"data": {"source": "CHEMBL183408", "target": "CHEMBL361537"}}, {"data": {"source": "CHEMBL2425656", "target": "CHEMBL2425654"}}, {"data": {"source": "CHEMBL2425656", "target": "CHEMBL2425652"}}, {"data": {"source": "CHEMBL361565", "target": "CHEMBL133712"}}, {"data": {"source": "CHEMBL361565", "target": "CHEMBL361537"}}, {"data": {"source": "CHEMBL361565", "target": "CHEMBL183408"}}, {"data": {"source": "CHEMBL607544", "target": "CHEMBL593683"}}, {"data": {"source": "CHEMBL607544", "target": "CHEMBL595023"}}, {"data": {"source": "CHEMBL2336381", "target": "CHEMBL2336384"}}, {"data": {"source": "CHEMBL2336381", "target": "CHEMBL2336375"}}, {"data": {"source": "CHEMBL2336381", "target": "CHEMBL2336374"}}]}
;


$(function(){ // on dom ready

var cy = cytoscape({
  container: $('#cy')[0],
  style: cytoscape.stylesheet()
    .selector('node')
      .css({
        'text-valign': 'center',
        'background-color': 'darkblue',
        'text-outline-width': 2,
        'width': 10,
        'height':10,
        'text-outline-color': '#888'
      })
    .selector('edge')
      .css({
        'width': 5,
        'line-color': 'blue',
      })
    .selector(':selected')
      .css({
        'background-color': 'black',
        'line-color': 'black',
        'target-arrow-color': 'black',
        'source-arrow-color': 'black'
      })
    .selector('.faded')
      .css({
        'opacity': 0.25,
        'text-opacity': 0
      }),
  
  elements: cy3json,
  
  layout: {
    name: 'arbor',
    padding: [50,50,50,50]
  },
});
cy.on('tap', 'node', function(){
  alert( this.data('smi') );
});
}); // on dom ready
</script>
<div class="container">
    <div class="row">
        <div class="col-md-12" style="background:lightblue; height:600px;">
        This is test env.<br>
  <div id="cy"></div>
        </div>
    </div>
 </div>
</body>
{% endblock content %}

OK I did it. Then run the localserver.
And Access mol_network site.

pen:chemoflask iwatobipen$ python app.py

Yah! I could make molecular network.
I used arbor layout. “The arbor layout uses a force-directed physics simulation.”
And tap each node, the site return smiles strings.

If you are good at javascript programming, you can make more rich web site.

network