Make Interactive Cluster Heatmap

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/ .
Screen Shot 2014-11-02 at 2.49.36 PM

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

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中