Why are the relayoutData and selectedData variables of dcc.Graph both changed when using the select box or lasso tool?

Hello everyone,

I have just checked out the 4th part of the dash tutorial and it surprises me that the relayoutData variable in the first example on that website changes when the box select or lasso tool is used. The coordinates of the box selection or lasso tool are then stored in relayoutData and seem to overwrite all previously stored values regarding the actual layout of the plot. This means the properties related to the zoom and layout of the plot are replaced with what appears to be completely redundant information because the box and lasso selection values are already stored in the selectedData variable, where I would them expect to be. Just try the tutorial and watch the output in the " Zoom and Relayout Data" column when using these tools to see what I am talking about.

Is it be supposed to be like that? I can imagine deleting the properties related to the layout by these tool becomes troublesome if the x.range and y.range values are used in a callback function for example.

Hello, same thing here, not all shapes are shown in this callback, only the ones in the radius of selection, it looks like this is expected behavior…
Is there maybe some workaround to show all drawn shapes in dcc.Graph?
Happy New Year, btw:)

Update: to get the data of the full graph, you should use
State(‘graph-figure’, ‘figure’), returns a dict

Hi @Manwe, welcome to the forums. Actually I can’t answer your question, but I can’t imagine how this behaviour could be troublesome.

@worker1 I don’t quite understand what you are trying to do.

The shapes are stored in the figure.layout.

Here is an example how to access and change them:

Hello @Manwe,

My guess is that relayout is adjusted when you create a selection, as the selection displays. And obviously, the selectedData is populated when you make selections.


a simple use case that comes to my mind is adding a dash_table to the aforementioned tutorial that only shows the data points in the current zoom of the plotly figure (independent of an additional box or lasso selection).
A straight forward approach would be taking the entries of the relayoutData dict to determine the current x- and y-axis size. As long as the plotly tools which actually change the view are used, there appears to be an entry in the dictionary that corresponds to the current view. Hence, a callback function could check for the entries in the relayoutData dictionary and slice a copy of the original data frame according to whatever information on the current view is found there. After a zoom or pan event, the “x.range” and “y.range” entries provide the exact size of the current view for instance, and I guess the “autosize” or “xaxis.autorange” entries can also be used to get the exact view of the plot somehow, even though I do not know how at the moment. However, as soon as the lasso or box tool is picked all information on the current view vanishes completely. If there is no information on the current view at all, how to get the desired table right? I guess the last known view could be stored and a check implemented within the callback function if the relayoutData was changed because the view was actually changed or not, but this is what I feel might become troublesome.

I also don’t know if this is the best way to get a table with the data of the current view. If you know a better one that might also give the current x- and y-ranges after using an autoscale event, that’d be nice to know.

Hello @Manwe,

If you want to just use the ranges to determine the current data in the table, then I’d recommend disabling the selection and lasso buttons:

Hi @worker1

thanks for the hint to rather use State(‘graph-figure’, ‘figure’) than the relayoutData variable when looking for the current range of the x or y axis of in a dcc.Graph for example. It seems this is a more robust method that doesn’t break if a select tool or any other interaction changing the relayoudData variable is used.
It looks like this method also avoids the problem that the range values of the relayoutData are different depending on the mode of user interaction as posted by @geepy here.
In that case, I also understand why @AIMPED doesn’t see how the current behaviour of the relayoutData variable might be troublesome.