Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 29bc81e

Browse filesBrowse files
committed
remove cached trace._interpz from heatmaps/contour maps with gaps
it turned out to be more trouble to properly invalidate this cache than it was worth - especially for edge cases like removing a previously filled-in value.
1 parent 28aed69 commit 29bc81e
Copy full SHA for 29bc81e

File tree

5 files changed

+97
-23
lines changed
Filter options

5 files changed

+97
-23
lines changed

‎src/traces/contourcarpet/calc.js

Copy file name to clipboardExpand all lines: src/traces/contourcarpet/calc.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ function heatmappishCalc(gd, trace) {
8484
z = trace._z = clean2dArray(trace._z || trace.z, trace.transpose);
8585

8686
trace._emptypoints = findEmpties(z);
87-
trace._interpz = interp2d(z, trace._emptypoints, trace._interpz);
87+
interp2d(z, trace._emptypoints);
8888

8989
// create arrays of brick boundaries, to be used by autorange and heatmap.plot
9090
var xlen = maxRowLength(z),

‎src/traces/heatmap/calc.js

Copy file name to clipboardExpand all lines: src/traces/heatmap/calc.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ module.exports = function calc(gd, trace) {
7777

7878
if(isContour || trace.connectgaps) {
7979
trace._emptypoints = findEmpties(z);
80-
trace._interpz = interp2d(z, trace._emptypoints, trace._interpz);
80+
interp2d(z, trace._emptypoints);
8181
}
8282
}
8383

‎src/traces/heatmap/interp2d.js

Copy file name to clipboardExpand all lines: src/traces/heatmap/interp2d.js
+24-21Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,37 @@
1010

1111
var Lib = require('../../lib');
1212

13-
var INTERPTHRESHOLD = 1e-2,
14-
NEIGHBORSHIFTS = [[-1, 0], [1, 0], [0, -1], [0, 1]];
13+
var INTERPTHRESHOLD = 1e-2;
14+
var NEIGHBORSHIFTS = [[-1, 0], [1, 0], [0, -1], [0, 1]];
1515

1616
function correctionOvershoot(maxFractionalChange) {
1717
// start with less overshoot, until we know it's converging,
1818
// then ramp up the overshoot for faster convergence
1919
return 0.5 - 0.25 * Math.min(1, maxFractionalChange * 0.5);
2020
}
2121

22-
module.exports = function interp2d(z, emptyPoints, savedInterpZ) {
23-
// fill in any missing data in 2D array z using an iterative
24-
// poisson equation solver with zero-derivative BC at edges
25-
// amazingly, this just amounts to repeatedly averaging all the existing
26-
// nearest neighbors (at least if we don't take x/y scaling into account)
27-
var maxFractionalChange = 1,
28-
i,
29-
thisPt;
30-
31-
if(Array.isArray(savedInterpZ)) {
32-
for(i = 0; i < emptyPoints.length; i++) {
33-
thisPt = emptyPoints[i];
34-
z[thisPt[0]][thisPt[1]] = savedInterpZ[thisPt[0]][thisPt[1]];
35-
}
36-
}
37-
else {
38-
// one pass to fill in a starting value for all the empties
39-
iterateInterp2d(z, emptyPoints);
40-
}
22+
/*
23+
* interp2d: Fill in missing data from a 2D array using an iterative
24+
* poisson equation solver with zero-derivative BC at edges.
25+
* Amazingly, this just amounts to repeatedly averaging all the existing
26+
* nearest neighbors, at least if we don't take x/y scaling into account,
27+
* which is the right approach here where x and y may not even have the
28+
* same units.
29+
*
30+
* @param {array of arrays} z
31+
* The 2D array to fill in. Will be mutated here. Assumed to already be
32+
* cleaned, so all entries are numbers except gaps, which are `undefined`.
33+
* @param {array of arrays} emptyPoints
34+
* Each entry [i, j, neighborCount] for empty points z[i][j] and the number
35+
* of neighbors that are *not* missing. Assumed to be sorted from most to
36+
* least neighbors, as produced by heatmap/find_empties.
37+
*/
38+
module.exports = function interp2d(z, emptyPoints) {
39+
var maxFractionalChange = 1;
40+
var i;
41+
42+
// one pass to fill in a starting value for all the empties
43+
iterateInterp2d(z, emptyPoints);
4144

4245
// we're don't need to iterate lone empties - remove them
4346
for(i = 0; i < emptyPoints.length; i++) {

‎test/jasmine/tests/contour_test.js

Copy file name to clipboardExpand all lines: test/jasmine/tests/contour_test.js
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,4 +458,46 @@ describe('contour plotting and editing', function() {
458458
.catch(fail)
459459
.then(done);
460460
});
461+
462+
it('can change z values with gaps', function(done) {
463+
Plotly.newPlot(gd, [{
464+
type: 'contour',
465+
z: [[1, 2], [null, 4], [1, 2]]
466+
}])
467+
.then(function() {
468+
expect(gd.calcdata[0][0].z).toEqual([[1, 2], [2, 4], [1, 2]]);
469+
expect(gd.calcdata[0][0].zmask).toEqual([[1, 1], [0, 1], [1, 1]]);
470+
471+
return Plotly.react(gd, [{
472+
type: 'contour',
473+
z: [[6, 5], [8, 7], [null, 10]]
474+
}]);
475+
})
476+
.then(function() {
477+
expect(gd.calcdata[0][0].z).toEqual([[6, 5], [8, 7], [9, 10]]);
478+
expect(gd.calcdata[0][0].zmask).toEqual([[1, 1], [1, 1], [0, 1]]);
479+
480+
return Plotly.react(gd, [{
481+
type: 'contour',
482+
z: [[1, 2], [null, 4], [1, 2]]
483+
}]);
484+
})
485+
.then(function() {
486+
expect(gd.calcdata[0][0].z).toEqual([[1, 2], [2, 4], [1, 2]]);
487+
expect(gd.calcdata[0][0].zmask).toEqual([[1, 1], [0, 1], [1, 1]]);
488+
489+
return Plotly.react(gd, [{
490+
type: 'contour',
491+
// notice that this one is the same as the previous, except that
492+
// a previously present value was removed...
493+
z: [[1, 2], [null, 4], [1, null]]
494+
}]);
495+
})
496+
.then(function() {
497+
expect(gd.calcdata[0][0].z).toEqual([[1, 2], [2, 4], [1, 2.5]]);
498+
expect(gd.calcdata[0][0].zmask).toEqual([[1, 1], [0, 1], [1, 0]]);
499+
})
500+
.catch(fail)
501+
.then(done);
502+
});
461503
});

‎test/jasmine/tests/heatmap_test.js

Copy file name to clipboardExpand all lines: test/jasmine/tests/heatmap_test.js
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,35 @@ describe('heatmap plot', function() {
587587
.catch(failTest)
588588
.then(done);
589589
});
590+
591+
it('can change z values with connected gaps', function(done) {
592+
var gd = createGraphDiv();
593+
Plotly.newPlot(gd, [{
594+
type: 'heatmap', connectgaps: true,
595+
z: [[1, 2], [null, 4], [1, 2]]
596+
}])
597+
.then(function() {
598+
expect(gd.calcdata[0][0].z).toEqual([[1, 2], [2, 4], [1, 2]]);
599+
600+
return Plotly.react(gd, [{
601+
type: 'heatmap', connectgaps: true,
602+
z: [[6, 5], [8, 7], [null, 10]]
603+
}]);
604+
})
605+
.then(function() {
606+
expect(gd.calcdata[0][0].z).toEqual([[6, 5], [8, 7], [9, 10]]);
607+
608+
return Plotly.react(gd, [{
609+
type: 'heatmap', connectgaps: true,
610+
z: [[1, 2], [null, 4], [1, 2]]
611+
}]);
612+
})
613+
.then(function() {
614+
expect(gd.calcdata[0][0].z).toEqual([[1, 2], [2, 4], [1, 2]]);
615+
})
616+
.catch(fail)
617+
.then(done);
618+
});
590619
});
591620

592621
describe('heatmap hover', function() {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.