t-viSNE: Interactive Assessment and Interpretation of t-SNE Projections
https://doi.org/10.1109/TVCG.2020.2986996
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
437 lines
26 KiB
437 lines
26 KiB
<html>
|
|
<head>
|
|
|
|
<!-- Ignore Favicon -> Solved the warning in console of the browser. -->
|
|
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
|
|
|
|
<!-- Three.js and Lodash libraries-->
|
|
<script src='./modules/three.js-r101/three.js'></script>
|
|
<script src='./modules/lodash/lodash.js'></script>
|
|
|
|
<!-- Importing D3 minified versions v3 and v5. -->
|
|
<script src='./modules/d3v3/d3.min.js'></script>
|
|
<script src='./modules/d3/d3.min.js'></script>
|
|
|
|
<!-- Importing additional modules such as PCP, annotator, tip, legend, lasso, papaParse, and Jquery. -->
|
|
<script src='./modules/d3-annotations/d3-annotator.js'></script>
|
|
<script src="./modules/d3-tip/tip.js"></script>
|
|
<script src="./modules/d3-legend/d3-legend.min.js"></script>
|
|
<script src="./modules/d3-lasso/lasso.js"></script>
|
|
<script src="./modules/plotly/plotly_min.js"></script>
|
|
<script src="./modules/pcp/d3v3.parcoords.js"></script>
|
|
|
|
<script src="./modules/papa/papaparse.min.js"></script>
|
|
<script src="./modules/jquery/jquery.min.js"></script>
|
|
|
|
<!-- Basic scripts that we execute. -->
|
|
<script src="./js/tsne.js"></script>
|
|
<script src="./js/data_form_handler.js"></script>
|
|
<script src="./modules/pca/pca.js"></script>
|
|
|
|
<!-- CSS - Styling -->
|
|
<link rel="stylesheet" href="./css/style.css"/>
|
|
<link rel="stylesheet" href="./css/bootstrap.min.css"/>
|
|
<link rel="stylesheet" type="text/css" href="./css/d3.parcoords.css">
|
|
<link rel="stylesheet" href="./css/reset.css">
|
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.0/css/all.css" integrity="sha384-Mmxa0mLqhmOeaE8vgOSbKacftZcsNYDjQzuCOm6D02luYSzBG8vpaOykv9lFQ51Y" crossorigin="anonymous">
|
|
|
|
<!-- Bootstrap -->
|
|
|
|
<script src="./modules/popper/popper.min.js"></script>
|
|
<script src="./modules/bootstrap/bootstrap.min.js"></script>
|
|
|
|
|
|
</head>
|
|
|
|
<body>
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="panel panel-default" id="left-side-param">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title" style="display:inline-block" data-toggle="tooltip" data-placement="right" title="Tip: control t-SNE algorithm and its parameters.">t-SNE Parameters</h2><div id="cost" style="display:inline-block; float:right"></div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div id="control-panel" data-sr="enter left over 8s">
|
|
<div class="param">
|
|
<label id="data" for="param-dataset" data-toggle="tooltip" data-placement="right" title="Tip: use one of the data sets already provided or upload a new file.">Data sets</label>
|
|
<select id="param-dataset" name="param-dataset" onChange="changeDataset(this.value);">
|
|
<option value="diabetes.csv" selected>Pima Indian Diabetes</option>
|
|
<option value="breast-cancer-wisconsin.csv">Breast Cancer Wisconsin</option>
|
|
<option value="iris.csv">Iris</option>
|
|
<option value="winequality-red.csv">Red Wine - Quality</option>
|
|
<option value="empty">Upload New File</option>
|
|
</select>
|
|
<button type="button" class="button" id="FactRes" onclick="FactoryReset()" data-toggle="tooltip" data-placement="right" title="Tip: Restart the entire web page/application.">Factory reset</button>
|
|
</div>
|
|
<div class="param">
|
|
<label for="param-perplexity" data-toggle="tooltip" data-placement="right" title="Tip: perplexity is a measure for information that is defined as 2 to the power of the Shannon entropy. The perplexity of a fair die with k sides is equal to k. In t-SNE, the perplexity may be viewed as a knob that sets the number of effective nearest neighbors. (Source: https://lvdmaaten.github.io/tsne/)">Perplexity</label>
|
|
<input id="param-perplexity" type="range" min="5" max="100" value="30", step="1" >
|
|
<output for="param-perplexity" id="param-perplexity-value">30</output>
|
|
</div>
|
|
<div class="param">
|
|
<label for="param-learningrate" data-toggle="tooltip" data-placement="right" title="Tip: if the learning rate is too high, the data may look like a ‘ball’ with any point approximately equidistant from its nearest neighbours. If the learning rate is too low, most points may look compressed in a dense cloud with few outliers. If the cost function gets stuck in a bad local minimum increasing the learning rate may help. (Source: https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html)">Learning rate</label>
|
|
<input id="param-learningrate" type="range" min="1" max="150" value="10", step="1">
|
|
<output for="param-learningrate" id="param-learningrate-value">10</output>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="param">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<label for="param-maxiter" style="padding: 25px 0 0 8px" data-toggle="tooltip" data-placement="right" title="Tip: maximum number of iterations for the optimization. Should usually be around 250. (Source: https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html)">Max iterations</label>
|
|
</div>
|
|
<div class="col-md-4" style="padding: 25px 0 0 0px">
|
|
<input id="param-maxiter" type="range" min="10" max="1000" value="500", step="10" >
|
|
</div>
|
|
<div class="col-md-1">
|
|
<output for="param-maxiter" id="param-maxiter-value" style="padding: 25px 0 0 0" >500</output>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div id="hider2"></div>
|
|
<div id="PlotCost"></div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="param">
|
|
<label for="param-distance" data-toggle="tooltip" data-placement="right" title="Tip: distance different measurements. Usually Euclidean distance is used.">Distance metric</label>
|
|
<select id="param-distance" name="param-distance">
|
|
<option value="euclideanDist" selected>Euclidean distance</option>
|
|
<option value="jaccardDist">Jaccard dissimilarity</option>
|
|
</select>
|
|
<input id="file-input" type="file" name="name" style="display: none;" />
|
|
<button type="button" class="button" onclick='loadAnalysis();' style="padding:0 12px 0 12px" data-toggle="tooltip" data-placement="right" title="Tip: load previously executed file in .txt format.">Load execut.</button>
|
|
</div>
|
|
<div class="param">
|
|
<label for="param-transform" data-toggle="tooltip" data-placement="right" title="Tip: distance transformation measurements. Usually either no transformation or Log10/Asinh (logarithmic/hyperbolic) distance are used.">Data transform</label>
|
|
<select id="param-transform" name="param-transform">
|
|
<option value="noTrans" selected>No transform</option>
|
|
<option value="logTrans">Log10</option>
|
|
<option value="asinhTrans">Asinh</option>
|
|
<option value="binTrans">Binarize</option>
|
|
</select>
|
|
<button type="button" class="button" onclick="SaveAnalysis()" style="padding:0 10px 0 10px" data-toggle="tooltip" data-placement="right" title="Tip: save/store previously executed file in .txt format.">Store execut.</button>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<p><div id="run-button"><button id="ExecuteBut" class="btn btn-primary btn-block" onclick="getData();" value="Execute new t-SNE analysis" style="margin-top: 4px"><i class="fas fa-running fa-lg" style="margin-right: 10px"></i>Execute new t-SNE analysis</button></div></p>
|
|
</div>
|
|
<div class="col-md-4" style="margin-top: 10px">
|
|
<label data-toggle="tooltip" data-placement="right" title="Tip: if you store distances the file size will be larger but on a loading of this execution it will be processed much quicker than without this option enabled.">
|
|
<input id="downloadDists" checked type="checkbox" >
|
|
Distances cached on "Store execution"
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<svg id="SvgAnnotator"></svg>
|
|
<svg id="modtSNEcanvas_svg"></svg>
|
|
<svg id="modtSNEcanvas_svg_Schema"></svg>
|
|
<div id="modtSNEDiv">
|
|
<canvas id = "modtSNEcanvas" ></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2" style="width: 24.999999995%">
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title">Interaction Modes</h2>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div id="resetAllFilters" style="margin-bottom: 20px">
|
|
<button class="btn btn-info active" onclick="setLayerProj();" style="margin-left: -1px !important" ><i class="fas fa-mouse-pointer fa-lg" ></i>t-SNE Points Exploration</button>
|
|
<button class="btn btn-info" onclick="setLayerComp();" style="margin-left: -1.4px"><i class="far fa-object-group fa-lg" ></i>Group Selection</button>
|
|
<button class="btn btn-info" onclick="setLayerSche();" style="margin-left: -2px !important"><i class="fas fa-draw-polygon fa-lg" ></i>Dimension Correlation</button>
|
|
</div>
|
|
<button class="btn btn-info" onclick="setReset();" style="margin-left: 225px"><i class="fas fa-trash-alt fa-lg" style="margin-right: 10px"></i>Reset Filters</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-3" style="margin-top:-4px">
|
|
<div class="panel panel-default" style="padding-bottom: 35px;">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title" style="display:inline-block" data-toggle="tooltip" data-placement="right" title="Tip: t-SNE overview with or without labels depending on each data set. To determine the feature of a data set that corresponds to classes set a * mark after this feature.">t-SNE Overview</h2><div id="datasetDetails"style="display:inline-block; float:right"></div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="panel-body">
|
|
<div class="col-md-6">
|
|
<div id="overviewRect"></div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div style="display:block" id="CategoryName"></div>
|
|
<div class="legend" id = "legend2"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 col-md-offset-6">
|
|
<div class="panel panel-default" style="margin-top: -195px">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title">Visual Mapping</h2>
|
|
</div>
|
|
<div class="row">
|
|
<div class="panel-body">
|
|
<div class="col-md-12">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="param" style="padding: 5px 0 5px 0">
|
|
<label for="male"></label>Density</label>
|
|
<select id="param-neighborHood" name ="param-neighborHood" onchange="setReInitialize(true);" style="display:inline-block;margin-left: 60px">
|
|
<option selected="selected" value="color" >Color-encoding</option>
|
|
<option value="size">Size-encoding</option>
|
|
</select>
|
|
</div>
|
|
<div class="param" style="padding: 10px 0 10px 0" >
|
|
<output for="param-neighborHood" id="param-neighborHood-value " ></output>
|
|
<label for="male">Remaining cost</label>
|
|
<label id="selectionLabel" style="margin-top:4px; margin-left: 15px">Size-encoding</label>
|
|
</div>
|
|
<div class="param">
|
|
<div class="row" style="margin-top: 30px">
|
|
<div class="col-md-6">
|
|
<label for="param-corr" data-toggle="tooltip" data-placement="right" title="Tip: percentage of all points taken into account by Dimension Correlation.">Correlation threshold (%)</label>
|
|
</div>
|
|
<div class="col-md-5">
|
|
<input id="param-corr" type="range" min="0" max="100" value="25", step="1" onchange="CalculateCorrel(true);" style="margin-left: -20px;">
|
|
</div>
|
|
<div class="col-md-1">
|
|
<output for="param-corr" id="param-corr-value" style="margin-left: -20px;">25</output>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="param">
|
|
<div class="row" style="margin-top: 30px">
|
|
<div class="col-md-6">
|
|
<label for="param-lim" data-toggle="tooltip" data-placement="right" title="Tip: x*times the actual radius (increase/decrease points radius).">Points radius scaling</label>
|
|
</div>
|
|
<div class="col-md-5">
|
|
<input id="param-lim" type="range" min="1" max="4" value="3", step="0.5" onchange="setReInitialize(false);" style="margin-left: -20px;">
|
|
</div>
|
|
<div class="col-md-1">
|
|
<output for="param-lim" id="param-lim-value" style="margin-left: -20px;">3</output>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<svg id="legend1" style = "margin-left: -25px"></svg>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<svg id="legend4" style = "margin-left: -45px"></svg>
|
|
</div>
|
|
</div>
|
|
<div class="annotationAllClass" style="margin-top: 30px">
|
|
<label style="padding-bottom: 0px">
|
|
<input id="controls" type="checkbox" style="margin-top: 18px">
|
|
Hide annotations' controllers</input>
|
|
<button class="btn btn-default" onclick="BringBackAnnotations();" style="display:inline-block; float:right; margin-left:178px"><i class="fas fa-eye fa-lg" style="margin-right: 10px"></i>Reveal annotations</button>
|
|
</label>
|
|
<div id="param-correlation">
|
|
Annotation: <textarea type="text" id="comment" name="textforAnnotator" placeholder="Please, provide your comment."></textarea>
|
|
</div>
|
|
<div id="commBtn">
|
|
<div class="param" style="margin-top:10px">
|
|
<div id="toggleAnnotator" style= "margin-left: -120px"><button class="btn btn-default" onclick="setAnnotator();" style="display:inline-block; float:left; margin-left: 120px" ><i class="fas fa-comment fa-lg" style="margin-right: 10px"></i>Add annotation</button></div>
|
|
<div id="continue"></div><button class="btn btn-default active" onclick="setContinue();" style="display:inline-block; float:middle; margin-left: 6px"><i class="fas fa-chart-line fa-lg" style="margin-right: 10px"></i>Continue the analysis</button></div>
|
|
<button class="btn btn-default" onclick="deleteAnnotations();" style="display:inline-block; float:right; margin-top: -45px" ><i class="fas fa-comment-slash fa-lg" style="margin-right: 10px"></i>Delete annotations</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-3" style="margin-top:-4px">
|
|
<div class="panel panel-default" style="padding-bottom : 60px">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title" data-toggle="tooltip" data-placement="right" title="Tip: a view related to the overall quality of the projection.">Shepard Heatmap</h2>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<svg id="sheparheat"></svg>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<svg id="legend3"></svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 col-md-offset-6">
|
|
<div class="panel panel-default right-side-cor">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title" style="display:inline-block">Dimension Correlation</h2><div class="param" style="display:inline-block; margin-top:-5px; float:right"><label for="param-corlim" style="display:inline-block; float: right">Min. Visible Correlation: #<output for="param-corlim" id="param-corlim-value" style="display:inline-block; float:right">0.0</output></label>
|
|
<input id="param-corlim" type="range" min="0" max="1" value="0.0", step="0.1" style="display:inline-block; float:right" onchange="CalculateCorrel(true);">
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<svg id="correlation"></svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
|
|
<div class="col-md-3" id="extra-information" style="width: 24.8vw">
|
|
<div class="panel panel-default right-side-hist">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title" style="display:inline-block;" data-toggle="tooltip" data-placement="right" title="Tip: it might be useful to take a look at this histogram, to observe the density and remaining cost distributions, when remaining cost values are low and have an idea about the distributions.">Density and Remaining Cost Distributions</h2>
|
|
<div class="col-md-7"></div>
|
|
<div class="col-md-5">
|
|
<div class="param" style="display:inline-block; float:right; margin-top:-21.5px; margin-right: -18px">
|
|
<label for="param-costlim" style="display:inline-block; float: right" data-toggle="tooltip" data-placement="right" title="Tip: set the rate of the limiter for the minimum acceptable visible cost at the main visualization view.">Min. Visible Cost Rate: #<output for="param-costlim" id="param-costlim-value" style="display:inline-block; float:right">1</output></label>
|
|
<input id="param-costlim" type="range" min="0.1" max="1" value="1", step="0.1" style="display:inline-block; float:right" onchange="setReInitialize(false);">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div id="costHist"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div class = col-md-6>
|
|
<div class="panel panel-default med-bottom">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title" style="display:inline-block">Neighborhood Preservation </h2>
|
|
[Visualization:
|
|
<select id="param-NB-view" name="param-NB-view" onchange="LineBar()">
|
|
<option value="1" selected>Bar Chart</option>
|
|
<option value="2">Line Plot</option>
|
|
<option value="3">Difference Line Plot</option>
|
|
</select>
|
|
]
|
|
<div id="knnBarChartDetails"style="display:inline-block; float:right">
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div id="hider"></div>
|
|
<div id="knnBarChart"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="panel panel-default right-side-PCP">
|
|
<div class="panel-heading">
|
|
<h2 class="panel-title">Adaptive Parallel Coordinates Plot</h2>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div id="PCP" class="parcoords"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Tooltip
|
|
$(document).ready(function(){
|
|
$(this).tooltip();
|
|
});
|
|
|
|
$("#cost").html('(Unknown Iteration and Cost Values)');
|
|
$("#datasetDetails").html('(Unknown Number of Dimensions and Instances)');
|
|
$("#CategoryName").html('No Classification');
|
|
$("#knnBarChartDetails").html('(Number of Selected Points: 0/0)');
|
|
/* This script is used in order to give functionalities to the different buttons provide through the front-end. */
|
|
$('#param-lim').bind('input', function () { $('#param-lim-value').text($('#param-lim').val()); });
|
|
$('#param-corr').bind('input', function () { $('#param-corr-value').text($('#param-corr').val()); });
|
|
$('#param-corlim').bind('input', function () { $('#param-corlim-value').text($('#param-corlim').val()); });
|
|
$('#param-costlim').bind('input', function () { $('#param-costlim-value').text($('#param-costlim').val()); });
|
|
$('#param-perplexity').bind('input', function () { $('#param-perplexity-value').text($('#param-perplexity').val()); });
|
|
$('#param-earlyexag').bind('input', function () { $('#param-earlyexag-value').text($('#param-earlyexag').val()); });
|
|
$('#param-learningrate').bind('input', function () { $('#param-learningrate-value').text($('#param-learningrate').val()); });
|
|
$('#param-maxiter').bind('input', function () { $('#param-maxiter-value').text($('#param-maxiter').val()); });
|
|
|
|
// Get the container element
|
|
var btnContainer = document.getElementById("commBtn"); //Add a new comment button
|
|
|
|
// Get all buttons with class="btn" inside the container
|
|
var btns = btnContainer.getElementsByClassName("btn");
|
|
for (var i = 0; i < btns.length; i++) {
|
|
btns[i].addEventListener("click", function() {
|
|
let current = document.getElementById("commBtn").getElementsByClassName("active");
|
|
current[0].className = current[0].className.replace("btn btn-default active", "btn btn-default");
|
|
this.className += " active";
|
|
});
|
|
}
|
|
|
|
// Get the container element
|
|
var btnContainer2 = document.getElementById("resetAllFilters"); //resetAllFilters button
|
|
|
|
// Get all buttons with class="btn" inside the container
|
|
var btns2 = btnContainer2.getElementsByClassName("btn");
|
|
|
|
for (var i = 0; i < btns2.length; i++) {
|
|
btns2[i].addEventListener("click", function() {
|
|
let current = document.getElementsByClassName("active");
|
|
current[0].className = current[0].className.replace("btn btn-info active", "btn btn-info");
|
|
this.className += " active";
|
|
});
|
|
}
|
|
|
|
</script>
|
|
|
|
<script>
|
|
/* On resize refresh the shepardHeatmap */
|
|
window.onresize = function(event) {
|
|
if ( document.getElementById('cost').hasChildNodes() ) {
|
|
|
|
// Clear legend for the shepardHeatmap
|
|
//var svgLegend = d3.select("#legend3");
|
|
//svgLegend.selectAll("*").remove();
|
|
|
|
// Clear the SheapHeardmap before refreshing
|
|
//var svg = d3.select("#sheparheat");
|
|
//svg.selectAll("*").remove();
|
|
|
|
// Call the ShepardHeatmap again to be redrawn
|
|
//ShepardHeatMap();
|
|
MainVisual();
|
|
|
|
}
|
|
}
|
|
|
|
/* When the user clicks on the button,
|
|
toggle between hiding and showing the dropdown content */
|
|
function myFunction() {
|
|
document.getElementById("myDropdown").classList.toggle("show");
|
|
}
|
|
|
|
// Close the dropdown menu if the user clicks outside of it
|
|
window.onclick = function(event) {
|
|
if (!event.target.matches('.dropbtn')) {
|
|
var dropdowns = document.getElementsByClassName("dropdown-content");
|
|
var i;
|
|
for (i = 0; i < dropdowns.length; i++) {
|
|
var openDropdown = dropdowns[i];
|
|
if (openDropdown.classList.contains('show')) {
|
|
openDropdown.classList.remove('show');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<!-- Load the core visualization script. -->
|
|
<script src="./js/tsne_vis.js"></script>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|