Skip to content

Commit 63ca14e

Browse files
committed
Merge pull request #74 from plotly/scale-errorbars
Scale gl3d error bars
2 parents 7c33004 + cda8431 commit 63ca14e

File tree

6 files changed

+196
-72
lines changed

6 files changed

+196
-72
lines changed

src/traces/scatter3d/calc_errors.js

+59-57
Original file line numberDiff line numberDiff line change
@@ -9,95 +9,97 @@
99

1010
'use strict';
1111

12-
function calculateAxisErrors(data, params) {
13-
if(!params || !params.visible) {
14-
return null;
15-
}
12+
function calculateAxisErrors(data, params, scaleFactor) {
13+
if(!params || !params.visible) return null;
1614

1715
function option(name, value) {
18-
if(name in params) {
19-
return params[name];
20-
}
16+
if(name in params) return params[name];
2117
return value;
2218
}
2319

24-
var result = new Array(data.length);
25-
var type = option('type', 'percent');
26-
var symmetric = option('symmetric', true);
27-
var value = +option('value', 10);
28-
var minusValue = +option('valueminus', 10);
29-
var error = option('array', null);
30-
var minusError = option('arrayminus', null);
31-
var x, h, l, r, i;
20+
var result = new Array(data.length),
21+
type = option('type', 'percent'),
22+
symmetric = option('symmetric', true),
23+
value = +option('value', 10),
24+
minusValue = +option('valueminus', 10),
25+
error = option('array', null),
26+
minusError = option('arrayminus', null);
3227

3328
if(symmetric) {
3429
minusValue = value;
3530
minusError = error;
3631
}
3732

38-
if(type === 'data' && (!error || !minusError)) {
39-
return null;
40-
}
33+
if(type === 'data' && (!error || !minusError)) return null;
34+
35+
for(var i = 0; i < data.length; i++) {
36+
var x = +data[i];
4137

42-
for(i=0; i<data.length; ++i) {
43-
x = +data[i];
4438
switch(type) {
45-
case 'percent':
46-
h = Math.abs(x) * value / 100.0;
47-
l = Math.abs(x) * minusValue / 100.0;
48-
result[i] = [ -l, h ];
49-
break;
50-
51-
case 'constant':
52-
result[i] = [ -minusValue, value ];
53-
break;
54-
55-
case 'sqrt':
56-
r = Math.sqrt(Math.abs(x));
57-
result[i] = [ -r, r ];
58-
break;
59-
60-
case 'data':
61-
result[i] = [ (+minusError[i]) - x, (+error[i]) - x ];
62-
break;
39+
case 'percent':
40+
result[i] = [
41+
-Math.abs(x) * (minusValue / 100.0) * scaleFactor,
42+
Math.abs(x) * (value / 100.0) * scaleFactor
43+
];
44+
break;
45+
46+
case 'constant':
47+
result[i] = [
48+
-minusValue * scaleFactor,
49+
value * scaleFactor
50+
];
51+
break;
52+
53+
case 'sqrt':
54+
var r = Math.sqrt(Math.abs(x)) * scaleFactor;
55+
result[i] = [-r, r];
56+
break;
57+
58+
case 'data':
59+
result[i] = [
60+
-(+minusError[i]) * scaleFactor,
61+
(+error[i]) * scaleFactor
62+
];
63+
break;
6364
}
6465
}
6566

6667
return result;
6768
}
6869

6970
function dataLength(array) {
70-
for(var i=0; i<array.length; ++i) {
71-
if(array[i]) {
72-
return array[i].length;
73-
}
71+
for(var i = 0; i < array.length; i++) {
72+
if(array[i]) return array[i].length;
7473
}
7574
return 0;
7675
}
7776

78-
function calculateErrors(data) {
77+
function calculateErrors(data, scaleFactor) {
7978
var errors = [
80-
calculateAxisErrors(data.x, data.error_x),
81-
calculateAxisErrors(data.y, data.error_y),
82-
calculateAxisErrors(data.z, data.error_z) ],
83-
errorBounds,
84-
n = dataLength(errors),
85-
i, j, k, bound;
86-
if(n === 0) {
87-
return null;
88-
}
89-
errorBounds = new Array(n);
90-
for(i=0; i<n; ++i) {
91-
bound = [[0,0,0],[0,0,0]];
92-
for(j=0; j<3; ++j) {
79+
calculateAxisErrors(data.x, data.error_x, scaleFactor[0]),
80+
calculateAxisErrors(data.y, data.error_y, scaleFactor[1]),
81+
calculateAxisErrors(data.z, data.error_z, scaleFactor[2])
82+
];
83+
84+
var n = dataLength(errors);
85+
if(n === 0) return null;
86+
87+
var errorBounds = new Array(n);
88+
89+
for(var i = 0; i < n; i++) {
90+
var bound = [[0,0,0], [0,0,0]];
91+
92+
for(var j = 0; j < 3; j++) {
9393
if(errors[j]) {
94-
for(k=0; k<2; ++k) {
94+
for(var k = 0; k < 2; k++) {
9595
bound[k][j] = errors[j][i][k];
9696
}
9797
}
9898
}
99+
99100
errorBounds[i] = bound;
100101
}
102+
101103
return errorBounds;
102104
}
103105

src/traces/scatter3d/convert.js

+19-15
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,23 @@ function constructDelaunay(points, color, axis) {
106106

107107
function calculateErrorParams(errors) {
108108
/*jshint camelcase: false */
109-
var capSize = [0.0, 0.0, 0.0], i, e;
110-
var color = [[0,0,0],[0,0,0],[0,0,0]];
111-
var lineWidth = [0.0, 0.0, 0.0];
112-
for(i=0; i<3; ++i) {
113-
e = errors[i];
114-
if (e && e.copy_zstyle !== false) {
115-
e = errors[2];
116-
}
109+
110+
var capSize = [0.0, 0.0, 0.0],
111+
color = [[0,0,0], [0,0,0], [0,0,0]],
112+
lineWidth = [0.0, 0.0, 0.0];
113+
114+
for(var i = 0; i < 3; i++) {
115+
var e = errors[i];
116+
117+
if(e && e.copy_zstyle !== false) e = errors[2];
117118
if(!e) continue;
118-
capSize[i] = e.width / 100.0; //Ballpark rescaling, attempt to make consistent with plot.ly
119+
120+
capSize[i] = e.width / 2; // ballpark rescaling
119121
color[i] = str2RgbaArray(e.color);
120122
lineWidth = e.thickness;
121123

122124
}
125+
123126
return {capSize: capSize, color: color, lineWidth: lineWidth};
124127
}
125128

@@ -173,7 +176,6 @@ function convertPlotlyOptions(scene, data) {
173176
zaxis = sceneLayout.zaxis,
174177
marker = data.marker,
175178
line = data.line,
176-
errorParams = calculateErrorParams([ data.error_x, data.error_y, data.error_z ]),
177179
xc, x = data.x || [],
178180
yc, y = data.y || [],
179181
zc, z = data.z || [],
@@ -241,13 +243,15 @@ function convertPlotlyOptions(scene, data) {
241243
}
242244
}
243245

244-
params.errorBounds = calculateError(data);
245-
params.errorColor = errorParams.color;
246+
params.errorBounds = calculateError(data, scaleFactor);
247+
248+
var errorParams = calculateErrorParams([data.error_x, data.error_y, data.error_z]);
249+
params.errorColor = errorParams.color;
246250
params.errorLineWidth = errorParams.lineWidth;
247-
params.errorCapSize = errorParams.capSize;
251+
params.errorCapSize = errorParams.capSize;
248252

249-
params.delaunayAxis = data.surfaceaxis;
250-
params.delaunayColor = str2RgbaArray(data.surfacecolor);
253+
params.delaunayAxis = data.surfaceaxis;
254+
params.delaunayColor = str2RgbaArray(data.surfacecolor);
251255

252256
return params;
253257
}
16.2 KB
Loading
20.9 KB
Loading
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"data": [
3+
{
4+
"type": "scatter3d",
5+
"mode": "markers",
6+
"x": [
7+
1,
8+
2,
9+
3
10+
],
11+
"y": [
12+
1,
13+
2,
14+
3
15+
],
16+
"z": [
17+
2000,
18+
1000,
19+
2000
20+
],
21+
"error_z": {
22+
"array": [
23+
1000,
24+
500,
25+
1000
26+
],
27+
"arrayminus": [
28+
0,
29+
500,
30+
0
31+
],
32+
"color": "green",
33+
"thickness": 10
34+
},
35+
"error_x": {
36+
"type": "constant",
37+
"value": 0.1,
38+
"color": "black"
39+
},
40+
"marker": {
41+
"symbol": "square"
42+
},
43+
"uid": "0c6e64"
44+
}
45+
],
46+
"layout": {
47+
"scene": {
48+
"camera": {
49+
"eye": {
50+
"x": 0.2,
51+
"y": 3.5,
52+
"z": 0.4
53+
}
54+
},
55+
"aspectratio": {
56+
"x": 2,
57+
"y": 2,
58+
"z": 1
59+
}
60+
},
61+
"height": 450,
62+
"width": 1000,
63+
"autosize": true
64+
}
65+
}
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"data": [
3+
{
4+
"type": "scatter3d",
5+
"x": [
6+
1,
7+
2,
8+
3
9+
],
10+
"y": [
11+
1,
12+
2,
13+
3
14+
],
15+
"z": [
16+
200,
17+
100,
18+
200
19+
],
20+
"error_z": {
21+
"type": "percent",
22+
"value": 20,
23+
"color": "red",
24+
"width": 5
25+
},
26+
"error_y": {
27+
"type": "constant",
28+
"value": 0.25,
29+
"valueminus": 0.1
30+
},
31+
"uid": "a8f51d"
32+
}
33+
],
34+
"layout": {
35+
"scene": {
36+
"camera": {
37+
"eye": {
38+
"x": 3,
39+
"y": 0.2,
40+
"z": 0.2
41+
}
42+
},
43+
"aspectratio": {
44+
"x": 2,
45+
"y": 2,
46+
"z": 1
47+
}
48+
},
49+
"height": 450,
50+
"width": 1000,
51+
"autosize": true
52+
}
53+
}

0 commit comments

Comments
 (0)