Skip to content

Commit

Permalink
histogram: make timeseries histogram visualization compatible with v3…
Browse files Browse the repository at this point in the history
… data format (tensorflow#5392)

* make timeseries histogram visualization compatible with v3 data format

* improve getBinContribution description (thanks nfelt@!)

* update test for edge case zero-width bin scenarios

* remove duplicate test case

* update doc

* improve test
  • Loading branch information
yatbear committed Mar 27, 2023
1 parent 2387a79 commit bebb831
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 58 deletions.
22 changes: 17 additions & 5 deletions tensorboard/webapp/widgets/histogram/histogram_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,21 @@ function rebuildBins(bins: Bin[], range: Range, binCount: number): Bin[] {
}

/**
* Computes how much of the input bin's 'y' counts should be allocated to a new
* range. For 0 width input bins, the allocation may be split in half across 2
* bins.
* Computes how much of the input bin's 'y' counts should be allocated to this output bin.
*
* Where both bins have non-zero width, this is computed by multiplying the input y value by
* the ratio of the width-wise overlap in the bins to the total width of the output bin.
* (This can be thought of redistributing the overlapping "area" of the bar in the input
* histogram across the full width of the output bin.)
*
* When the input bin has zero width (the output bin cannot have zero width by construction),
* we instead have to consider several cases depending on the open/closed-ness of the
* underlying intervals. If the zero width input bin has y value 0, the contribution is
* always 0. Otherwise, if zero width input bin has y value greater than 0, it must represent
* the closed interval [x, x]. In this case, it contributes the full value of y if and only
* if the output bin's interval contains x. This interval is the closed-open interval
* [resultLeft, resultRight), except if resultHasRightNeighbor is false, in which case it's
* the closed interval [resultLeft, resultRight].
*/
function getBinContribution(
bin: Bin,
Expand All @@ -165,8 +177,8 @@ function getBinContribution(
}

if (bin.dx === 0) {
if (resultHasRightNeighbor && binRight === resultRight) {
return {curr: 0.5 * bin.y, next: 0.5 * bin.y};
if (resultHasRightNeighbor && binRight >= resultRight) {
return {curr: 0, next: bin.y};
}
return {curr: bin.y, next: 0};
}
Expand Down
86 changes: 33 additions & 53 deletions tensorboard/webapp/widgets/histogram/histogram_util_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,45 +260,24 @@ describe('histogram util', () => {
]);
});

it('redistributes 0 width bin evenly over edges of result bins', () => {
it('redistributes bin counts where the last bin has zero width', () => {
expect(
histogramsToBins(
buildNormalizedHistograms(
[
binsToHistogram([
{x: 0, dx: 1, y: 0},
{x: 5, dx: 0, y: 200},
{x: 9, dx: 1, y: 0},
{x: 0, dx: 1, y: 10},
{x: 1, dx: 1, y: 10},
{x: 2, dx: 0, y: 10},
]),
],
2
)
)
).toEqual([
[
{x: 0, dx: 5, y: 100},
{x: 5, dx: 5, y: 100},
],
]);
});

it('redistributes 0 width bins at the edges', () => {
expect(
histogramsToBins(
buildNormalizedHistograms(
[
binsToHistogram([
{x: 0, dx: 0, y: 100},
{x: 10, dx: 0, y: 200},
]),
],
2
)
)
).toEqual([
[
{x: 0, dx: 5, y: 100},
{x: 5, dx: 5, y: 200},
{x: 0, dx: 1, y: 10},
{x: 1, dx: 1, y: 20},
],
]);
});
Expand Down Expand Up @@ -345,32 +324,6 @@ describe('histogram util', () => {
)
).toEqual([[{x: 0, dx: 10, y: 300}]]);
});

it(
'produces result bins with full and partial contributions from ' +
'multiple 0 width bins',
() => {
expect(
histogramsToBins(
buildNormalizedHistograms(
[
binsToHistogram([
{x: 0, dx: 1, y: 0},
{x: 5, dx: 0, y: 200},
{x: 10, dx: 0, y: 100},
]),
],
2
)
)
).toEqual([
[
{x: 0, dx: 5, y: 100},
{x: 5, dx: 5, y: 200},
],
]);
}
);
});

describe('multiple histograms', () => {
Expand Down Expand Up @@ -426,6 +379,33 @@ describe('histogram util', () => {
],
]);
});

it(
'produces result bins from multiple 0 width bins in different ' +
'steps',
() => {
expect(
histogramsToBins(
buildNormalizedHistograms(
[
binsToHistogram([{x: 0, dx: 0, y: 200}]),
binsToHistogram([{x: 1.0, dx: 0, y: 100}]),
],
2
)
)
).toEqual([
[
{x: 0, dx: 0.5, y: 200},
{x: 0.5, dx: 0.5, y: 0},
],
[
{x: 0, dx: 0.5, y: 0},
{x: 0.5, dx: 0.5, y: 100},
],
]);
}
);
});
});
});

0 comments on commit bebb831

Please sign in to comment.