Skip to content

Commit f4b9e43

Browse files
authored
Merge pull request #6625 from lvlte/fix-contour-colorscale-6623
Fix contour plot colorscale domain
2 parents 2effef5 + aea78dd commit f4b9e43

28 files changed

+107
-15
lines changed

draftlogs/6625_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix contour plot colorscale domain (take account of [zmin, zmax] and [cmin, cmax]) [[#6625](https://github.com/plotly/plotly.js/pull/6625)], with thanks to @lvlte for the contribution!

src/components/colorbar/draw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ function drawColorBar(g, opts, gd) {
512512
.data(fillLevels);
513513
fills.enter().append('rect')
514514
.classed(cn.cbfill, true)
515-
.style('stroke', 'none');
515+
.attr('style', '');
516516
fills.exit().remove();
517517

518518
var zBounds = zrange

src/traces/contour/make_color_map.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ module.exports = function makeColorMap(trace) {
2929

3030
var si, i;
3131

32-
if(contours.coloring === 'heatmap') {
33-
var zmin0 = cOpts.min;
34-
var zmax0 = cOpts.max;
32+
var zmin0 = cOpts.min;
33+
var zmax0 = cOpts.max;
3534

35+
if(contours.coloring === 'heatmap') {
3636
for(i = 0; i < len; i++) {
3737
si = scl[i];
3838
domain[i] = si[0] * (zmax0 - zmin0) + zmin0;
@@ -60,11 +60,37 @@ module.exports = function makeColorMap(trace) {
6060
range.push(range[range.length - 1]);
6161
}
6262
} else {
63+
var zRangeInput = trace._input && (
64+
typeof trace._input.zmin === 'number' && typeof trace._input.zmax === 'number'
65+
);
66+
67+
// If zmin/zmax are explicitly set, consider case where user specifies a
68+
// narrower z range than that of the contours start/end.
69+
if(zRangeInput && (start <= zmin0 || end >= zmax0)) {
70+
if(start <= zmin0) start = zmin0;
71+
if(end >= zmax0) end = zmax0;
72+
nc = Math.floor((end - start) / cs) + 1;
73+
extra = 0;
74+
}
75+
6376
for(i = 0; i < len; i++) {
6477
si = scl[i];
6578
domain[i] = (si[0] * (nc + extra - 1) - (extra / 2)) * cs + start;
6679
range[i] = si[1];
6780
}
81+
82+
// Make the colorscale fit the z range except if contours are explicitly
83+
// set BUT NOT zmin/zmax.
84+
if(zRangeInput || trace.autocontour) {
85+
if(domain[0] > zmin0) {
86+
domain.unshift(zmin0);
87+
range.unshift(range[0]);
88+
}
89+
if(domain[domain.length - 1] < zmax0) {
90+
domain.push(zmax0);
91+
range.push(range[range.length - 1]);
92+
}
93+
}
6894
}
6995

7096
return Colorscale.makeColorScaleFunc(

test/image/baselines/25.png

-321 Bytes
Loading

test/image/baselines/airfoil.png

-1.24 KB
Loading
-6.29 KB
Loading
-6.29 KB
Loading
56 Bytes
Loading
Loading
-1.91 KB
Loading
43 Bytes
Loading
Loading
316 Bytes
Loading
-447 Bytes
Loading
683 Bytes
Loading
25 Bytes
Loading
275 Bytes
Loading
-50 Bytes
Loading
-1.11 KB
Loading
Loading
1.15 KB
Loading
Loading
571 Bytes
Loading
Loading
-498 Bytes
Loading
931 Bytes
Loading

test/jasmine/tests/colorbar_test.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -529,19 +529,19 @@ describe('Test colorbar:', function() {
529529
return attrs;
530530
}
531531

532-
var z = [[1, 10], [100, 1000]];
532+
var mock = require('../../image/mocks/contour_transposed');
533+
var z = mock.data[0].z;
533534

534535
var expectedAttrs;
535536
var actualAttrs;
536537

537-
Plotly.newPlot(gd, [{type: 'contour', z: z}])
538+
Plotly.newPlot(gd, mock)
538539
.then(function() {
539540
expectedAttrs = getCBFillAttributes();
540-
541-
return Plotly.newPlot(gd, [{type: 'heatmap', z: z}])
542-
.then(function() {
543-
return Plotly.react(gd, [{type: 'contour', z: z}]);
544-
});
541+
return Plotly.newPlot(gd, [{type: 'heatmap', z: z}]);
542+
})
543+
.then(function() {
544+
return Plotly.react(gd, mock);
545545
})
546546
.then(function() {
547547
actualAttrs = getCBFillAttributes();

test/jasmine/tests/contour_test.js

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,22 @@ describe('contour defaults', function() {
120120
describe('contour makeColorMap', function() {
121121
'use strict';
122122

123-
it('should make correct color map function (\'fill\' coloring case)', function() {
123+
function _makeColorMap(trace) {
124+
trace.type = 'contour';
125+
if(trace.z === undefined) {
126+
trace.z = [[0]]; // dummy data for calc to work properly
127+
}
128+
var gd = { data: [trace] };
129+
supplyAllDefaults(gd);
130+
131+
var fullTrace = gd._fullData[0];
132+
fullTrace._extremes = {};
133+
Contour.calc(gd, fullTrace);
134+
135+
return makeColorMap(fullTrace);
136+
}
137+
138+
it('should make correct color map function (\'fill\' coloring case 1)', function() {
124139
var trace = {
125140
contours: {
126141
coloring: 'fill',
@@ -141,7 +156,7 @@ describe('contour makeColorMap', function() {
141156
]]
142157
};
143158

144-
var colorMap = makeColorMap(trace);
159+
var colorMap = _makeColorMap(trace);
145160

146161
expect(colorMap.domain()).toEqual(
147162
[-1.75, -0.75, 0.25, 1.25, 2.25]
@@ -151,6 +166,56 @@ describe('contour makeColorMap', function() {
151166
'rgb(12,51,131)', 'rgb(10,136,186)', 'rgb(242,211,56)',
152167
'rgb(242,143,56)', 'rgb(217,30,30)'
153168
]);
169+
170+
// Set lower/upper bounds of the color domain via zmin/zmax
171+
trace.zmin = -5;
172+
trace.zmax = 5;
173+
174+
colorMap = _makeColorMap(trace);
175+
176+
expect(colorMap.domain()).toEqual(
177+
[-5, -1.75, -0.75, 0.25, 1.25, 2.25, 5]
178+
);
179+
180+
expect(colorMap.range()).toEqual([
181+
'rgb(12,51,131)', 'rgb(12,51,131)', 'rgb(10,136,186)', 'rgb(242,211,56)',
182+
'rgb(242,143,56)', 'rgb(217,30,30)', 'rgb(217,30,30)'
183+
]);
184+
});
185+
186+
it('should make correct color map function (\'fill\' coloring case 2)', function() {
187+
var trace = {
188+
z: [[0, 1]],
189+
autocontour: true,
190+
contours: {
191+
coloring: 'fill'
192+
},
193+
colorscale: colorScales.RdBu,
194+
};
195+
196+
var colorMap = _makeColorMap(trace);
197+
var domain = colorMap.domain();
198+
var range = colorMap.range();
199+
200+
expect(domain[0]).toBe(0);
201+
expect(domain[domain.length - 1]).toBe(1);
202+
203+
expect(range[0]).toBe('rgb(5,10,172)');
204+
expect(range[range.length - 1]).toBe('rgb(178,10,28)');
205+
206+
// Set lower/upper bounds of the color domain via zmin/zmax
207+
trace.zmin = -1;
208+
trace.zmax = 2;
209+
210+
colorMap = _makeColorMap(trace);
211+
domain = colorMap.domain();
212+
range = colorMap.range();
213+
214+
expect(domain[0]).toBe(trace.zmin);
215+
expect(domain[domain.length - 1]).toBe(trace.zmax);
216+
217+
expect(range[0]).toBe('rgb(5,10,172)');
218+
expect(range[range.length - 1]).toBe('rgb(178,10,28)');
154219
});
155220

156221
it('should make correct color map function (\'heatmap\' coloring case)', function() {
@@ -166,7 +231,7 @@ describe('contour makeColorMap', function() {
166231
zmax: 6
167232
};
168233

169-
var colorMap = makeColorMap(trace);
234+
var colorMap = _makeColorMap(trace);
170235

171236
expect(colorMap.domain()).toEqual(
172237
[1, 2.75, 3.5, 4, 4.5, 6]
@@ -189,7 +254,7 @@ describe('contour makeColorMap', function() {
189254
colorscale: colorScales.RdBu
190255
};
191256

192-
var colorMap = makeColorMap(trace);
257+
var colorMap = _makeColorMap(trace);
193258

194259
expect(colorMap.domain()).toEqual(
195260
[1.5, 2.9, 3.5, 3.9, 4.3, 5.5]

0 commit comments

Comments
 (0)