Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit aa6d3b6

Browse files
committedApr 20, 2023
Move supervise by to projection panel
initialize input fix lint bookmark
1 parent 4f0cd50 commit aa6d3b6

File tree

6 files changed

+134
-144
lines changed

6 files changed

+134
-144
lines changed
 

‎tensorboard/plugins/projector/vz_projector/data.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,9 @@ export class State {
673673
tSNEIteration: number = 0;
674674
tSNEPerplexity: number = 0;
675675
tSNELearningRate: number = 0;
676+
tSNESuperviseFactor: number = 0;
677+
tSNESuperviseInput: string;
678+
tSNESuperviseColumn: string;
676679
tSNEis3d: boolean = true;
677680
/** UMAP parameters */
678681
umapIs3d: boolean = true;

‎tensorboard/plugins/projector/vz_projector/vz-projector-data-panel.html.ts

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ export const template = html`
122122
}
123123
124124
.metadata-editor,
125-
.supervise-settings,
126125
.colorlabel-container {
127126
display: flex;
128127
}
@@ -140,15 +139,6 @@ export const template = html`
140139
display: none;
141140
}
142141
143-
.supervise-settings paper-dropdown-menu {
144-
width: 100px;
145-
margin-right: 10px;
146-
}
147-
148-
.supervise-settings paper-input {
149-
width: calc(100% - 110px);
150-
}
151-
152142
.metadata-editor paper-dropdown-menu {
153143
width: 100px;
154144
margin-right: 10px;
@@ -354,31 +344,6 @@ export const template = html`
354344
</template>
355345
</div>
356346
<template is="dom-if" if="[[_hasChoice(labelOptions)]]">
357-
<!-- Supervise by -->
358-
<div hidden$="[[!showSuperviseSettings]]" class="supervise-settings">
359-
<paper-dropdown-menu no-animations label="Supervise with">
360-
<paper-listbox
361-
attr-for-selected="value"
362-
class="dropdown-content"
363-
on-selected-item-changed="superviseColumnChanged"
364-
selected="{{superviseColumn}}"
365-
slot="dropdown-content"
366-
>
367-
<template is="dom-repeat" items="[[metadataFields]]">
368-
<paper-item value="[[item]]" label="[[item]]">
369-
[[item]]
370-
</paper-item>
371-
</template>
372-
</paper-listbox>
373-
</paper-dropdown-menu>
374-
<paper-input
375-
value="{{superviseInput}}"
376-
label="{{superviseInputLabel}}"
377-
on-change="superviseInputChange"
378-
on-input="superviseInputTyping"
379-
>
380-
</paper-input>
381-
</div>
382347
<!-- Edit by -->
383348
<div class="metadata-editor">
384349
<paper-dropdown-menu no-animations label="Edit by">

‎tensorboard/plugins/projector/vz_projector/vz-projector-data-panel.ts

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,7 @@ import {PolymerElement} from '@polymer/polymer';
1717
import '../../../components/polymer/irons_and_papers';
1818
import {LegacyElementMixin} from '../../../components/polymer/legacy_element_mixin';
1919
import * as d3 from '../../../webapp/third_party/d3';
20-
import {
21-
ColorOption,
22-
ColumnStats,
23-
Projection,
24-
SpriteAndMetadataInfo,
25-
} from './data';
20+
import {ColorOption, ColumnStats, SpriteAndMetadataInfo} from './data';
2621
import {
2722
DataProvider,
2823
EmbeddingInfo,
@@ -63,22 +58,13 @@ class DataPanel extends LegacyElementMixin(PolymerElement) {
6358
metadataEditorColumn: string;
6459
@property({type: Boolean})
6560
metadataEditorButtonDisabled: boolean;
66-
@property({type: String})
67-
superviseInput: string;
68-
@property({type: String})
69-
superviseInputLabel: string = 'Ignored label';
70-
@property({type: String})
71-
superviseColumn: string;
72-
@property({type: Boolean})
73-
showSuperviseSettings: boolean = false;
7461

7562
@property({type: String})
7663
readonly _wordDelimiter = '[/=_,-]';
7764

7865
private labelOptions: string[];
7966
private colorOptions: ColorOption[];
8067
forceCategoricalColoring: boolean = false;
81-
private superviseInputSelected: string;
8268
private selectedPointIndices: number[];
8369
private neighborsOfFirstPoint: knn.NearestEntry[];
8470
private dataProvider: DataProvider;
@@ -97,7 +83,6 @@ class DataPanel extends LegacyElementMixin(PolymerElement) {
9783
ready() {
9884
super.ready();
9985
this.normalizeData = true;
100-
this.superviseInputSelected = '';
10186
}
10287
initialize(projector: any, dp: DataProvider) {
10388
this.projector = projector;
@@ -180,27 +165,6 @@ class DataPanel extends LegacyElementMixin(PolymerElement) {
180165
// Make the default label the first non-numeric column.
181166
this.metadataEditorColumn = this.metadataFields[Math.max(0, labelIndex)];
182167
}
183-
if (
184-
this.superviseColumn == null ||
185-
this.metadataFields.filter((name) => name === this.superviseColumn)
186-
.length === 0
187-
) {
188-
// Make the default supervise class the first non-numeric column.
189-
this.superviseColumn = this.metadataFields[Math.max(0, labelIndex)];
190-
this.superviseInput = '';
191-
}
192-
this.superviseInputChange();
193-
}
194-
projectionChanged(projection: Projection) {
195-
if (projection) {
196-
switch (projection.projectionType) {
197-
case 'tsne':
198-
this.set('showSuperviseSettings', true);
199-
break;
200-
default:
201-
this.set('showSuperviseSettings', false);
202-
}
203-
}
204168
}
205169
onProjectorSelectionChanged(
206170
selectedPointIndices: number[],
@@ -381,59 +345,6 @@ class DataPanel extends LegacyElementMixin(PolymerElement) {
381345
anyDownloadMetadataLink.click();
382346
}
383347
}
384-
private superviseInputTyping() {
385-
let value = this.superviseInput.trim();
386-
if (value == null || value.trim() === '') {
387-
if (this.superviseInputSelected === '') {
388-
this.superviseInputLabel = 'No ignored label';
389-
} else {
390-
this.superviseInputLabel = `Supervising without '${this.superviseInputSelected}'`;
391-
}
392-
return;
393-
}
394-
if (this.projector && this.projector.dataSet) {
395-
let numMatches = this.projector.dataSet.points.filter(
396-
(p) => p.metadata[this.superviseColumn].toString().trim() === value
397-
).length;
398-
if (numMatches === 0) {
399-
this.superviseInputLabel = 'Label not found';
400-
} else {
401-
if (this.projector.dataSet.superviseInput != value) {
402-
this.superviseInputLabel = `Supervise without '${value}' [${numMatches} points]`;
403-
}
404-
}
405-
}
406-
}
407-
private superviseInputChange() {
408-
let value = this.superviseInput.trim();
409-
if (value == null || value.trim() === '') {
410-
this.superviseInputSelected = '';
411-
this.superviseInputLabel = 'No ignored label';
412-
this.setSupervision(this.superviseColumn, '');
413-
return;
414-
}
415-
if (this.projector && this.projector.dataSet) {
416-
let numMatches = this.projector.dataSet.points.filter(
417-
(p) => p.metadata[this.superviseColumn].toString().trim() === value
418-
).length;
419-
if (numMatches === 0) {
420-
this.superviseInputLabel = `Supervising without '${this.superviseInputSelected}'`;
421-
} else {
422-
this.superviseInputSelected = value;
423-
this.superviseInputLabel = `Supervising without '${value}' [${numMatches} points]`;
424-
this.setSupervision(this.superviseColumn, value);
425-
}
426-
}
427-
}
428-
private superviseColumnChanged() {
429-
this.superviseInput = '';
430-
this.superviseInputChange();
431-
}
432-
private setSupervision(superviseColumn: string, superviseInput: string) {
433-
if (this.projector && this.projector.dataSet) {
434-
this.projector.dataSet.setSupervision(superviseColumn, superviseInput);
435-
}
436-
}
437348
setNormalizeData(normalizeData: boolean) {
438349
this.normalizeData = normalizeData;
439350
}

‎tensorboard/plugins/projector/vz_projector/vz-projector-projections-panel.html.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,19 @@ export const template = html`
8787
margin-bottom: -8px;
8888
}
8989
90+
.supervise-settings {
91+
display: flex;
92+
}
93+
94+
.supervise-settings paper-dropdown-menu {
95+
width: 100px;
96+
margin-right: 10px;
97+
}
98+
99+
.supervise-settings paper-input {
100+
width: calc(100% - 110px);
101+
}
102+
90103
#z-container {
91104
display: flex;
92105
align-items: center;
@@ -351,6 +364,31 @@ export const template = html`
351364
</paper-slider>
352365
<span></span>
353366
</div>
367+
<!-- Supervise by -->
368+
<div class="supervise-settings">
369+
<paper-dropdown-menu no-animations label="Supervise with">
370+
<paper-listbox
371+
attr-for-selected="value"
372+
class="dropdown-content"
373+
on-selected-item-changed="superviseColumnChanged"
374+
selected="{{superviseColumn}}"
375+
slot="dropdown-content"
376+
>
377+
<template is="dom-repeat" items="[[metadataFields]]">
378+
<paper-item value="[[item]]" label="[[item]]">
379+
[[item]]
380+
</paper-item>
381+
</template>
382+
</paper-listbox>
383+
</paper-dropdown-menu>
384+
<paper-input
385+
value="{{superviseInput}}"
386+
label="{{superviseInputLabel}}"
387+
on-change="superviseInputChange"
388+
on-input="superviseInputTyping"
389+
>
390+
</paper-input>
391+
</div>
354392
<p>
355393
<button class="run-tsne ink-button" title="Re-run t-SNE">
356394
Run

‎tensorboard/plugins/projector/vz_projector/vz-projector-projections-panel.ts

Lines changed: 92 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
8282
// Custom projection.
8383
@property({type: String})
8484
customSelectedSearchByMetadataOption: string;
85+
@property({type: String})
86+
superviseInput: string;
87+
@property({type: String})
88+
superviseInputLabel: string = 'Ignored label';
89+
@property({type: String})
90+
superviseColumn: string;
91+
@property({type: Boolean})
92+
showSuperviseSettings: boolean = false;
8593

8694
private projector: any; // Projector; type omitted b/c LegacyElement
8795

@@ -109,6 +117,8 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
109117
private perplexitySlider: HTMLInputElement;
110118
private learningRateInput: HTMLInputElement;
111119
private superviseFactorInput: HTMLInputElement;
120+
private superviseInputSelected: string;
121+
private metadataFields: string[];
112122
private zDropdown: HTMLElement;
113123
private iterationLabelTsne: HTMLElement;
114124
private runUmapButton: HTMLButtonElement;
@@ -144,6 +154,7 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
144154
) as HTMLInputElement;
145155
this.iterationLabelTsne = this.$$('.run-tsne-iter') as HTMLElement;
146156
this.runUmapButton = this.$$('#run-umap') as HTMLButtonElement;
157+
this.superviseInputSelected = '';
147158
}
148159
disablePolymerChangesTriggerReprojection() {
149160
this.polymerChangesTriggerReprojection = false;
@@ -258,6 +269,9 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
258269
if (this.learningRateInput) {
259270
this.learningRateInput.value = bookmark.tSNELearningRate.toString();
260271
}
272+
this.superviseFactor = bookmark.tSNESuperviseFactor;
273+
this.superviseColumn = bookmark.tSNESuperviseColumn;
274+
this.superviseInput = bookmark.tSNESuperviseInput || '';
261275
this.tSNEis3d = bookmark.tSNEis3d;
262276
// UMAP
263277
this.umapIs3d = bookmark.umapIs3d;
@@ -293,6 +307,9 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
293307
this.setZDropdownEnabled(this.pcaIs3d);
294308
this.updateTSNEPerplexityFromSliderChange();
295309
this.updateTSNELearningRateFromUIChange();
310+
this.updateTSNESuperviseFactorFromUIChange();
311+
this.setSupervision(this.superviseInput, this.superviseColumn);
312+
this.superviseInputChange();
296313
if (this.iterationLabelTsne) {
297314
this.iterationLabelTsne.innerText = bookmark.tSNEIteration.toString();
298315
}
@@ -315,6 +332,9 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
315332
if (this.learningRateInput != null) {
316333
bookmark.tSNELearningRate = +this.learningRateInput.value;
317334
}
335+
bookmark.tSNESuperviseFactor = this.superviseFactor;
336+
bookmark.tSNESuperviseInput = this.superviseInput;
337+
bookmark.tSNESuperviseColumn = this.superviseColumn;
318338
bookmark.tSNEis3d = this.tSNEis3d;
319339
// UMAP
320340
bookmark.umapIs3d = this.umapIs3d;
@@ -401,6 +421,25 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
401421
})!;
402422
this.customSelectedSearchByMetadataOption =
403423
this.searchByMetadataOptions[Math.max(0, searchByMetadataIndex)];
424+
let labelIndex = -1;
425+
if (spriteAndMetadata.stats) {
426+
this.metadataFields = spriteAndMetadata.stats.map((stats, i) => {
427+
if (!stats.isNumeric && labelIndex === -1) {
428+
labelIndex = i;
429+
}
430+
return stats.name;
431+
});
432+
}
433+
if (
434+
this.superviseColumn == null ||
435+
this.metadataFields.filter((name) => name === this.superviseColumn)
436+
.length === 0
437+
) {
438+
// Make the default supervise class the first non-numeric column.
439+
this.superviseColumn = this.metadataFields[Math.max(0, labelIndex)];
440+
this.superviseInput = '';
441+
}
442+
this.superviseInputChange();
404443
}
405444
public showTab(id: ProjectionType) {
406445
this.currentProjection = id;
@@ -455,6 +494,59 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
455494
this.reprojectCustom();
456495
}
457496
}
497+
private superviseInputTyping() {
498+
let value = this.superviseInput.trim();
499+
if (value == null || value.trim() === '') {
500+
if (this.superviseInputSelected === '') {
501+
this.superviseInputLabel = 'No ignored label';
502+
} else {
503+
this.superviseInputLabel = `Supervising without '${this.superviseInputSelected}'`;
504+
}
505+
return;
506+
}
507+
if (this.projector && this.projector.dataSet) {
508+
let numMatches = this.projector.dataSet.points.filter(
509+
(p) => p.metadata[this.superviseColumn].toString().trim() === value
510+
).length;
511+
if (numMatches === 0) {
512+
this.superviseInputLabel = 'Label not found';
513+
} else {
514+
if (this.projector.dataSet.superviseInput != value) {
515+
this.superviseInputLabel = `Supervise without '${value}' [${numMatches} points]`;
516+
}
517+
}
518+
}
519+
}
520+
private superviseInputChange() {
521+
let value = this.superviseInput.trim();
522+
if (value == null || value.trim() === '') {
523+
this.superviseInputSelected = '';
524+
this.superviseInputLabel = 'No ignored label';
525+
this.setSupervision(this.superviseColumn, '');
526+
return;
527+
}
528+
if (this.projector && this.projector.dataSet) {
529+
let numMatches = this.projector.dataSet.points.filter(
530+
(p) => p.metadata[this.superviseColumn].toString().trim() === value
531+
).length;
532+
if (numMatches === 0) {
533+
this.superviseInputLabel = `Supervising without '${this.superviseInputSelected}'`;
534+
} else {
535+
this.superviseInputSelected = value;
536+
this.superviseInputLabel = `Supervising without '${value}' [${numMatches} points]`;
537+
this.setSupervision(this.superviseColumn, value);
538+
}
539+
}
540+
}
541+
private superviseColumnChanged() {
542+
this.superviseInput = '';
543+
this.superviseInputChange();
544+
}
545+
private setSupervision(superviseColumn: string, superviseInput: string) {
546+
if (this.projector && this.projector.dataSet) {
547+
this.projector.dataSet.setSupervision(superviseColumn, superviseInput);
548+
}
549+
}
458550
private showTSNE() {
459551
const dataSet = this.dataSet;
460552
if (dataSet == null) {
@@ -480,7 +572,6 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
480572
}
481573
}
482574
private runTSNE() {
483-
let projectionChangeNotified = false;
484575
this.runTsneButton.innerText = 'Stop';
485576
this.runTsneButton.disabled = true;
486577
this.pauseTsneButton.innerText = 'Pause';
@@ -496,17 +587,12 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
496587
this.pauseTsneButton.disabled = false;
497588
this.iterationLabelTsne.innerText = '' + iteration;
498589
this.projector.notifyProjectionPositionsUpdated();
499-
if (!projectionChangeNotified && this.dataSet.projections['tsne']) {
500-
this.projector.onProjectionChanged();
501-
projectionChangeNotified = true;
502-
}
503590
} else {
504591
this.runTsneButton.innerText = 'Re-run';
505592
this.runTsneButton.disabled = false;
506593
this.pauseTsneButton.innerText = 'Pause';
507594
this.pauseTsneButton.disabled = true;
508595
this.perturbTsneButton.disabled = true;
509-
this.projector.onProjectionChanged();
510596
}
511597
}
512598
);
@@ -536,22 +622,16 @@ class ProjectionsPanel extends LegacyElementMixin(PolymerElement) {
536622
}
537623
}
538624
private runUmap() {
539-
let projectionChangeNotified = false;
540625
this.runUmapButton.disabled = true;
541626
const nComponents = this.umapIs3d ? 3 : 2;
542627
const nNeighbors = this.umapNeighbors;
543628
this.dataSet.projectUmap(nComponents, nNeighbors, (iteration: number) => {
544629
if (iteration != null) {
545630
this.runUmapButton.disabled = false;
546631
this.projector.notifyProjectionPositionsUpdated();
547-
if (!projectionChangeNotified && this.dataSet.projections['umap']) {
548-
this.projector.onProjectionChanged();
549-
projectionChangeNotified = true;
550-
}
551632
} else {
552633
this.runUmapButton.innerText = 'Re-run';
553634
this.runUmapButton.disabled = false;
554-
this.projector.onProjectionChanged();
555635
}
556636
});
557637
}

‎tensorboard/plugins/projector/vz_projector/vz-projector.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -567,9 +567,6 @@ class Projector
567567
this.registerHoverListener((hoverIndex: number) =>
568568
this.onHover(hoverIndex)
569569
);
570-
this.registerProjectionChangedListener((projection: Projection) =>
571-
this.onProjectionChanged(projection)
572-
);
573570
this.registerSelectionChangedListener(
574571
(
575572
selectedPointIndices: number[],
@@ -614,9 +611,6 @@ class Projector
614611
this.statusBar.style.display = 'none';
615612
}
616613
}
617-
onProjectionChanged(projection?: Projection) {
618-
this.dataPanel.projectionChanged(projection);
619-
}
620614
setProjection(projection: Projection | null) {
621615
this.projection = projection;
622616
if (projection != null) {
@@ -683,7 +677,6 @@ class Projector
683677
if (state.shuffledDataIndices) {
684678
this.dataSet.shuffledDataIndices = state.shuffledDataIndices;
685679
}
686-
this.dataSet.hasTSNERun = state.selectedProjection === 'tsne';
687680
this.dataSet.tSNEIteration = state.tSNEIteration;
688681
this.projectionsPanel.restoreUIFromBookmark(state);
689682
this.inspectorPanel.restoreUIFromBookmark(state);

0 commit comments

Comments
 (0)
Please sign in to comment.