Explicitly only skip the zeroth iteration of t-SNE update when sending new
points to the scatter plot. This fixes t-SNE bookmarks where the reprojection would occur, but not be sent to the scatter plot for rendering. Change: 137080345
This commit is contained in:
parent
79a2a241c4
commit
4a465522c1
@ -115,6 +115,7 @@ export class DataSet implements scatterPlot.DataSet {
|
||||
projections = d3.set();
|
||||
nearest: knn.NearestEntry[][];
|
||||
nearestK: number;
|
||||
tSNEIteration: number = 0;
|
||||
tSNEShouldStop = true;
|
||||
dim = [0, 0];
|
||||
hasTSNERun: boolean = false;
|
||||
@ -199,6 +200,13 @@ export class DataSet implements scatterPlot.DataSet {
|
||||
return accessors;
|
||||
}
|
||||
|
||||
hasMeaningfulVisualization(projection: Projection): boolean {
|
||||
if (projection !== 'tsne') {
|
||||
return true;
|
||||
}
|
||||
return this.tSNEIteration > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new subset dataset by copying out data. We make a copy because
|
||||
* we have to modify the vectors by normalizing them.
|
||||
@ -295,11 +303,12 @@ export class DataSet implements scatterPlot.DataSet {
|
||||
let opt = {epsilon: learningRate, perplexity: perplexity, dim: tsneDim};
|
||||
this.tsne = new TSNE(opt);
|
||||
this.tSNEShouldStop = false;
|
||||
let iter = 0;
|
||||
this.tSNEIteration = 0;
|
||||
|
||||
let step = () => {
|
||||
if (this.tSNEShouldStop) {
|
||||
stepCallback(null);
|
||||
this.tsne = null;
|
||||
return;
|
||||
}
|
||||
this.tsne.step();
|
||||
@ -313,8 +322,8 @@ export class DataSet implements scatterPlot.DataSet {
|
||||
dataPoint.projections['tsne-2'] = result[i * tsneDim + 2];
|
||||
}
|
||||
});
|
||||
iter++;
|
||||
stepCallback(iter);
|
||||
this.tSNEIteration++;
|
||||
stepCallback(this.tSNEIteration);
|
||||
requestAnimationFrame(step);
|
||||
};
|
||||
|
||||
@ -338,7 +347,6 @@ export class DataSet implements scatterPlot.DataSet {
|
||||
runAsyncTask('Initializing T-SNE...', () => {
|
||||
this.tsne.initDataDist(this.nearest);
|
||||
}).then(step);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -429,6 +437,9 @@ export interface State {
|
||||
/** The selected projection tab. */
|
||||
selectedProjection?: Projection;
|
||||
|
||||
/** The t-SNE iteration of this projection. */
|
||||
tSNEIteration?: number;
|
||||
|
||||
/** The projection component dimensions (for PCA) */
|
||||
componentDimensions?: number[];
|
||||
|
||||
|
@ -414,11 +414,9 @@ export class Projector extends ProjectorPolymer implements SelectionContext,
|
||||
this.scatterPlot.showTickLabels(false);
|
||||
this.scatterPlot.setPointAccessors(pointAccessors);
|
||||
|
||||
this.scatterPlot.update();
|
||||
/* tsne needs to do an iteration for the points to look reasonable
|
||||
if (projection !== 'tsne') {
|
||||
if (this.dataSet.hasMeaningfulVisualization(projection)) {
|
||||
this.scatterPlot.update();
|
||||
} */
|
||||
}
|
||||
|
||||
this.scatterPlot.recreateScene();
|
||||
this.scatterPlot.setCameraDefForNextCameraCreation(null);
|
||||
@ -442,6 +440,7 @@ export class Projector extends ProjectorPolymer implements SelectionContext,
|
||||
|
||||
state.selectedProjection = this.selectedProjection;
|
||||
state.is3d = this.projectionsPanel.is3d;
|
||||
state.tSNEIteration = this.dataSet.tSNEIteration;
|
||||
if (this.selectedProjection === 'pca') {
|
||||
state.componentDimensions =
|
||||
this.projectionsPanel.getPCAComponentUIValues();
|
||||
@ -466,6 +465,7 @@ export class Projector extends ProjectorPolymer implements SelectionContext,
|
||||
if (state.selectedProjection === 'tsne') {
|
||||
this.dataSet.hasTSNERun = true;
|
||||
}
|
||||
this.dataSet.tSNEIteration = state.tSNEIteration;
|
||||
|
||||
this.projectionsPanel.disablePolymerChangesTriggerReprojection();
|
||||
this.projectionsPanel.is3d = state.is3d;
|
||||
|
Loading…
Reference in New Issue
Block a user