Skip to content

Histogram does not scale to the range of new data on restyle #24

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

Closed
rasmusab opened this issue Nov 22, 2015 · 7 comments · Fixed by #1901
Closed

Histogram does not scale to the range of new data on restyle #24

rasmusab opened this issue Nov 22, 2015 · 7 comments · Fixed by #1901
Labels
bug something broken

Comments

@rasmusab
Copy link

If you set up a histogram...

var data1 = [1, 2, 2, 3, 3, 3, 4, 4, 5];
var hist = document.getElementById('hist_div');
Plotly.plot(hist, [{x: data1, type: 'histogram' }]);

... and then update this histogram with wider data followed by a restyle...

var data2 = [10, 20, 20, 30, 30, 30, 40, 40, 50];
Plotly.restyle(hist, {x: [data2]});

... the histogram keeps the old range (in this case 1 to 5) and does not scale to the range of the new data (which is the case when using scatter style plot). Here is a codepen showing this: http://codepen.io/rasmusab/pen/megKOo

I have not found any documentation regarding whether this is the expected behavior. If it is, what would be the best practice for updating a histogram with new data?

@pavanmehtamca
Copy link

There seems to be a problem with it..
I think the expected behavior should be to append the points in the X-axis and their corresponding values of Y be plotted on the Histogram

@etpinard
Copy link
Contributor

Bug confirmed. Thank very much for reporting.

Histogram traces don't update on restyle and extendTraces.

@etpinard etpinard added the bug something broken label Nov 23, 2015
@mdtusz
Copy link
Contributor

mdtusz commented Dec 29, 2015

#149

@etpinard
Copy link
Contributor

@rasmusab @pavanmehtamca

As mentioned in #149 (comment), this issue only affects restyle/extendTraces calls with new data outside the computed [ xbins.start , xbins.end ] interval.

Here's a workaround: http://codepen.io/etpinard/pen/MKbzNv

@alexcjohnson
Copy link
Collaborator

This is officially our oldest open bug! At more than a year and a half, it needs to go.

this issue only affects restyle/extendTraces calls with new data outside the computed [ xbins.start , xbins.end ] interval.

Generally true, but size also depends on the number of samples, and start and end can get shifted due to the precise values - for example if most are or are not integers.

And copying over some comments from @etpinard in #149:

Times where the calc or plot step adds attributes to user data:

  • histogram and histogram2d calc step: xbins and ybins when autobin? is true
  • contour calc step: contours when autocontours is true
  • contour plot step: zmin and zmax when zauto is true and coloring set to 'heatmap'
  • heatmap calc step: zsmooth when data can't be smooth using the 'fast' algorithm.
  • colorscale calc: zmin / zmax or cmin / cmax + colorscale when zauto or cauto is true

Updating histogram data should clear the computed xbins and ybins, but the other cases aren't as obvious.

Should updating contour data clear the computed contours attributes? I'd vote for no.

Should the updating data linked to a colorscale update the bounds of the colorscale? I'd vote for no also.

So, looks like xbins ans ybins are in a league of their own.

I would actually argue that in all of these cases the update should reset the derived attributes - for example if new colorscale or contour data expands the range, you would want to see that information unless you had explicitly hidden it. Us putting attributes back into data and layout (in this case xbins) is basically a convenience to avoid unnecessary repeated calculations and shouldn't affect the behavior the user sees - so a Plotly.plot followed by a Plotly.restyle should behave exactly as if the edits were incorporated in the original Plotly.plot call. I hesitate to make this a completely blanket statement, but if there are good exceptions to this I'd like to see them!

The fix I'd propose then is - perhaps counterintuitively - to also copy the inferred auto... values back to the input figure. This is what we do with axis ranges, and restyle / relayout make sure to clear them when the user manually edits the range.

@etpinard
Copy link
Contributor

I would actually argue that in all of these cases the update should reset the derived attributes

This means that if a user wants the auto first view (e.g. say the cmin and cmax colorbar attribute) of the first Plotly.newPlot to remain after updates, they will need to set cmin and cmax to those value that they don't know in advance, which is a little annoying in my mind.

I'm not sure how common this use case is for plotly.js users. Maybe it doesn't matter. Maybe we need another auto mode (e.g. cauto would be an enumerated true, false or first-view). But at the very least I'd call what @alexcjohnson is proposing a breaking change.

@alexcjohnson
Copy link
Collaborator

Ha, for colorscales it turns out we already do what I was about to propose here: if you explicitly specify *auto: false, then it will fill in the auto values but leave it looking like *auto: false so that future changes will not re-invoke the autoscaling; but if you don't specify an explicit *auto value it defaults to true since the explicit ranges are missing.

So for example:

var x1 = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4];
var y1 = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4];
Plotly.newPlot(gd, [{type: 'histogram2d', x: x1, y: y1, zauto: false}]);

screen shot 2017-07-20 at 12 35 48 pm

and then:

// move the last point so we have one bin that gets 1 sample, another gets 3
Plotly.restyle(gd,'x', [[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 3]])

screen shot 2017-07-20 at 12 37 17 pm
range is still 1.5->2.5

But if you don't specify zauto: false in the first place, the initial plot is identical but after restyle you get:
screen shot 2017-07-20 at 12 38 56 pm
recalculated autocolor: 1->3

So I think it's only in the context of histogram bins that this is a change - and therefore I'd consider it an inconsistency, a bug, not a breaking change, and I should implement the same logic with explicit autobin*: false values in histograms.

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

Successfully merging a pull request may close this issue.

5 participants