diff --git a/__pycache__/run.cpython-37.pyc b/__pycache__/run.cpython-37.pyc index 82a321aab..0b3962345 100644 Binary files a/__pycache__/run.cpython-37.pyc and b/__pycache__/run.cpython-37.pyc differ diff --git a/frontend/index.html b/frontend/index.html index d5c2c05b5..48ec241d1 100755 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,7 +3,7 @@ - istacking + StackVis
diff --git a/frontend/src/components/Algorithms.vue b/frontend/src/components/Algorithms.vue index c2ef5db8a..bcce5b4dd 100644 --- a/frontend/src/components/Algorithms.vue +++ b/frontend/src/components/Algorithms.vue @@ -23,9 +23,12 @@ export default { brushedBoxPl: [], previousColor: 0, selectedAlgorithm: 0, + AllAlgorithms: ['KNN','RF'], KNNModels: 576, //KNN models WH: [], parameters: [], + algorithm1: [], + algorithm2: [], chart: '' } }, @@ -34,28 +37,22 @@ export default { d3.selectAll("#exploding_boxplot > *").remove(); const PerformAlgor1 = JSON.parse(this.PerformanceAllModels[0]) const PerformAlgor2 = JSON.parse(this.PerformanceAllModels[2]) - var algorithm1 = [] - var algorithm2 = [] + this.algorithm1 = [] + this.algorithm2 = [] var parameters = [] for (var i = 0; i < Object.keys(PerformAlgor1['0']).length; i++) { - algorithm1.push({Performance: Object.values(PerformAlgor1['0'])[i]*100,Algorithm:'KNN',Model:'Model ' + i + '; Parameters '+JSON.stringify(Object.values(PerformAlgor1['params'])[i])+'; Performance '}) + this.algorithm1.push({Performance: Object.values(PerformAlgor1['0'])[i]*100,Algorithm:'KNN',Model:'Model ' + i + '; Parameters '+JSON.stringify(Object.values(PerformAlgor1['params'])[i])+'; Performance ',ModelID:i}) parameters.push(JSON.stringify(Object.values(PerformAlgor1['params'])[i])) } var temp = i for (let j = 0; j < Object.keys(PerformAlgor2['0']).length; j++) { temp = i + j - algorithm2.push({Performance: Object.values(PerformAlgor2['0'])[j]*100,Algorithm:'RF',Model:'Model ' + temp + '; Parameters '+JSON.stringify(Object.values(PerformAlgor2['params'])[j])+'; Performance '}) + this.algorithm2.push({Performance: Object.values(PerformAlgor2['0'])[j]*100,Algorithm:'RF',Model:'Model ' + temp + '; Parameters '+JSON.stringify(Object.values(PerformAlgor2['params'])[j])+'; Performance ',ModelID:temp}) parameters.push(JSON.stringify(Object.values(PerformAlgor2['params'])[j])) } EventBus.$emit('ParametersAll', parameters) - var data = algorithm1.concat(algorithm2) - /*median.push(sum/Object.keys(PerformAlgor2['0']).length) - if (median[0] > median[1]) - var data = algorithm1.concat(algorithm2) - else - var data = algorithm2.concat(algorithm1)*/ + var data = this.algorithm1.concat(this.algorithm2) - // chart(data,aes) // aesthetic : // y : point's value on y axis // group : how to group data on x axis @@ -104,7 +101,70 @@ export default { }, brushActivationAll () { // continue here and select the correct points. - console.log(this.chart.returnBrush()) + var limiter = this.chart.returnBrush() + + var algorithm = [] + const previousColor = ['#8dd3c7','#ffffb3','#bebada','#fb8072','#80b1d3','#fdb462','#b3de69','#fccde5','#d9d9d9','#bc80bd','#ccebc5','#ffed6f'] + var modelsActive = [] + for (var j = 0; j < this.AllAlgorithms.length; j++) { + algorithm = [] + modelsActive = [] + if (this.AllAlgorithms[j] === 'KNN') { + var allPoints = document.getElementsByClassName('d3-exploding-boxplot point KNN') + algorithm = this.algorithm1 + } else { + var allPoints = document.getElementsByClassName('d3-exploding-boxplot point RF') + algorithm = this.algorithm2 + } + for (let k = 0; k < allPoints.length; k++) { + if (algorithm[k].Performance < limiter[0] && algorithm[k].Performance > limiter[1]) { + modelsActive.push(algorithm[k].ModelID) + } + } + for (let i = 0; i < allPoints.length; i++) { + if (this.AllAlgorithms[j] === 'KNN') { + allPoints[i].style.fill = previousColor[0] + } else { + allPoints[i].style.fill = previousColor[1] + } + } + + if (modelsActive.length == 0) { + for (let i = 0; i < allPoints.length; i++) { + //if (modelsActive.indexOf(i) == -1) { + allPoints[i].style.fill = "#d3d3d3" + allPoints[i].style.opacity = '1.0' + //} + } + } else if (modelsActive.length == allPoints.length) { + for (let i = 0; i < allPoints.length; i++) { + if (this.AllAlgorithms[j] === 'KNN') { + allPoints[i].style.fill = previousColor[0] + allPoints[i].style.opacity = '1.0' + } else { + allPoints[i].style.fill = previousColor[1] + allPoints[i].style.opacity = '1.0' + } + } + } else { + for (let i = 0; i < allPoints.length; i++) { + allPoints[i].style.opacity = '1.0' + if (this.AllAlgorithms[j] === 'KNN') { + if (modelsActive.indexOf(i) == -1) { + allPoints[i].style.fill = "#d3d3d3" + allPoints[i].style.opacity = '0.4' + } + } else { + if (modelsActive.indexOf(i+this.KNNModels) == -1) { + allPoints[i].style.fill = "#d3d3d3" + allPoints[i].style.opacity = '0.4' + } + } + } + } + } + + this.UpdateBarChart() }, brushed () { if (this.selectedAlgorithm == 'KNN') { diff --git a/frontend/src/components/BarChart.vue b/frontend/src/components/BarChart.vue index 00ae89837..55d0ebb2a 100644 --- a/frontend/src/components/BarChart.vue +++ b/frontend/src/components/BarChart.vue @@ -85,9 +85,9 @@ export default { } }*/ var layout = { - autosize: false, + autosize: true, barmode: 'group', - width: 550, + width: 650, height: 400, xaxis: { title: 'Algorithm', @@ -132,6 +132,13 @@ export default { }, exponentformat: 'e', showexponent: 'all' + }, + margin: { + l: 40, + r: 0, + b: 40, + t: 25, + pad: 0 } } /*for (let j = 0; j < ClassNames.length; j++) { diff --git a/frontend/src/components/CurrentStack.vue b/frontend/src/components/CurrentStack.vue deleted file mode 100644 index 387c2512e..000000000 --- a/frontend/src/components/CurrentStack.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - \ No newline at end of file diff --git a/frontend/src/components/Main.vue b/frontend/src/components/Main.vue index 11bacf4c0..c5501d684 100755 --- a/frontend/src/components/Main.vue +++ b/frontend/src/components/Main.vue @@ -15,25 +15,14 @@ - - - Data Space Visualization - - - - - - - Models Space Visualization - [Sel.:{{OverSelLength}}/All:{{OverAllLength}}] + [Sel.:{{OverSelLength}}/All:{{OverAllLength}}] @@ -52,6 +41,16 @@ + + + Data Space Visualization + + + + + + + @@ -101,22 +100,14 @@ - + - Current Stacking Ensemble + Current Stacking Ensemble and Provenance Visualization - - - Provenance Visualization - - - - - @@ -139,7 +130,6 @@ import BarChart from './BarChart.vue' import Heatmap from './Heatmap.vue' import ToggleSelection from './ToggleSelection.vue' import FinalResultsLinePlot from './FinalResultsLinePlot.vue' -import CurrentStack from './CurrentStack.vue' import Provenance from './Provenance.vue' import axios from 'axios' import { loadProgressBar } from 'axios-progress-bar' @@ -171,7 +161,6 @@ export default Vue.extend({ Heatmap, ToggleSelection, Provenance, - CurrentStack, FinalResultsLinePlot, mdbCard, mdbCardBody, @@ -216,6 +205,7 @@ export default Vue.extend({ selectVisualRepresentation () { const representationSelectionDocum = document.getElementById('selectBarChart') this.representationSelection = representationSelectionDocum.options[representationSelectionDocum.selectedIndex].value + console.log(this.representationSelection) EventBus.$emit('RepresentationSelection', this.representationSelection) }, getCollection () { diff --git a/frontend/src/components/PerMetricBarChart.vue b/frontend/src/components/PerMetricBarChart.vue index 7c3ab7e57..9d74c70c8 100644 --- a/frontend/src/components/PerMetricBarChart.vue +++ b/frontend/src/components/PerMetricBarChart.vue @@ -10,8 +10,7 @@ export default { name: 'PerMetricsBarChart', data () { return { - barchartmetrics: '', - representationDefault: 'bar' + barchartmetrics: '' } }, methods: { @@ -19,8 +18,8 @@ export default { var metricsPerModel = JSON.parse(this.barchartmetrics[9]) var vh = 80 - if (this.representationDefault === 'bar'){ - var type = 'bar'; + /*if (this.representationDefault === 'bar'){ + var type = 'bar'; } else if (this.representationDefault === 'line'){ var type = 'line'; } else { @@ -29,9 +28,9 @@ export default { var difference = []; for (var i=0; i {this.barchartmetrics = data;}) EventBus.$on('InitializeMetricsBarChart', this.LineBar) - EventBus.$on('RepresentationSelection', this.LineBar) - EventBus.$on('RepresentationSelection', data => {this.representationDefault = data}) } } \ No newline at end of file diff --git a/frontend/src/components/ScatterPlot.vue b/frontend/src/components/ScatterPlot.vue index 450427c56..e482a80a5 100644 --- a/frontend/src/components/ScatterPlot.vue +++ b/frontend/src/components/ScatterPlot.vue @@ -16,7 +16,7 @@ export default { data () { return { ScatterPlotResults: '', - representationDefault: 'MDS', + representationDef: 'MDS', colorsforOver: [], brushedBox : [], max: 0, @@ -56,10 +56,10 @@ export default { Plotly.purge('OverviewPlotly') var colorsforScatterPlot = JSON.parse(this.ScatterPlotResults[0]) - console.log(colorsforScatterPlot) var MDSData = JSON.parse(this.ScatterPlotResults[1]) - console.log(MDSData) var parameters = JSON.parse(this.ScatterPlotResults[2]) + var tSNEData = JSON.parse(this.ScatterPlotResults[12]) + parameters = JSON.parse(parameters) var classifiersInfo = this.brushedBox var keepingArrayIndices = [] @@ -75,7 +75,6 @@ export default { } } } - var flag this.length = keepingArrayIndices.length EventBus.$emit('sendPointsNumber', this.length) @@ -97,8 +96,7 @@ export default { counter++ } } - console.log(MDSData) - console.log(colorsforScatterPlot) + if (this.colorsforOver.length != 0) { if (this.colorsforOver[1].length != 0) { MDSData = this.colorsforOver[1] @@ -107,13 +105,15 @@ export default { colorsforScatterPlot = this.colorsforOver[0] } } - console.log(this.colorsforOver) + console.log(MDSData) + console.log(tSNEData) var classifiersInfoProcessing = [] for (let i = 0; i < modelsDetails.length; i++) { classifiersInfoProcessing[i] = 'Model ID: ' + modelsIDs[i] + '; Details: ' + modelsDetails[i] } var DataGeneral var layout + if (this.representationDef == 'MDS') { DataGeneral = [{ type: 'scatter', mode: 'markers', @@ -149,6 +149,43 @@ export default { hoverlabel: { bgcolor: "#FFF" }, legend: {orientation: 'h', y: -0.3}, } + } else { + DataGeneral = [{ + type: 'scatter', + mode: 'markers', + x: tSNEData[0], + y: tSNEData[1], + hovertemplate: + "%{text}

" + + "", + text: classifiersInfoProcessing, + marker: { + color: colorsforScatterPlot, + size: 12, + colorscale: 'Viridis', + colorbar: { + title: 'Metrics Average', + titleside: 'Top' + }, + } + }] + layout = { + title: 'Models Performance (MDS)', + xaxis: { + visible: false + }, + yaxis: { + visible: false + }, + autosize: true, + width: 400, + height: 400, + dragmode: 'lasso', + hovermode: "closest", + hoverlabel: { bgcolor: "#FFF" }, + legend: {orientation: 'h', y: -0.3}, + } + } var config = {scrollZoom: true, displaylogo: false, showLink: false, showSendToCloud: false, modeBarButtonsToRemove: ['toImage', 'toggleSpikelines', 'autoScale2d', 'hoverClosestGl2d','hoverCompareCartesian','select2d','hoverClosestCartesian','zoomIn2d','zoomOut2d','zoom2d'], responsive: true} @@ -193,6 +230,8 @@ export default { this.colorsforOver = data}) EventBus.$on('ParametersAll', data => { this.parametersAll = data }) EventBus.$on('getColors', this.UpdateScatter) + EventBus.$on('RepresentationSelection', data => {this.representationDef = data}) + EventBus.$on('RepresentationSelection', this.ScatterPlotView) } } \ No newline at end of file diff --git a/run.py b/run.py index b2219d392..fa5ed1e73 100644 --- a/run.py +++ b/run.py @@ -496,6 +496,7 @@ def InitializeEnsemble(): ModelSpaceMDS = FunMDS(XClassifiers) ModelSpaceTSNE = FunTsne(XClassifiers) ModelSpaceTSNE = ModelSpaceTSNE.tolist() + print(ModelSpaceTSNE) global ClassifierIDsList key = 0 EnsembleModel(ClassifierIDsList, key) @@ -530,6 +531,7 @@ def ReturnResults(sumPerClassifier,ModelSpaceMDS,ModelSpaceTSNE,preProcessResult Results.append(json.dumps(metricsPerModel)) # Position: 9 Results.append(perm_imp_eli5PDCon) # Position: 10 Results.append(featureScoresCon) # Position: 11 + Results.append(json.dumps(ModelSpaceTSNE)) # Position: 12 return Results # Retrieve data from client