Recalculate correlation values
This is the last of the series of examples, where we step by step introduce new chart properties for the
same set of charts.
Here, we utilise another aspect of in-built interactive functionality in the linked-charts library.
In the instrument panel, one can find a "Select elements" button. If it is pressed, then the user can select or
deselect cells or points by clicking and brushing. A double click will deselect all the elements. You can also
use this mode just keepint the Shift
key pressed. Just like clicking, selecting or - in the
linked-charts terms, marking - the elements, can trigger various actions. Let's, for example,
allow user to define, what cell lines to use for correlation calculations, by marking them on the correlation
scatter plot. Try to mark several points on the top right plot and see how the heatmap changes. By the way,
don't forget that you can recluster rows or columns after the correlation values have been recalculated.
Use the instrument panel for this.
The data used here are generated in a drug-screening experiment. 50 drugs at 5 different concentrations
were tested against 21 pancreatic cancer cell lines. The heatmap shows drug-drug correlation. Like in the
previous example, a click on a cell of the heatmap reveals the underlying statistics by demonstrating on
the scatter plot (right upper corner) the values of avarage inhibition for all tested cell lines and the two
selected drugs. By clicking on a data point one can select a cell line, and thus change the third plot
(right bottom corner) that demonstrates individual inhibition percent values for the two selected drugs and
the selected cell line.
The code for the example
A user of our framework can create apps with very little code. Bellow we show the part of
the code that hasn't been explained in previous examples. You can find the complete code
at the bottom of the page.
...
var heatmap = lc.heatmap()
.value( function( rowId, colId ) {
var selCL = [];
if(scatterplot)
selCL = scatterplot.get_marked()
.filter( function( e ) { return e[0] == "layer0"} )
.map( function( e ) { return e[1] } );
if( selCL.length < 2 ) selCL = cellLines;
var rowValues = selCL.map(function( e ) {
return inputData.RTG[rowId][e].avInh;
}),
colValues = selCL.map(function( e ) {
return inputData.RTG[colId][e].avInh;
});
return lc.pearsonCorr( rowValues, colValues );
})
...
.place( "#heatmap" );
var heatmapSlider = lc.colourSlider()
...
.place( "#heatmap" );
...
var scatterplot = lc.scatter()
...
lc.xLine( "line", scatterplot )
...
.markedUpdated( heatmap.updateCellColour )
.place( "#scatterplot" );
...
var scatterSlider = lc.colourSlider()
...
.place( "#scatterplot" );
...
var curveFit = lc.scatter( "points" )
...
lc.xLine( "lines", curveFit )
...
.place( "#scatterplot" );
...
|
Show/hide full code
<script src="linked-charts.min.js"></script>
<link rel="stylesheet" type="text/css" href="linked-charts.css">
<script>
inputData = [{"CellLine":"Pa16C","Drug":"Galunisertib","minConc":1, ...}, ... ];
</script>
<table><tr>
<td id="heatmap" valign="top"></td>
<td id="scatterplot" valign="top"></td>
</tr></table>
<script>
inputData = lc.separateBy(inputData, ["screen", "Drug", "CellLine"]);
var drugs = Object.keys(inputData.RTG),
cellLines = Object.keys(inputData.RTG[drugs[0]]);
var selDrugs = [drugs[0], drugs[1]],
selCellLine = cellLines[0];
var heatmap = lc.heatmap()
.value( function( rowId, colId ) {
var selCL = [];
if(scatterplot)
selCL = scatterplot.get_marked()
.filter( function( e ) { return e[0] == "layer0"} )
.map( function( e ) { return e[1] } );
if( selCL.length < 2 ) selCL = cellLines;
var rowValues = selCL.map(function( e ) {
return inputData.RTG[rowId][e].avInh;
}),
colValues = selCL.map(function( e ) {
return inputData.RTG[colId][e].avInh;
});
return lc.pearsonCorr( rowValues, colValues );
})
.rowIds( drugs )
.colIds( drugs )
.title( "Drug-drug correlation" )
.colourDomain( [ -1, 1 ] )
.margins({top: 50, left: 50, right: 100, bottom: 100})
.palette( function( val ) { return d3.interpolateRdBu( 1 - val ); } )
.on_click( function( rowId, colId ) {
selDrugs = [rowId, colId]
scatterplot.update();
curveFit.update();
})
.cluster( "Row" )
.cluster( "Col" )
.showLegend( false )
.place( "#heatmap" );
var heatmapSlider = lc.colourSlider()
.straightColourScale( heatmap.colourScale )
.on_change(function(){
heatmap.updateCellColour();
})
.place( "#heatmap" );
heatmap.colour( function( val ){
return heatmapSlider.colourScale( val );
} );
var get_curve = function( drug, cellLine, x ){
var max = inputData.RTG[drug][cellLine].max,
min = inputData.RTG[drug][cellLine].min,
IC50 = inputData.RTG[drug][cellLine].IC50,
slope = inputData.RTG[drug][cellLine].Slope,
minConc = inputData.RTG[drug][cellLine].minConc;
return min + ( max - min )/
(1 + Math.pow( 10, - ( x - Math.log10( IC50/minConc ) ) * slope));
}
var scatterplot = lc.scatter()
.width( 300 )
.height( 300 )
.elementIds( cellLines )
.x( function( k ) { return inputData.RTG[selDrugs[0]][k].avInh } )
.y( function( k ) { return inputData.RTG[selDrugs[1]][k].avInh } )
.axisTitleX( function() {return selDrugs[0]} )
.axisTitleY( function() {return selDrugs[1]} )
.title( "Average inhibition" )
.domainX( [-10, 50] )
.domainY( [-10, 50] )
.palette( ["green", "yellow","red"] )
.colourValue( function( k ) {
var res = 0;
for( var x = 0; x < 5; x++ )
for( var l = 0; l < 2; l++ )
res += Math.pow( get_curve( selDrugs[l], k, x ) -
inputData.RTG[selDrugs[l]][k]["D" + (x + 1)], 2 );
res = Math.sqrt( res );
return res;
})
.colourDomain( [ 0, 30 ] )
.on_click( function( k ) {
selCellLine = k;
curveFit.update();
})
.showLegend( false );
lc.xLine( "line", scatterplot )
.lineFun( function( x ){
return x;
})
.markedUpdated( heatmap.updateCellColour )
.place( "#scatterplot" );
var layer = scatterplot.get_layer( "layer0" );
var scatterSlider = lc.colourSlider()
.width( 300 )
.height( 110 )
.set_margins( {top: 50} )
.title( "Total curvefitting error" )
.straightColourScale( layer.colourScale )
.on_change( function(){
layer.updateElementStyle();
} )
.place( "#scatterplot" );
layer.colour(function( id ){
return scatterSlider.colourScale( layer.get_colourValue( id ) );
});
var curveFit = lc.scatter( "points" )
.width( 300 )
.height( 200 )
.nelements( 10 )
.title( function() {return selCellLine;} )
.axisTitleX( "Drug concentration" )
.axisTitleY( "Inhibition" )
.domainY( [-25, 100] )
.ticksX( function() {
var ticks = [d3.range( 5 ),
d3.range( 5 ).map( function( e ) {
return inputData.RTG[selDrugs[0]][selCellLine].minConc *
Math.pow( 10, e )
} ),
d3.range( 5 ).map( function( e ) {
return inputData.RTG[selDrugs[1]][selCellLine].minConc *
Math.pow( 10, e )
})];
ticks.colour = ["blue", "red"];
return ticks;
})
.x( function( k ) {
return k % 5;
} )
.y( function( k ) {
var ind = Math.floor( k / 5 );
return inputData.RTG[selDrugs[ind]][selCellLine]["D" + (k % 5 + 1)];
})
.colour( function( k ) {
return k > 4 ? "red" : "blue";
} );
lc.xLine( "lines", curveFit )
.nelements( 2 )
.lineFun( function( x, k ) {
return get_curve( selDrugs[k], selCellLine, x );
})
.colour(function( k ){
return k == 0 ? "blue" : "red";
})
.place( "#scatterplot" );
curveFit.legend.add_block(function() {return [selDrugs, ["blue", "red"]];},
"colour", "Drugs");
</script>