Skip to content

Initializing scattergl with empty traces throws TypeError #1298

Closed
@rldotai

Description

@rldotai

Summary

  1. Initializing plots with empty traces (traces are defined and styled but have no data yet) throws an error when using scattergl for the traces' type.
  2. This behavior is not consistent with how Plotly acts when using scatter, which allows the user to do this.
  3. An error also results when using Plotly.addTraces with scattergl trace that has no data present, which is also inconsistent with how Plotly behaves when the trace is of type scatter.
  4. It seems to be due to an assumption that the traces always have some data in plotly.js/src/components/errorbars/index.js`, but I do not understand enough of the code base to create a pull request, hence this issue.

Details

In some situations I find it helpful to initialize traces with empty arrays for their data prior to adding values through Plotly.extendTraces().
For example, before data starts arriving, we might wish to style the traces, or ensure that the traces are in some particular order.

This behavior appears to be supported in the SVG case (at least for type: scatter), but results in an error when using GL version.

The following works, allowing one to define the traces without adding data, and later extend them see CodePen demo

var data = [
	{y: [], type: 'scatter'}
];

var layout = {
	title: 'Graph Title'
};

Plotly.newPlot(graphDiv, data, layout);

Plotly.extendTraces(graphDiv, {y: [[1, 2, 3]]}, [0])

If we use type: 'scattergl' instead, it throws an error

var data = [
	{y: [], type: 'scattergl'}
];

var layout = {
	title: 'Graph Title'
};

// This throws an error (Plotly 1.21.3)
Plotly.newPlot(graphDiv, data, layout);

From the console, we get:

Uncaught TypeError: Cannot set property 'trace' of undefined
    at Object.errorBars.calcFromTrace (eval at <anonymous> (bundle.js:3613), <anonymous>:96224:27)
    at LineWithMarkers.proto.updateFancy (eval at <anonymous> (bundle.js:3613), <anonymous>:147929:31)
    at LineWithMarkers.proto.update (eval at <anonymous> (bundle.js:3613), <anonymous>:147793:14)
    at Object.createLineWithMarkers [as plot] (eval at <anonymous> (bundle.js:3613), <anonymous>:148148:10)
    at Scene2D.proto.updateTraces (eval at <anonymous> (bundle.js:3613), <anonymous>:124457:42)
    at Scene2D.proto.plot (eval at <anonymous> (bundle.js:3613), <anonymous>:124336:10)
    at Object.plotGl2d [as plot] (eval at <anonymous> (bundle.js:3613), <anonymous>:123933:15)
    at drawData (eval at <anonymous> (bundle.js:3613), <anonymous>:109268:32)
    at Object.lib.syncOrAsync (eval at <anonymous> (bundle.js:3613), <anonymous>:106093:15)
    at Object.Plotly.plot (eval at <anonymous> (bundle.js:3613), <anonymous>:109312:9)

For verification that it works when initial data is supplied, see this CodePen demo

It would appear that the issue originates in the assumption that the initial traces will always contain some data, in plotly.js/src/components/errorbars/index.js:

[...]
errorBars.calcFromTrace = function(trace, layout) {
    var x = trace.x || [],
        y = trace.y,
        len = x.length || y.length;

    var calcdataMock = new Array(len);

    for(var i = 0; i < len; i++) {
        calcdataMock[i] = {
            x: x[i],
            y: y[i]
        };
    }

    calcdataMock[0].trace = trace;

    errorBars.calc({
        calcdata: [calcdataMock],
        _fullLayout: layout
    });

    return calcdataMock;
};

...Which is in turn called because Plotly determines that these traces are fancy (I apologize but I could not find reference to what qualifies a trace as fancy in the documentation and was unable to assess what was going on without delving deeply into the code).

Requested Fix

It would be nice if I could still initialize empty traces when using the GL charts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugsomething broken

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions