master
parent 8f1ca2a081
commit 655408f595
  1. BIN
      __pycache__/run.cpython-37.pyc
  2. 1
      cachedir/joblib/run/GridSearchForModels/10f352afa4c8547af96ab9905e3cfc87/metadata.json
  3. BIN
      cachedir/joblib/run/GridSearchForModels/1ace3632acb8ced29677b3bf1fd54ebb/output.pkl
  4. 1
      cachedir/joblib/run/GridSearchForModels/7ed3e4ea234ba6e59e062c08100338df/metadata.json
  5. BIN
      cachedir/joblib/run/GridSearchForModels/e32f76451401c1a4c95d459bb4c74ce5/output.pkl
  6. 2
      cachedir/joblib/run/GridSearchForModels/func_code.py
  7. 206
      frontend/src/components/BalancePredictions.vue
  8. 9
      frontend/src/components/BarChart.vue
  9. 108
      frontend/src/components/DataSpace.vue
  10. 140
      frontend/src/components/Main.vue
  11. 51
      frontend/src/components/PCPData.vue
  12. 66
      frontend/src/components/Parameters.vue
  13. 4
      frontend/src/components/PredictionsSpace.vue
  14. 2
      frontend/src/components/ScatterPlot.vue
  15. 4
      frontend/src/main.js
  16. 130
      run.py

Binary file not shown.

@ -1 +0,0 @@
{"duration": 348.3931636810303, "input_args": {"clf": "RandomForestClassifier(bootstrap=True, class_weight=None, criterion='entropy',\n max_depth=None, max_features='auto', max_leaf_nodes=None,\n min_impurity_decrease=0.0, min_impurity_split=None,\n min_samples_leaf=1, min_samples_split=2,\n min_weight_fraction_leaf=0.0, n_estimators=119,\n n_jobs=None, oob_score=False, random_state=None,\n verbose=0, warm_start=False)", "params": "{'n_estimators': [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119], 'criterion': ['gini', 'entropy']}", "eachAlgor": "'RF'", "factors": "[1, 1, 1, 1, 1]", "AlgorithmsIDsEnd": "576"}}

@ -1 +0,0 @@
{"duration": 258.0446789264679, "input_args": {"clf": "KNeighborsClassifier(algorithm='ball_tree', leaf_size=30, metric='minkowski',\n metric_params=None, n_jobs=None, n_neighbors=24, p=2,\n weights='distance')", "params": "{'n_neighbors': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], 'weights': ['uniform', 'distance'], 'algorithm': ['brute', 'kd_tree', 'ball_tree'], 'metric': ['chebyshev', 'manhattan', 'euclidean', 'minkowski']}", "eachAlgor": "'KNN'", "factors": "[1, 1, 1, 1, 1]", "AlgorithmsIDsEnd": "0"}}

@ -1,4 +1,4 @@
# first line: 307
# first line: 371
@memory.cache
def GridSearchForModels(clf, params, eachAlgor, factors, AlgorithmsIDsEnd):

@ -7,6 +7,7 @@
<script>
import { EventBus } from '../main.js'
import * as d3Base from 'd3'
import { counter } from '@fortawesome/fontawesome-svg-core'
// attach all d3 plugins to the d3 library
const d3 = Object.assign(d3Base)
@ -15,19 +16,51 @@
name: 'BalancePredictions',
data () {
return {
resultsfromOverview: 0,
WH: []
resultsfromOverview: '',
newResultsFromSelection: '',
responsiveWidthHeight: []
}
},
methods: {
Balance () {
// Clear Heatmap first
// erase histogram
var svg = d3.select("#my_dataviz");
svg.selectAll("*").remove();
var widthInitial = this.WH[0]*3 // interactive visualization
var heightInitial = this.WH[1]/1.6 // interactive visualization
// responsive visualizations
var widthInitial = this.responsiveWidthHeight[0]*3
var heightInitial = this.responsiveWidthHeight[1]/1.6
var performancePerModel = JSON.parse(this.resultsfromOverview[0])
var performancePerModelSelection = []
if (this.newResultsFromSelection.length != 0) {
var performancePerModelSelection = JSON.parse(this.newResultsFromSelection[0])
}
var modelId = JSON.parse(this.resultsfromOverview[13])
var data = []
performancePerModel.forEach(element => {
let el = {}
el.type = "variable 1"
el.value = element * 100
data.push(el)
})
if (performancePerModelSelection.length == 0) {
performancePerModel.forEach(element => {
let el = {}
el.type = "variable 2"
el.value = element * 100
data.push(el)
})
} else {
performancePerModelSelection.forEach(element => {
let el = {}
el.type = "variable 2"
el.value = element * 100
data.push(el)
})
}
// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 50, left: 60},
@ -43,77 +76,118 @@
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// get the data
d3.csv("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_doubleHist.csv").then( function(data) {
// add the x Axis
var x = d3.scaleLinear()
.domain([-10,15])
.domain([0,100])
.range([0, width]);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the first y Axis
// set the parameters for the histogram
var histogram = d3.histogram()
.value(function(d) { return +d.value; }) // I need to give the vector of value
.domain(x.domain()) // then the domain of the graphic
.thresholds(x.ticks(40)); // then the numbers of bins
// And apply twice this function to data to get the bins.
var bins1 = histogram(data.filter( function(d){return d.type === "variable 1"} ));
var bins2 = histogram(data.filter( function(d){return d.type === "variable 2"} ));
// Y axis: scale and draw:
var y1 = d3.scaleLinear()
.range([height/2, 0])
.domain([0, 0.12]);
.range([height/2, 0])
.domain([0, d3.max(bins1, function(d) { return d.length; })]); // d3.hist has to be called before the Y axis obviously
svg.append("g")
.attr("transform", "translate(-20,0)")
.call(d3.axisLeft(y1).tickValues([0.05, 0.1]));
.call(d3.axisLeft(y1));
// add the first y Axis
// Y axis: scale and draw:
var y2 = d3.scaleLinear()
.range([height/2, height])
.domain([0, 0.12]);
.range([height/2, height])
.domain([0, d3.max(bins2, function(d) { return d.length; })]); // d3.hist has to be called before the Y axis obviously
svg.append("g")
.attr("transform", "translate(-20,0)")
.call(d3.axisLeft(y2).ticks(2).tickSizeOuter(0));
// Compute kernel density estimation
var kde = kernelDensityEstimator(kernelEpanechnikov(7), x.ticks(60))
var density1 = kde( data.filter( function(d){return d.type === "variable 1"} ).map(function(d){ return d.value; }) )
var density2 = kde( data.filter( function(d){return d.type === "variable 2"} ).map(function(d){ return d.value; }) )
// Plot the area
svg.append("path")
.attr("class", "mypath")
.datum(density1)
.attr("fill", "#000")
.attr("opacity", "1")
.attr("stroke", "#000")
.attr("stroke-width", 1)
.attr("stroke-linejoin", "round")
.attr("d", d3.line()
.curve(d3.curveBasis)
.x(function(d) { return x(d[0]); })
.y(function(d) { return y1(d[1]); })
);
// Plot the area
svg.append("path")
.attr("class", "mypath")
.datum(density2)
.attr("fill", "#D3D3D3")
.attr("opacity", "1")
.attr("stroke", "#000")
.attr("stroke-width", 1)
.attr("stroke-linejoin", "round")
.attr("d", d3.line()
.curve(d3.curveBasis)
.x(function(d) { return x(d[0]); })
.y(function(d) { return y2(d[1]); })
);
}).catch(function(error){
// handle error
})
.call(d3.axisLeft(y2));
// Add a tooltip div. Here I define the general feature of the tooltip: stuff that do not depend on the data point.
// Its opacity is set to 0: we don't see it by default.
var tooltip = d3.select("#my_dataviz")
.append("div")
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "black")
.style("color", "white")
.style("border-radius", "5px")
.style("padding", "10px")
// A function that change this tooltip when the user hover a point.
// Its opacity is set to 1: we can now see it. Plus it set the text and position of tooltip depending on the datapoint (d)
var showTooltip = function(d) {
tooltip
.transition()
.duration(100)
.style("opacity", 1)
tooltip
.html("Range: " + d.x0 + " - " + d.x1)
.style("left", (d3.mouse(this)[0]+20) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
var moveTooltip = function(d) {
tooltip
.style("left", (d3.mouse(this)[0]+20) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
// A function that change this tooltip when the leaves a point: just need to set opacity to 0 again
var hideTooltip = function(d) {
tooltip
.transition()
.duration(100)
.style("opacity", 0)
}
// append the bars for series 1
svg.selectAll("rect")
.data(bins1)
.enter()
.append("rect")
.attr("x", 1)
.attr("transform", function(d) { return "translate(" + x(d.x0) + "," + y1(d.length) + ")"; })
.attr("width", function(d) { return x(d.x1) - x(d.x0) - 1 ; })
.attr("height", function(d) { return height/2 - y1(d.length); })
.attr("stroke-linejoin", "round")
.style("fill", "#000000")
.style("opacity", 1)
.on("mouseover", showTooltip )
.on("mousemove", moveTooltip )
.on("mouseleave", hideTooltip )
// append the bars for series 2
svg.selectAll("rect2")
.data(bins2)
.enter()
.append("rect")
.attr("x", 1)
.attr("transform", function(d) { return "translate(" + x(d.x0) + "," + height/2 + ")"; })
.attr("width", function(d) { return x(d.x1) - x(d.x0) - 1 ; })
.attr("height", function(d) { return y2(d.length) - height/2; })
.attr("stroke-linejoin", "round")
.style("fill", "#D3D3D3")
.style("opacity", 1)
// Show tooltip on hover
.on("mouseover", showTooltip )
.on("mousemove", moveTooltip )
.on("mouseleave", hideTooltip )
// Handmade legend
var heightforText = 175
svg.append("circle").attr("cx",80).attr("cy",heightforText).attr("r", 6).style("fill", "#000")
svg.append("circle").attr("cx",300).attr("cy",heightforText).attr("r", 6).style("fill", "#D3D3D3")
svg.append("text").attr("x", 100).attr("y", heightforText).text("Entire distribution").style("font-size", "15px").attr("alignment-baseline","middle")
svg.append("text").attr("x", 320).attr("y", heightforText).text("Selected points").style("font-size", "15px").attr("alignment-baseline","middle")
svg.append("circle").attr("cx",30).attr("cy",heightforText).attr("r", 6).style("fill", "#000")
svg.append("circle").attr("cx",350).attr("cy",heightforText).attr("r", 6).style("fill", "#D3D3D3")
svg.append("text").attr("x", 50).attr("y", heightforText).text("Entire distribution").style("font-size", "15px").attr("alignment-baseline","middle")
svg.append("text").attr("x", 210).attr("y", heightforText).text("Performance").style("font-size", "15px").attr("alignment-baseline","top")
svg.append("text").attr("x", 370).attr("y", heightforText).text("Selected points").style("font-size", "15px").attr("alignment-baseline","middle")
// Function to compute density
function kernelDensityEstimator(kernel, X) {
@ -133,10 +207,18 @@
mounted () {
EventBus.$on('emittedEventCallingBalanceView', data => { this.resultsfromOverview = data} )
EventBus.$on('emittedEventCallingBalanceView', this.Balance)
EventBus.$on('UpdateBalanceView', data => { this.newResultsFromSelection = data} )
EventBus.$on('UpdateBalanceView', this.Balance)
EventBus.$on('Responsive', data => {
this.WH = data})
this.responsiveWidthHeight = data})
EventBus.$on('ResponsiveandChange', data => {
this.WH = data})
this.responsiveWidthHeight = data})
}
}
</script>
<style>
.hover {
fill: #69c;
}
</style>

@ -18,7 +18,8 @@ export default {
ClassNamesOverview: '',
algorithmsinBar: [],
modelsSelectedinBar: [],
KNNModels: 576, //KNN models
KNNModels: 576, //KNN models,
colorsValues: ['#6a3d9a','#b15928','#e31a1c'],
WH: []
}
},
@ -136,7 +137,7 @@ export default {
var traces = []
var tracesSel = []
var data = []
var colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a']
for (var i = 0; i < target_names.length; i++) {
traces[i] = {
x: ['KNN', 'RF'],
@ -145,7 +146,7 @@ export default {
opacity: 0.5,
marker: {
opacity: 0.5,
color: colors[i]
color: this.colorsValues[i]
},
type: 'bar'
};
@ -158,7 +159,7 @@ export default {
mode: 'markers',
marker: {
opacity: 1.0,
color: colors[i],
color: this.colorsValues[i],
},
width: [0.1, 0.1]
};

@ -1,5 +1,43 @@
<template>
<div id="OverviewDataPlotly" class="OverviewDataPlotly"></div>
<div>
<div align="center">
Filter: <select id="selectFilterID" @change="selectAppliedFilter()">
<option value="mean" selected>Mean</option>
<option value="median">Median</option>
</select>
Action: <button
id="mergeID"
v-on:click="merge">
<font-awesome-icon icon="object-group" />
{{ mergeData }}
</button>
<button
id="composeID"
v-on:click="compose">
<font-awesome-icon icon="clone" />
{{ composeData }}
</button>
<button
id="removeID"
v-on:click="remove">
<font-awesome-icon icon="eraser" />
{{ removeData }}
</button>
Provenance Controller: <button
id="saveID"
v-on:click="save">
<font-awesome-icon icon="save" />
{{ saveData }}
</button>
<button
id="restoreID"
v-on:click="restore">
<font-awesome-icon icon="undo" />
{{ restoreData }}
</button>
</div>
<div id="OverviewDataPlotly" class="OverviewDataPlotly"></div>
</div>
</template>
<script>
@ -12,21 +50,47 @@ export default {
return {
dataPoints: '',
highlightedPoints: '',
mergeData: 'Merge',
removeData: 'Remove',
composeData: 'Compose',
saveData: 'Save Step',
restoreData: 'Restore Step',
userSelectedFilter: 'mean',
responsiveWidthHeight: [],
colorsValues: ['#00bbbb','#b15928','#ff7f00']
colorsValues: ['#6a3d9a','#b15928','#e31a1c']
}
},
methods: {
selectAppliedFilter () {
var representationSelectionDocum = document.getElementById('selectFilterID')
this.userSelectedFilter = representationSelectionDocum.options[representationSelectionDocum.selectedIndex].value
EventBus.$emit('SendFilter', this.userSelectedFilter)
},
merge() {
EventBus.$emit('SendAction', 'merge')
},
remove () {
EventBus.$emit('SendAction', 'remove')
},
compose () {
EventBus.$emit('SendAction', 'compose')
},
save () {
EventBus.$emit('SendProvenance', 'save')
},
restore () {
EventBus.$emit('SendProvenance', 'restore')
},
scatterPlotDataView () {
// responsive visualization
let width = this.responsiveWidthHeight[0]*3
let height = this.responsiveWidthHeight[1]*2.1
var target_names = JSON.parse(this.dataPoints[4])
const XandYCoordinates = JSON.parse(this.dataPoints[7])
const DataSet = JSON.parse(this.dataPoints[14])
const DataSetY = JSON.parse(this.dataPoints[15])
const originalDataLabels = JSON.parse(this.dataPoints[16])
var target_names = JSON.parse(this.dataPoints[0])
const XandYCoordinates = JSON.parse(this.dataPoints[1])
const DataSet = JSON.parse(this.dataPoints[2])
const DataSetY = JSON.parse(this.dataPoints[3])
const originalDataLabels = JSON.parse(this.dataPoints[4])
var DataSetParse = JSON.parse(DataSet)
let intData = []
@ -88,7 +152,7 @@ export default {
y: aux_Y,
mode: 'markers',
name: target_names[i],
marker: { color: this.colorsValues[i], line: { color: 'rgb(0, 0, 0)', width: 2 }, opacity: Opacity },
marker: { color: this.colorsValues[i], line: { color: 'rgb(0, 0, 0)', width: 2 }, opacity: Opacity, size: 12 },
hovertemplate:
"<b>%{text}</b><br><br>" +
"<extra></extra>",
@ -114,6 +178,34 @@ export default {
var config = {scrollZoom: true, displaylogo: false, showLink: false, showSendToCloud: false, modeBarButtonsToRemove: ['toImage', 'toggleSpikelines', 'autoScale2d', 'hoverClosestGl2d','hoverCompareCartesian','select2d','hoverClosestCartesian','zoomIn2d','zoomOut2d','zoom2d'], responsive: true}
Plotly.newPlot('OverviewDataPlotly', traces, layout, config)
this.selectedDataPoints()
},
selectedDataPoints () {
const OverviewDataPlotly = document.getElementById('OverviewDataPlotly')
OverviewDataPlotly.on('plotly_selected', function (evt) {
if (typeof evt !== 'undefined') {
const ClassifierIDsList = []
const ClassifierIDsListCleared = []
for (let i = 0; evt.points.length; i++) {
if (evt.points[i] === undefined) {
break
} else {
const OnlyId = evt.points[i].text.split(';')
ClassifierIDsList.push(OnlyId[0])
let numb = OnlyId[0].match(/\d/g);
numb = numb.join("");
let numberNumb = Number(numb)
ClassifierIDsListCleared.push(numberNumb)
}
}
if (ClassifierIDsList != '') {
EventBus.$emit('SendSelectedPointsToServerEventfromData', ClassifierIDsListCleared)
} else {
EventBus.$emit('SendSelectedPointsToServerEventfromData', '')
}
}
})
}
},
mounted() {

@ -15,7 +15,7 @@
</mdb-card-body>
</mdb-card>
<mdb-card style="margin-top: 15px">
<mdb-card-header color="primary-color" tag="h5" class="text-center">HyperParameters Space Exploration Overview and Visual Encoding</mdb-card-header>
<mdb-card-header color="primary-color" tag="h5" class="text-center">HyperParameters Space Exploration Overview</mdb-card-header>
<mdb-card-body>
<Parameters/>
</mdb-card-body>
@ -49,6 +49,7 @@
<mdb-card-body>
<mdb-card-text class="text-center">
<DataSpace/>
<PCPData/>
</mdb-card-text>
</mdb-card-body>
</mdb-card>
@ -136,6 +137,7 @@ import ToggleSelection from './ToggleSelection.vue'
import FinalResultsLinePlot from './FinalResultsLinePlot.vue'
import Provenance from './Provenance.vue'
import Parameters from './Parameters.vue'
import PCPData from './PCPData.vue'
import axios from 'axios'
import { loadProgressBar } from 'axios-progress-bar'
import 'axios-progress-bar/dist/nprogress.css'
@ -167,6 +169,7 @@ export default Vue.extend({
ToggleSelection,
Provenance,
Parameters,
PCPData,
FinalResultsLinePlot,
mdbCard,
mdbCardBody,
@ -177,6 +180,7 @@ export default Vue.extend({
return {
Collection: 0,
OverviewResults: 0,
preDataResults: '',
RetrieveValueFile: 'IrisC',
ClassifierIDsList: '',
SelectedFeaturesPerClassifier: '',
@ -207,7 +211,12 @@ export default Vue.extend({
AlgorithmsUpdate: [],
SelectedMetricsForModels: [],
DataPointsSel: '',
DataPointsModels: ''
DataPointsModels: '',
dataPointsSelfromDataSpace: '',
userSelectedFilterMain: 'mean',
actionData: '',
filterData: '',
provenanceData: ''
}
},
methods: {
@ -267,7 +276,6 @@ export default Vue.extend({
EventBus.$emit('emitToggles', this.OverviewResults)
EventBus.$emit('emittedEventCallingToggles', toggles)
EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults)
EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults)
EventBus.$emit('emittedEventCallingPredictionsSpacePlotView', this.OverviewResults)
EventBus.$emit('emittedEventCallingBalanceView', this.OverviewResults)
this.getFinalResults()
@ -421,6 +429,7 @@ export default Vue.extend({
this.DataPointsModels = response.data.DataPointsModels
console.log('Server successfully sent the new models for the scatterplot!')
EventBus.$emit('UpdateModelsScatterplot', this.DataPointsModels)
EventBus.$emit('UpdateBalanceView', this.DataPointsModels)
})
.catch(error => {
console.log(error)
@ -486,12 +495,34 @@ export default Vue.extend({
axios.post(path, postData, axiosConfig)
.then(response => {
console.log('Send request to server! FileName was sent successfully!')
this.SendAlgorithmsToServer()
this.DataSpaceCall()
this.SendAlgorithmsToServer()
})
.catch(error => {
console.log(error)
})
},
DataSpaceCall () {
const path = `http://localhost:5000/data/requestDataSpaceResults`
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
}
}
axios.get(path, axiosConfig)
.then(response => {
this.preDataResults = response.data.preDataResults
EventBus.$emit('emittedEventCallingDataSpacePlotView', this.preDataResults)
EventBus.$emit('emittedEventCallingDataPCP', this.preDataResults)
})
.catch(error => {
console.log(error)
})
},
SendAlgorithmsToServer () {
const path = `http://127.0.0.1:5000/data/ServerRequestSelParameters`
const postData = {
@ -682,9 +713,93 @@ export default Vue.extend({
toggles.push(this.toggle2)
toggles.push(this.toggle3)
EventBus.$emit('emittedEventCallingTogglesUpdate', toggles)
}
},
DataSpaceFun () {
const path = `http://127.0.0.1:5000/data/SendDataSpacPoints`
const postData = {
points: this.dataPointsSelfromDataSpace
}
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
}
}
axios.post(path, postData, axiosConfig)
.then(response => {
console.log('Send request to server! Brushed points sent successfully!')
})
.catch(error => {
console.log(error)
})
},
FilterFun () {
const path = `http://127.0.0.1:5000/data/UpdateFilter`
const postData = {
filter: this.filterData
}
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
}
}
axios.post(path, postData, axiosConfig)
.then(response => {
console.log('Send request to server! Updated filter!')
})
.catch(error => {
console.log(error)
})
},
ActionFun () {
const path = `http://127.0.0.1:5000/data/UpdateAction`
const postData = {
action: this.actionData
}
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
}
}
axios.post(path, postData, axiosConfig)
.then(response => {
console.log('Send request to server! Updated action!')
})
.catch(error => {
console.log(error)
})
},
ProvenanceControlFun () {
const path = `http://127.0.0.1:5000/data/UpdateProvenanceState`
const postData = {
provenance: this.provenanceData
}
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
}
}
axios.post(path, postData, axiosConfig)
.then(response => {
console.log('Send request to server! Updated provenance state!')
})
.catch(error => {
console.log(error)
})
},
},
created() {
created () {
// does the browser support the Navigation Timing API?
if (window.performance) {
console.info("window.performance is supported");
@ -741,6 +856,19 @@ export default Vue.extend({
EventBus.$on('sendPointsNumber', data => {this.OverAllLength = data})
EventBus.$on('AllSelModels', data => {this.valueSel = data})
EventBus.$on('RemoveFromStack', this.RemoveFromStackModels)
EventBus.$on('SendSelectedPointsToServerEventfromData', data => {this.dataPointsSelfromDataSpace = data})
EventBus.$on('SendSelectedPointsToServerEventfromData', this.DataSpaceFun)
EventBus.$on('SendFilter', data => {this.filterData = data})
EventBus.$on('SendFilter', this.FilterFun)
EventBus.$on('SendAction', data => {this.actionData = data})
EventBus.$on('SendAction', this.ActionFun)
EventBus.$on('SendProvenance', data => {this.provenanceData = data})
EventBus.$on('SendProvenance', this.ProvenanceControlFun)
//Prevent double click to search for a word.
document.addEventListener('mousedown', function (event) {
if (event.detail > 1) {

@ -0,0 +1,51 @@
<template>
<div id="PCPDataView" class="parcoords" style="width: 300px; height:200px"></div>
</template>
<script>
import 'parcoord-es/dist/parcoords.css';
import ParCoords from 'parcoord-es';
import * as d3Base from 'd3'
// attach all d3 plugins to the d3 library
const d3 = Object.assign(d3Base)
import { EventBus } from '../main.js'
export default {
name: 'PCPData',
data () {
return {
PCPDataReceived: '',
colorsValues: ['#6a3d9a','#b15928','#e31a1c']
}
},
methods: {
PCPView () {
d3.selectAll("#PCPDataView > *").remove();
const target_names = JSON.parse(this.PCPDataReceived[3])
const DataSet = JSON.parse(this.PCPDataReceived[5])
const target = JSON.parse(this.PCPDataReceived[6])
var colors = this.colorsValues
this.pc = ParCoords()("#PCPDataView")
.data(DataSet)
.color(function(d, i) { return colors[target_names[i]] })
.hideAxis([target,'_id','InstanceID'])
.bundlingStrength(0) // set bundling strength
.smoothness(0)
.showControlPoints(false)
.render()
.brushMode('1D-axes')
.reorderable()
.interactive();
},
},
// fix when selecting points the pcp should update!
mounted() {
EventBus.$on('emittedEventCallingDataPCP', data => { this.PCPDataReceived = data })
EventBus.$on('emittedEventCallingDataPCP', this.PCPView)
EventBus.$on('ResponsiveandChange', this.PCPView)
}
}
</script>

@ -1,6 +1,14 @@
<template>
<div>
<div id="overview"></div>
<b-row class="md-3">
<b-col cols="12">
<div id="overview"></div>
</b-col>
<!--
<b-col cols="4">
<div id="encodings"></div>
</b-col>-->
</b-row>
</div>
</template>
@ -515,7 +523,56 @@ export default {
d3.selectAll("text.temporary-text").remove()
}
}
},
drawEncodings () {
// Clear Heatmap first
var svg = d3.select("#encodings");
svg.selectAll("*").remove();
var widthinter = this.WH[0]*0.95 // interactive visualization
var heightinter = this.WH[1]*0.5 // interactive visualization
/*
// Create the SVG element and set its dimensions.
var width = widthinter,
height = heightinter,
padding = 15;
var div = d3.select('#encodings'),
svg = div.append('svg');
svg.attr('width', width).attr('height', height);
// Create the svg:defs element and the main gradient definition.
var svgDefs = svg.append('defs');
var mainGradient = svgDefs.append('linearGradient')
.attr("id", "mainGradient")
.attr("x1", "0%")
.attr("x2", "100%")
.attr("y1", "0%")
.attr("y2", "100%");
mainGradient.append("stop")
.attr('class', 'start')
.attr("offset", "0%")
.attr("stop-color", "red")
.attr("stop-opacity", 1);
mainGradient.append("stop")
.attr('class', 'end')
.attr("offset", "100%")
.attr("stop-color", "blue")
.attr("stop-opacity", 1);
// Use the gradient to set the shape fill, via CSS.
svg.append('rect')
.classed('filled', true)
.attr('x', padding)
.attr('y', padding)
.attr('width', width - 2 * padding)
.attr('height', height - 2 * padding);
*/
}
},
mounted () {
EventBus.$on('updateFlagKNN', data => { this.FlagKNN = data })
@ -525,6 +582,7 @@ export default {
EventBus.$on('sendParameters', data => { this.storeParameters = data })
EventBus.$on('updateActiveModels', data => { this.storeActiveModels = data })
EventBus.$on('updateActiveModels', this.draw)
EventBus.$on('updateActiveModels', this.drawEncodings)
EventBus.$on('Responsive', data => {
this.WH = data})
EventBus.$on('ResponsiveandChange', data => {
@ -602,4 +660,8 @@ export default {
font-size: 14px;
fill: #fff;
}
.filled {
fill: url(#mainGradient);
}
</style>

@ -12,7 +12,7 @@ export default {
return {
PredictionsData: '',
UpdatedData: '',
colorsValues: ['#00bbbb','#b15928','#ff7f00'],
colorsValues: ['#6a3d9a','#b15928','#e31a1c'],
responsiveWidthHeight: []
}
},
@ -65,7 +65,7 @@ export default {
y: aux_Y,
mode: 'markers',
name: target_names[i],
marker: { color: this.colorsValues[i], line: { color: 'rgb(0, 0, 0)', width: 2 }, opacity: 1 },
marker: { color: this.colorsValues[i], line: { color: 'rgb(0, 0, 0)', width: 2 }, opacity: 1, size: 12 },
hovertemplate:
"<b>%{text}</b><br><br>" +
"<extra></extra>",

@ -31,7 +31,7 @@ export default {
return {
ScatterPlotResults: '',
representationDef: 'mds',
representationSelection: 'MDS',
representationSelection: 'mds',
colorsforOver: [],
brushedBox : [],
max: 0,

@ -6,10 +6,10 @@ import 'bootstrap-vue/dist/bootstrap-vue.css'
import router from './router'
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faUpload, faPlay, faCheck, faSave, faTrash, faPlus, faBalanceScale, faMinus} from '@fortawesome/free-solid-svg-icons'
import { faUpload, faPlay, faCheck, faSave, faTrash, faPlus, faBalanceScale, faMinus, faEraser, faClone, faObjectGroup, faUndo } from '@fortawesome/free-solid-svg-icons'
import bFormSlider from 'vue-bootstrap-slider'
library.add(faUpload, faPlay, faCheck, faSave, faTrash, faPlus, faBalanceScale, faMinus)
library.add(faUpload, faPlay, faCheck, faSave, faTrash, faPlus, faBalanceScale, faMinus, faEraser, faClone, faObjectGroup, faUndo)
Vue.component('font-awesome-icon', FontAwesomeIcon)

130
run.py

@ -7,6 +7,7 @@ import collections
import numpy as np
import re
from numpy import array
from statistics import mode
import pandas as pd
import warnings
import copy
@ -67,6 +68,12 @@ def Reset():
global yData
yData = []
global XDataStored
XDataStored = []
global yDataStored
yDataStored = []
global detailsParams
detailsParams = []
@ -136,6 +143,15 @@ def RetrieveFileName():
global yData
yData = []
global XDataStored
XDataStored = []
global yDataStored
yDataStored = []
global filterDataFinal
filterDataFinal = 'mean'
global ClassifierIDsList
ClassifierIDsList = ''
@ -224,6 +240,8 @@ def DataSetSelection():
DataResultsRaw.sort(key=lambda x: x[target], reverse=True)
DataResults.sort(key=lambda x: x[target], reverse=True)
dataBefore = copy.deepcopy(DataResults)
for dictionary in DataResults:
del dictionary['_id']
del dictionary['InstanceID']
@ -251,9 +269,40 @@ def DataSetSelection():
global XData, yData, RANDOM_SEED
XData, yData = ArrayDataResults, AllTargetsFloatValues
global XDataStored, yDataStored
XDataStored = XData.copy()
yDataStored = yData.copy()
DataSpaceRes = FunTsne(XData)
DataSpaceListRes = DataSpaceRes.tolist()
XDataJSONEntireSetRes = XData.to_json(orient='records')
global preResults
preResults = []
preResults.append(json.dumps(target_names)) # Position: 0
preResults.append(json.dumps(DataSpaceListRes)) # Position: 1
preResults.append(json.dumps(XDataJSONEntireSetRes)) # Position: 2
preResults.append(json.dumps(yData)) # Position: 3
preResults.append(json.dumps(AllTargets)) # Position: 4
preResults.append(json.dumps(dataBefore)) # Position: 5
preResults.append(json.dumps(target)) # Position: 6
warnings.simplefilter('ignore')
return 'Everything is okay'
# Sending each model's results to frontend
@app.route('/data/requestDataSpaceResults', methods=["GET", "POST"])
def SendDataSpaceResults():
global preResults
response = {
'preDataResults': preResults,
}
return jsonify(response)
# Main function
if __name__ == '__main__':
app.run()
@ -1260,3 +1309,84 @@ def SendToPlotFinalResults():
'FinalResults': scores
}
return jsonify(response)
# Retrieve data from client
@cross_origin(origin='localhost',headers=['Content-Type','Authorization'])
@app.route('/data/UpdateFilter', methods=["GET", "POST"])
def RetrieveFilter():
filterData = request.get_data().decode('utf8').replace("'", '"')
filterDataCleared = json.loads(filterData)
global filterDataFinal
filterDataFinal = filterDataCleared['filter']
return 'Done'
# Retrieve data from client
@cross_origin(origin='localhost',headers=['Content-Type','Authorization'])
@app.route('/data/SendDataSpacPoints', methods=["GET", "POST"])
def RetrieveDataSpacePoints():
dataSpacePoints = request.get_data().decode('utf8').replace("'", '"')
dataSpacePointsCleared = json.loads(dataSpacePoints)
global dataSpacePointsIDs
dataSpacePointsIDs = dataSpacePointsCleared['points']
return 'Done'
# Retrieve data from client
@cross_origin(origin='localhost',headers=['Content-Type','Authorization'])
@app.route('/data/UpdateAction', methods=["GET", "POST"])
def RetrieveAction():
filterAction = request.get_data().decode('utf8').replace("'", '"')
filterActionCleared = json.loads(filterAction)
global filterActionFinal
global dataSpacePointsIDs
global filterDataFinal
global XData
global yData
filterActionFinal = filterActionCleared['action']
if (filterActionFinal == 'merge'): # fix merge
if (filterDataFinal == 'mean' or filterDataFinal == ''):
mean = XData.iloc[dataSpacePointsIDs, :].mean()
XData.loc[len(XData)]= mean
else:
median = XData.iloc[dataSpacePointsIDs, :].median()
XData.loc[len(XData)]= median
elif (filterActionFinal == 'compose'):
if (filterDataFinal == 'mean' or filterDataFinal == ''):
mean = XData.iloc[dataSpacePointsIDs, :].mean()
XData.loc[len(XData)]= mean
else:
median = XData.iloc[dataSpacePointsIDs, :].median()
XData.loc[len(XData)]= median
yDataSelected = [yData[i] for i in dataSpacePointsIDs]
storeMode = mode(yDataSelected)
yData.append(storeMode)
else:
XData = XData.drop(dataSpacePointsIDs)
yData = [i for j, i in enumerate(yData) if j not in dataSpacePointsIDs]
print(XData)
print(yData)
return 'Done'
# Retrieve data from client
@cross_origin(origin='localhost',headers=['Content-Type','Authorization'])
@app.route('/data/UpdateProvenanceState', methods=["GET", "POST"])
def RetrieveProvenance():
filterProvenance = request.get_data().decode('utf8').replace("'", '"')
filterProvenanceCleared = json.loads(filterProvenance)
global filterProvenanceFinal
filterProvenanceFinal = filterProvenanceCleared['provenance']
global XDataStored
global XData
global yDataStored
global yData
# fix save and restore
if (filterProvenanceFinal == 'restore'):
XData = XDataStored.copy()
yData = yDataStored.copy()
return 'Done'
Loading…
Cancel
Save