Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initializing scattergl with empty traces throws TypeError #1298

Closed
rldotai opened this issue Jan 12, 2017 · 2 comments · Fixed by #1300
Closed

Initializing scattergl with empty traces throws TypeError #1298

rldotai opened this issue Jan 12, 2017 · 2 comments · Fixed by #1300

Comments

@rldotai
Copy link

rldotai commented Jan 12, 2017

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.

@etpinard
Copy link
Contributor

Thanks for the report.

@rldotai
Copy link
Author

rldotai commented Jan 12, 2017

Sorry, the CodePens were mixed around but they should refer to the correct ones now.

For reference, I am using plotly.js version 1.21.3 from npm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants