diff --git a/src/components/colorscale/color_attributes.js b/src/components/colorscale/color_attributes.js index 0b22527a2f8..68c21984eac 100644 --- a/src/components/colorscale/color_attributes.js +++ b/src/components/colorscale/color_attributes.js @@ -10,6 +10,7 @@ var colorScaleAttributes = require('./attributes'); var extendDeep = require('../../lib/extend').extendDeep; +var palettes = require('./scales.js'); module.exports = function makeColorScaleAttributes(context) { return { @@ -19,7 +20,7 @@ module.exports = function makeColorScaleAttributes(context) { role: 'style', description: [ 'Sets the ', context, ' color. It accepts either a specific color', - ' or an array of values that are mapped to the colorscale', + ' or an array of numbers that are mapped to the colorscale', ' relative to the max and min values of the array or relative to', ' `cmin` and `cmax` if set.' ].join('') @@ -35,14 +36,19 @@ module.exports = function makeColorScaleAttributes(context) { ' values are required. For example,', ' `[[0, \'rgb(0,0,255)\', [1, \'rgb(255,0,0)\']]`.', ' To control the bounds of the colorscale in color space,', - ' use `', context, '.cmin` and `', context, '.cmax`.' - ].join('') + ' use `', context, '.cmin` and `', context, '.cmax`.', + ' Alternatively, `colorscale` may be a palette name string', + ' of the following list: ' + ].join('').concat(Object.keys(palettes).join(', ')) }), cauto: extendDeep({}, colorScaleAttributes.zauto, { description: [ - 'Has an effect only if `', context, '.color` is set to a numerical array.', - ' Determines the whether or not the color domain is computed', - ' automatically.' + 'Has an effect only if `', context, '.color` is set to a numerical array', + ' and `cmin`, `cmax` are set by the user. In this case,', + ' it controls whether the range of colors in `colorscale` is mapped to', + ' the range of values in the `color` array (`cauto: true`), or the `cmin`/`cmax`', + ' values (`cauto: false`).', + ' Defaults to `false` when `cmin`, `cmax` are set by the user.' ].join('') }), cmax: extendDeep({}, colorScaleAttributes.zmax, { @@ -64,14 +70,18 @@ module.exports = function makeColorScaleAttributes(context) { autocolorscale: extendDeep({}, colorScaleAttributes.autocolorscale, { description: [ 'Has an effect only if `', context, '.color` is set to a numerical array.', - ' Determines whether or not the colorscale is picked using', - ' values inside `', context, '.color`.' + ' Determines whether the colorscale is a default palette (`autocolorscale: true`)', + ' or the palette determined by `', context, '.colorscale`.', + ' In case `colorscale` is unspecified or `autocolorscale` is true, the default ', + ' palette will be chosen according to whether numbers in the `color` array are', + ' all positive, all negative or mixed.' ].join('') }), reversescale: extendDeep({}, colorScaleAttributes.reversescale, { description: [ 'Has an effect only if `', context, '.color` is set to a numerical array.', - ' Reverses the colorscale.' + ' Reverses the color mapping if true (`cmin` will correspond to the last color', + ' in the array and `cmax` will correspond to the first color).' ].join('') }) }; diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index c895bcc1c8b..371f834584e 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -1590,7 +1590,9 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { 'outsidetextfont.size', 'outsidetextfont.family', 'outsidetextfont.color', 'hole', 'scalegroup', 'domain', 'domain.x', 'domain.y', 'domain.x[0]', 'domain.x[1]', 'domain.y[0]', 'domain.y[1]', - 'tilt', 'tiltaxis', 'depth', 'direction', 'rotation', 'pull' + 'tilt', 'tiltaxis', 'depth', 'direction', 'rotation', 'pull', + 'line.showscale', 'line.cauto', 'line.autocolorscale', 'line.reversescale', + 'marker.line.showscale', 'marker.line.cauto', 'marker.line.autocolorscale', 'marker.line.reversescale' ]; for(i = 0; i < traces.length; i++) { if(Plots.traceIs(gd._fullData[traces[i]], 'box')) { @@ -1612,6 +1614,8 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { var replotAttrs = [ 'zmin', 'zmax', 'zauto', 'marker.cmin', 'marker.cmax', 'marker.cauto', + 'line.cmin', 'line.cmax', + 'marker.line.cmin', 'marker.line.cmax', 'contours.start', 'contours.end', 'contours.size', 'contours.showlines', 'line', 'line.smoothing', 'line.shape', diff --git a/src/traces/scatter/calc.js b/src/traces/scatter/calc.js index 21304864b93..3ac952cce2d 100644 --- a/src/traces/scatter/calc.js +++ b/src/traces/scatter/calc.js @@ -15,7 +15,7 @@ var Axes = require('../../plots/cartesian/axes'); var Lib = require('../../lib'); var subTypes = require('./subtypes'); -var calcMarkerColorscale = require('./marker_colorscale_calc'); +var calcColorscale = require('./colorscale_calc'); module.exports = function calc(gd, trace) { @@ -73,7 +73,7 @@ module.exports = function calc(gd, trace) { s.map(markerTrans) : markerTrans(s); } - calcMarkerColorscale(trace); + calcColorscale(trace); // TODO: text size diff --git a/src/traces/scatter/marker_colorscale_calc.js b/src/traces/scatter/colorscale_calc.js similarity index 57% rename from src/traces/scatter/marker_colorscale_calc.js rename to src/traces/scatter/colorscale_calc.js index d8db642d9fa..4aef0fe15e9 100644 --- a/src/traces/scatter/marker_colorscale_calc.js +++ b/src/traces/scatter/colorscale_calc.js @@ -17,16 +17,21 @@ var subTypes = require('./subtypes'); // common to 'scatter', 'scatter3d' and 'scattergeo' module.exports = function calcMarkerColorscale(trace) { - if(!subTypes.hasMarkers(trace)) return; - - var marker = trace.marker; // auto-z and autocolorscale if applicable - if(hasColorscale(trace, 'marker')) { - calcColorscale(trace, marker.color, 'marker', 'c'); + + if(subTypes.hasLines(trace) && hasColorscale(trace, 'line')) { + calcColorscale(trace, trace.line.color, 'line', 'c'); } - if(hasColorscale(trace, 'marker.line')) { - calcColorscale(trace, marker.line.color, 'marker.line', 'c'); + if(subTypes.hasMarkers(trace)) { + + if(hasColorscale(trace, 'marker')) { + calcColorscale(trace, trace.marker.color, 'marker', 'c'); + } + + if(hasColorscale(trace, 'marker.line')) { + calcColorscale(trace, trace.marker.line.color, 'marker.line', 'c'); + } } }; diff --git a/src/traces/scatter/defaults.js b/src/traces/scatter/defaults.js index 3690160053f..5b0df90a510 100644 --- a/src/traces/scatter/defaults.js +++ b/src/traces/scatter/defaults.js @@ -40,7 +40,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('mode', defaultMode); if(subTypes.hasLines(traceOut)) { - handleLineDefaults(traceIn, traceOut, defaultColor, coerce); + handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce); handleLineShapeDefaults(traceIn, traceOut, coerce); coerce('connectgaps'); } diff --git a/src/traces/scatter/line_defaults.js b/src/traces/scatter/line_defaults.js index 64f4104bd31..92aae25b149 100644 --- a/src/traces/scatter/line_defaults.js +++ b/src/traces/scatter/line_defaults.js @@ -9,14 +9,26 @@ 'use strict'; +var hasColorscale = require('../../components/colorscale/has_colorscale'); +var colorscaleDefaults = require('../../components/colorscale/defaults'); + // common to 'scatter', 'scatter3d', 'scattergeo' and 'scattergl' -module.exports = function lineDefaults(traceIn, traceOut, defaultColor, coerce) { +module.exports = function lineDefaults(traceIn, traceOut, defaultColor, layout, coerce) { + var markerColor = (traceIn.marker || {}).color; - // don't try to inherit a color array - coerce('line.color', (Array.isArray(markerColor) ? false : markerColor) || - defaultColor); + coerce('line.color', defaultColor); + if(hasColorscale(traceIn, 'line')) { + colorscaleDefaults( + traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'} + ); + } else { + coerce('line.color', (Array.isArray(markerColor) ? false : markerColor) || + defaultColor); + } + + coerce('line.width'); coerce('line.dash'); }; diff --git a/src/traces/scatter/marker_defaults.js b/src/traces/scatter/marker_defaults.js index 57b85dbeb1f..eaee453d6c0 100644 --- a/src/traces/scatter/marker_defaults.js +++ b/src/traces/scatter/marker_defaults.js @@ -19,7 +19,7 @@ var subTypes = require('./subtypes'); // common to 'scatter', 'scatter3d', 'scattergeo' and 'scattergl' module.exports = function markerDefaults(traceIn, traceOut, defaultColor, layout, coerce) { var isBubble = subTypes.isBubble(traceIn), - lineColor = (traceIn.line || {}).color, + lineColor = !Array.isArray(traceIn.line) ? (traceIn.line || {}).color : undefined, defaultMLC; if(lineColor) defaultColor = lineColor; diff --git a/src/traces/scatter3d/attributes.js b/src/traces/scatter3d/attributes.js index e60d02d9686..06b1cecc708 100644 --- a/src/traces/scatter3d/attributes.js +++ b/src/traces/scatter3d/attributes.js @@ -97,11 +97,21 @@ module.exports = { z: makeProjectionAttr('z') }, connectgaps: scatterAttrs.connectgaps, - line: { - color: scatterLineAttrs.color, + line: extendFlat({}, { width: scatterLineAttrs.width, - dash: scatterLineAttrs.dash + dash: scatterLineAttrs.dash, + showscale: { + valType: 'boolean', + role: 'info', + dflt: false, + description: [ + 'Has an effect only if `line.color` is set to a numerical array.', + 'Determines whether or not a colorbar is displayed.' + ].join(' ') + } }, + colorAttributes('line') + ), marker: extendFlat({}, { // Parity with scatter.js? symbol: { valType: 'enumerated', diff --git a/src/traces/scatter3d/calc.js b/src/traces/scatter3d/calc.js index b50ae40b221..2fee965f035 100644 --- a/src/traces/scatter3d/calc.js +++ b/src/traces/scatter3d/calc.js @@ -9,7 +9,7 @@ 'use strict'; var arraysToCalcdata = require('../scatter/arrays_to_calcdata'); -var calcMarkerColorscale = require('../scatter/marker_colorscale_calc'); +var calcColorscales = require('../scatter/colorscale_calc'); /** @@ -21,7 +21,7 @@ module.exports = function calc(gd, trace) { var cd = [{x: false, y: false, trace: trace, t: {}}]; arraysToCalcdata(cd); - calcMarkerColorscale(trace); + calcColorscales(trace); return cd; }; diff --git a/src/traces/scatter3d/convert.js b/src/traces/scatter3d/convert.js index 434850fb8ba..8715b3c962e 100644 --- a/src/traces/scatter3d/convert.js +++ b/src/traces/scatter3d/convert.js @@ -204,7 +204,7 @@ function convertPlotlyOptions(scene, data) { }; if('line' in data) { - params.lineColor = str2RgbaArray(line.color); + params.lineColor = formatColor(line, 1, len); params.lineWidth = line.width; params.lineDashes = line.dash; } diff --git a/src/traces/scatter3d/defaults.js b/src/traces/scatter3d/defaults.js index 46767aaf83a..9dcf04788f8 100644 --- a/src/traces/scatter3d/defaults.js +++ b/src/traces/scatter3d/defaults.js @@ -37,7 +37,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout if(subTypes.hasLines(traceOut)) { coerce('connectgaps'); - handleLineDefaults(traceIn, traceOut, defaultColor, coerce); + handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce); } if(subTypes.hasMarkers(traceOut)) { diff --git a/src/traces/scattergeo/calc.js b/src/traces/scattergeo/calc.js index 2cc53eca681..bb338a66f3b 100644 --- a/src/traces/scattergeo/calc.js +++ b/src/traces/scattergeo/calc.js @@ -9,13 +9,13 @@ 'use strict'; -var calcMarkerColorscale = require('../scatter/marker_colorscale_calc'); +var calcColorscale = require('../scatter/colorscale_calc'); module.exports = function calc(gd, trace) { var cd = [{x: false, y: false, trace: trace, t: {}}]; - calcMarkerColorscale(trace); + calcColorscale(trace); return cd; }; diff --git a/src/traces/scattergeo/defaults.js b/src/traces/scattergeo/defaults.js index beb6ded2c72..1990a000dcd 100644 --- a/src/traces/scattergeo/defaults.js +++ b/src/traces/scattergeo/defaults.js @@ -34,7 +34,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('mode'); if(subTypes.hasLines(traceOut)) { - handleLineDefaults(traceIn, traceOut, defaultColor, coerce); + handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce); } if(subTypes.hasMarkers(traceOut)) { diff --git a/src/traces/scattergl/defaults.js b/src/traces/scattergl/defaults.js index f7583d42d42..b1a8effb015 100644 --- a/src/traces/scattergl/defaults.js +++ b/src/traces/scattergl/defaults.js @@ -38,7 +38,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout if(subTypes.hasLines(traceOut)) { coerce('connectgaps'); - handleLineDefaults(traceIn, traceOut, defaultColor, coerce); + handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce); } if(subTypes.hasMarkers(traceOut)) { diff --git a/src/traces/scattermapbox/calc.js b/src/traces/scattermapbox/calc.js index 295b6ffec3e..a3c6f50df57 100644 --- a/src/traces/scattermapbox/calc.js +++ b/src/traces/scattermapbox/calc.js @@ -15,7 +15,7 @@ var Lib = require('../../lib'); var hasColorscale = require('../../components/colorscale/has_colorscale'); var makeColorScaleFn = require('../../components/colorscale/make_scale_function'); var subtypes = require('../scatter/subtypes'); -var calcMarkerColorscale = require('../scatter/marker_colorscale_calc'); +var calcMarkerColorscale = require('../scatter/colorscale_calc'); var makeBubbleSizeFn = require('../scatter/make_bubble_size_func'); diff --git a/src/traces/scatterternary/calc.js b/src/traces/scatterternary/calc.js index ae439af07a6..871c17a825c 100644 --- a/src/traces/scatterternary/calc.js +++ b/src/traces/scatterternary/calc.js @@ -15,7 +15,7 @@ var Axes = require('../../plots/cartesian/axes'); var Lib = require('../../lib'); var subTypes = require('../scatter/subtypes'); -var calcMarkerColorscale = require('../scatter/marker_colorscale_calc'); +var calcColorscale = require('../scatter/colorscale_calc'); var dataArrays = ['a', 'b', 'c']; var arraysToFill = {a: ['b', 'c'], b: ['a', 'c'], c: ['a', 'b']}; @@ -88,7 +88,7 @@ module.exports = function calc(gd, trace) { } } - calcMarkerColorscale(trace); + calcColorscale(trace); // this has migrated up from arraysToCalcdata as we have a reference to 's' here if(typeof s !== undefined) Lib.mergeArray(s, cd, 'ms'); diff --git a/src/traces/scatterternary/defaults.js b/src/traces/scatterternary/defaults.js index 169d922a958..d9e0ebd92cd 100644 --- a/src/traces/scatterternary/defaults.js +++ b/src/traces/scatterternary/defaults.js @@ -68,7 +68,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('mode', defaultMode); if(subTypes.hasLines(traceOut)) { - handleLineDefaults(traceIn, traceOut, defaultColor, coerce); + handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce); handleLineShapeDefaults(traceIn, traceOut, coerce); coerce('connectgaps'); } diff --git a/test/image/baselines/gl3d_scatter-color-array.png b/test/image/baselines/gl3d_scatter-color-array.png new file mode 100644 index 00000000000..b0c2847bda7 Binary files /dev/null and b/test/image/baselines/gl3d_scatter-color-array.png differ diff --git a/test/image/baselines/gl3d_scatter-color-line-gradient.png b/test/image/baselines/gl3d_scatter-color-line-gradient.png new file mode 100644 index 00000000000..d09a868ea5c Binary files /dev/null and b/test/image/baselines/gl3d_scatter-color-line-gradient.png differ diff --git a/test/image/baselines/gl3d_scatter-color-mono-and-palette.png b/test/image/baselines/gl3d_scatter-color-mono-and-palette.png new file mode 100644 index 00000000000..b0c269c9ca0 Binary files /dev/null and b/test/image/baselines/gl3d_scatter-color-mono-and-palette.png differ diff --git a/test/image/baselines/gl3d_scatter-colorscale-marker.png b/test/image/baselines/gl3d_scatter-colorscale-marker.png new file mode 100644 index 00000000000..7a4c4156a99 Binary files /dev/null and b/test/image/baselines/gl3d_scatter-colorscale-marker.png differ diff --git a/test/image/mocks/gl3d_scatter-color-array.json b/test/image/mocks/gl3d_scatter-color-array.json new file mode 100644 index 00000000000..d6226c7685c --- /dev/null +++ b/test/image/mocks/gl3d_scatter-color-array.json @@ -0,0 +1,53 @@ +{ + "data": [ + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[11,10,9,7,5,6,4,2,3,1,3], + "z":[4,5,4,3,2,1,0,-1,-2,-3,-4], + "mode": "lines", + "line": { + "width": 5, + "color": [ + "#67001f", + "#b2182b", + "#d6604d", + "#f4a582", + "#fddbc7", + "#d1e5f0", + "#92c5de", + "#4393c3", + "#2166ac", + "#053061" + ] + }, + "type":"scatter3d" + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[7,5,6,4,2,3,1,3,-1,-4,-2], + "z":[2,3,4,5,4,3,2,1,0,-1,-2], + "mode": "lines+markers", + "line": { + "width": 5, + "color": [ + "#67001f", + "#b2182b", + "#d6604d", + "#f4a582", + "#fddbc7", + "#d1e5f0", + "#92c5de", + "#4393c3", + "#2166ac", + "#053061" + ] + }, + "type":"scatter3d" + } + ], + "layout": { + "title": "Markers should default to line color", + "height":758, + "width":1310 + } +} diff --git a/test/image/mocks/gl3d_scatter-color-line-gradient.json b/test/image/mocks/gl3d_scatter-color-line-gradient.json new file mode 100644 index 00000000000..992e6e200bd --- /dev/null +++ b/test/image/mocks/gl3d_scatter-color-line-gradient.json @@ -0,0 +1,86 @@ +{ + "data": [ + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[7,5,6,4,2,3,1,3,-1,-4,-2], + "z":[2,3,4,5,4,3,2,1,0,-1,-2], + "marker": { + "color": "purple" + }, + "line": { + "width": 10, + "color": [ + "rgb(166,206,227)", + "rgb(31,120,180)", + "rgb(31,120,180)", + "rgb(178,223,138)", + "rgb(51,160,44)", + "rgb(51,160,44)", + "rgb(251,154,153)", + "rgb(227,26,28)", + "rgb(255,127,0)", + "rgb(106,61,154)", + "rgb(106,61,154)" + ] + }, + "type":"scatter3d" + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[11,10,9,7,5,6,4,2,3,1,3], + "z":[2,3,4,5,4,3,2,1,0,-1,-2], + "marker": { + "color": [1,2,3,4,5,6,7,8,9,10,11] + }, + "line": { + "width": 10, + "color": [ + "rgb(166,206,227)", + "rgb(31,120,180)", + "rgb(31,120,180)", + "rgb(178,223,138)", + "rgb(51,160,44)", + "rgb(51,160,44)", + "rgb(251,154,153)", + "rgb(227,26,28)", + "rgb(255,127,0)", + "rgb(106,61,154)", + "rgb(106,61,154)" + ] + }, + "type":"scatter3d" + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[17,15,14,12,11,10,9,7,5,6,4], + "z":[2,3,4,5,4,3,2,1,0,-1,-2], + "marker": { + "color": [1,2,3,4,5,6,7,8,9,10,11], + "colorscale": "Viridis" + }, + "line": { + "width": 10, + "color": [ + "rgb(166,206,227)", + "rgb(31,120,180)", + "rgb(31,120,180)", + "rgb(178,223,138)", + "rgb(51,160,44)", + "rgb(51,160,44)", + "rgb(251,154,153)", + "rgb(227,26,28)", + "rgb(255,127,0)", + "rgb(106,61,154)", + "rgb(106,61,154)" + ] + }, + "type":"scatter3d" + } + + ], + "layout": { + "title": "Color array for lines, and explicit color for markers", + "height":758, + "width":1310 + } +} diff --git a/test/image/mocks/gl3d_scatter-color-mono-and-palette.json b/test/image/mocks/gl3d_scatter-color-mono-and-palette.json new file mode 100644 index 00000000000..9f5a0a3017d --- /dev/null +++ b/test/image/mocks/gl3d_scatter-color-mono-and-palette.json @@ -0,0 +1,76 @@ +{ + "data": [ + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[7,5,6,4,2,3,1,3,-1,-4,-2], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "lines+markers", + "line": { + "width": 5, + "colorscale": "Viridis", + "color": [1,2,3,4,5,6,7,8,9,10] + }, + "marker": { + "size": 5 + }, + "type":"scatter3d" + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[10,8,9,7,5,6,4,6,2,-1,1], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "lines", + "line": { + "width": 8, + "color": "magenta" + }, + "marker": { + "size": 10 + }, + "type":"scatter3d" + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[12,10,11,9,7,8,6,8,4,1,3], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "lines+markers", + "line": { + "width": 8, + "color": "magenta" + }, + "marker": { + "size": 5 + }, + "type":"scatter3d" + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[16,14,15,13,11,12,10,12,8,5,7], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "lines", + "line": { + "colorscale": "Viridis", + "color": [1,2,3,4,5,6,7,8,9,10], + "width": 5 + }, + "type":"scatter3d" + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[20,18,19,17,15,16,14,16,12,9,11], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "lines", + "line": { + "width": 4 + }, + "type":"scatter3d" + } + + + ], + "layout": { + "title": "Monochrome and palette based line plots", + "height":758, + "width":1310 + } +} diff --git a/test/image/mocks/gl3d_scatter-colorscale-marker.json b/test/image/mocks/gl3d_scatter-colorscale-marker.json new file mode 100644 index 00000000000..7f33e744ee7 --- /dev/null +++ b/test/image/mocks/gl3d_scatter-colorscale-marker.json @@ -0,0 +1,180 @@ +{ + "data": [ + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[0,0,0,0,0,0,0,0,0,0,0], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 14, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Greens", + "cmin": 2, + "cmax": 4, + "cauto": true + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[1,1,1,1,1,1,1,1,1,1,1], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 12, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Viridis", + "cmin": 2, + "cmax": 4 + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[2,2,2,2,2,2,2,2,2,2,2], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 9, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Viridis", + "cmin": -20, + "cmax": 20, + "reversescale": false + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[3,3,3,3,3,3,3,3,3,3,3], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 6, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Viridis", + "cmin": -20, + "cmax": 20, + "reversescale": true + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[4,4,4,4,4,4,4,4,4,4,4], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 8, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Reds", + "autocolorscale": false + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[5,5,5,5,5,5,5,5,5,5,5], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 11, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Viridis", + "autocolorscale": true + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[6,6,6,6,6,6,6,6,6,6,6], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 14, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Viridis" + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[7,7,7,7,7,7,7,7,7,7,7], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 12, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "colorscale": "Viridis", + "cmin": 2, + "cmax": 4, + "reversescale": true + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[8,8,8,8,8,8,8,8,8,8,8], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 9, + "color": [-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11] + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[9,9,9,9,9,9,9,9,9,9,9], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 7, + "color": [0,1,2,3,4,5,6,7,8,9,10] + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[10,10,10,10,10,10,10,10,10,10,10], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 8, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "cmin": 2, + "cmax": 4, + "cauto": true + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[11,11,11,11,11,11,11,11,11,11,11], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 11, + "color": [-2,-1,0,1,2,3,4,5,6,7,8] + } + }, + { + "x":[-4,-3,-2,-1,0,1,2,3,4,5,6], + "y":[12,12,12,12,12,12,12,12,12,12,12], + "z":[0,0,0,0,0,0,0,0,0,0,0], + "mode": "markers", + "type":"scatter3d", + "marker": { + "size": 13, + "color": [-2,-1,0,1,2,3,4,5,6,7,8], + "reversescale": true + } + } + ], + "layout": { + "title": "Scatter colorscale marker cauto, constrained and expanded variations", + "height":758, + "width":1310 + } +}