Heat map is useful tool to visualise multi parameter not only biology, but also chemoinformatics.
I often use spot-fire or R to make it.
Last week I found cool javascript library “InCHlib(Interactive Cluster Heatmap library)”.
There is good document in this link http://openscreen.cz/software/inchlib/home/ .
I make simple test to use the library.
At first, I wrote app.py in my folder. (Use flask.)
from flask import Flask from flask_bootstrap import Bootstrap from flask import render_template def create_app(): app = Flask( __name__ ) Bootstrap( app ) return app app = create_app() @app.route("/") def root(): return render_template("sample.html") if __name__=="__main__": app.run(debug = True)
I set three javascript librarys in static/js folder
kinetic-v5.1.0.min.js, jquery-2.0.3.min.js, inchlib-1.1.0.js
First, I make dataset using rdkit, and pandas.
Sample data is CDK2 inh. download form chembldb.
To make sampledata, I made two dataset, firstdata.csv(mol_id, and some descriptors), metadata.csv(mol_id and biological data).
iwatobipen$ head -n 5 firstdata.csv CMPD_CHEMBLID,MOLWT,LOGP,RING,HDN,HACC,NRotB CHEMBL573578,331.4230000000001,3.9075000000000024,4,1,5,2 CHEMBL270724,463.745,4.8344000000000005,1,1,1,2 CHEMBL75680,267.332,3.6731000000000025,3,2,3,4 CHEMBL281948,467.4810000000003,3.655100000000002,8,2,7,1 iwatobipen$ head -n 5 metadf.csv CMPD_CHEMBLID,STANDARD_VALUE CHEMBL573578,57 CHEMBL270724,67 CHEMBL75680,18 CHEMBL281948,0
Then, make data using inchlib_clust.py.
“-dh and -mh” option mean that use header(column names) in csv files.
python inchlib_clust.py firstdata.csv -m metadata.csv -dh -mh -o cdk2.json
Now I got cdk2.json file that contains the cluster heatmap in the InCHlib input format.
Next, write html template.
1.Base template using bootstrap.
{% extends "bootstrap/base.html" %} {% block title %}{% endblock %} {% block navbar %} <nav class="navbar navbar-inverse navbar-fixed-top" 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 collapsed" 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="#">sample</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="/">Top</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="#">hoge</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 %} {% endblock %}
2.sample page.
This sample page shows heatmap and structure depends on mouse position.
{% extends "templ.html" %} {% block title %} InCHlib {% endblock %} {% block styles %} {{super()}} <style type="text/css"> #molecule{ position: absolute; height: 305px; width: 220px; z-index: 100; border: solid #D2D2D2 1px; border-radius: 10px; display: none; background-color: white; } #molecule_img{ margin-left: auto; margin-right: auto; display: block; width: 95%; background-color: white; border-radius: 10px; } </style> {% endblock %} {% block scripts %} {{ super() }} <script type=text/javascript src="{{ url_for('static', filename='js/jquery-2.0.3.min.js')}}"></script> <script type=text/javascript src="{{ url_for('static', filename='js/kinetic-v5.1.0.min.js')}}"></script> <script type=text/javascript src="{{ url_for('static', filename='js/inchlib-1.1.0.js')}}"></script> <script> // load JSON $(document).ready(function() { //run when the whole page is loaded window.inchlib = new InCHlib({ //instantiate InCHlib target: "inchlib", //ID of a target HTML element metadata: true, //turn on the metadata column_metadata: true, //turn on the column metadata max_height: 1200, //set maximum height of visualization in pixels width: 600, //set width of visualization in pixels heatmap_colors: "Greens", //set color scale for clustered data metadata_colors: "Reds", //set color scale for metadata }); inchlib.read_data_from_file("{{ url_for('static', filename='demodata/cdk2.json')}}"); //read input json file inchlib.draw(); //draw cluster heatmap var molecule_url = "{{ url_for('static', filename='img/')}}"; var target_element = $("#inchlib"); var offset = target_element.offset(); var x_pos = offset.left + inchlib.settings.width - 80;; var max_y = offset.top+150; var img_element = $("#molecule_img"); var mol_element = $("#molecule").css({"left" : x_pos}); var mol_id_element = $("mol_id"); var floating_mol = $("#floating_mol"); bind_dendrogram_events(); function show_molecule(mol_id, evt){ var filepath = molecule_url + mol_id + ".png"; var y = evt.evt.pageY-300; if(y < max_y){ y = max_y; } mol_element.css({"top": y, "border-width": "1px"}); img_element.attr("src", filepath); mol_id_element.text(mol_id); //mol_link.attr("href", chembl_url+mol_id); mol_element.show(); } function hide_molecule(ids, evt){ mol_element.hide(); } function fix_molecule(){ floating_mol.hide(); inchlib.events.row_onmouseover = function(){}; inchlib.events.heatmap_onmouseout = function(){ floating_mol.hide(); }; } function bind_dendrogram_events(){ inchlib.events.row_onmouseover = function(ids, evt){ show_molecule(ids, evt); }; inchlib.events.heatmap_onmouseout = function(evt){ hide_molecule(evt); floating_mol.hide(); }; inchlib.events.row_onclick = function(ids, evt){ show_molecule(ids[0], evt); fix_molecule(ids[0]); current_mol = ids[0]; inchlib.highlight_rows(ids); mol_element.css({"border-width": "2px"}); inchlib.unhighlight_cluster(); }; inchlib.events.dendrogram_node_highlight = function(object_ids, evt){ var i; for(i = 0; i<object_ids.length; i++){ if(object_ids[i] == current_mol){ return; } } inchlib.highlight_rows([]); } inchlib.events.empty_space_onclick = function(){ hide_molecule(); inchlib.highlight_rows([]); bind_dendrogram_events(); } } $(document).click(function(evt){ if(evt.target.localName != "img" && evt.target.localName != "canvas" && evt.target.localName != "a"){ hide_molecule(); bind_dendrogram_events(); } }); }); </script> {% endblock %} {% block content %} <div class="container-fluid"> <div class="row"> <h1>InCHlib test</h1></br> <div class="col-md-12" style='background-color: lightblue; height: 1200px'> <div id="inchlib"></div> <div id="molecule"> <h1></h1> <img src="" id="molecule_img" style=""></img> </div> </div> </div> </div> {% endblock %}
Finally run app and access 127.0.0.1:5000/ .
In summary, InCHlib is very cool tools to visualise molecular structures and biological activity or another data in web.
I uploaded sample to github.
https://github.com/iwatobipen/inchlib-test