Skip to content

Support updates to positions of scatter3d points#559

Merged
nvaytet merged 12 commits intomainfrom
scatter3d-pos-update
Apr 30, 2026
Merged

Support updates to positions of scatter3d points#559
nvaytet merged 12 commits intomainfrom
scatter3d-pos-update

Conversation

@nvaytet
Copy link
Copy Markdown
Member

@nvaytet nvaytet commented Apr 27, 2026

Alternative to #484

Much of the changes are similar, but things are written in a simpler manner here, and we do not check for equality of coordinates (as this took time).

Updating the positions is between 3 and 10 times faster than updating the colors.
The gain of removing the unexpected behaviour that positions don't update (only colors used to update) are worth the cost, I think.

I tried looking at the Dream instrument view again and the loss of performance was not noticeable, contrary to what I wrote in #484 (comment)
Possibly because of performance updates done on the instrument view side itself? (scipp/scippneutron#691)

Fixes #495

@nvaytet nvaytet changed the title Update positions of scatter3d point upon update Update positions of scatter3d points upon update Apr 27, 2026
@nvaytet nvaytet changed the title Update positions of scatter3d points upon update Support updates to positions of scatter3d points Apr 27, 2026
@nvaytet nvaytet marked this pull request as ready for review April 27, 2026 21:27
opacity = self.opacity.value if at_least_one_cut else 1.0
self._set_opacity({'new': opacity})

if (not self._nodes) and at_least_one_cut:
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We change the mechanism here: instead of grabbing the data from the nodes in the view, we add children nodes to the data which is the input to the view.

This means that automatically, if the input data changes, the data in the cuts will also update.
We ca now do this because updating a scatter point with different number of points is now allowed (when we update the cut range, the number of selected points changes).

@nvaytet nvaytet requested a review from jl-wynen April 28, 2026 10:29
@nvaytet
Copy link
Copy Markdown
Member Author

nvaytet commented Apr 28, 2026

Assigning you @jl-wynen as you already reviewed the older PR, and changes here are pretty similar (though some things were fixed with the clip3d).

Comment on lines +183 to +185
self._canvas.remove(self.points)
self.points = new_points
self._canvas.add(self.points)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you further change this?

Suggested change
self._canvas.remove(self.points)
self.points = new_points
self._canvas.add(self.points)
self._canvas.add(self.points)
self.points = new_points
self._canvas.remove(self.points)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I get it, why would I add the current points again instead of the new points?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I missed that self.points changes in the middle.
My idea was to add and then remove to not have a blank canvas in case that causes problems. But does 3js rerender when removing points? Or only when you explicitly tell it to?

].astype('float32')

def update(self, new_values):
def update(self, new_values: sc.DataArray) -> None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it feasible to have a simpler update_values method that only updates the colours and that gets called by nodes that do not change positions?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, the values you get from an update are just a full data array with new data, where both coordinates or data could change.
If we want to change this, then it would be a much more fundamental change in how the whole Plopp works...

Comment thread src/plopp/backends/pythreejs/scatter3d.py Outdated
Comment thread src/plopp/widgets/clip3d.py Outdated
)
self._nodes[n.id].add_view(self._view)

if self._nodes and (not at_least_one_cut):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not at_least_one_cut here? Don't you want to remove old nodes regardless of whether there is a cut now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the logic is the following:

To start with, we have just the original data nodes (just say one of them for simplicity, which is the most common case).
When a button is clicked to create a new cut, we add a node which selects a subset of data points from the original node.

After that, no matter how many new cuts we add on top, we are still using that same node, which performs a selection from the originaly node, combining all selection criteria from the different cuts. There are at most only 2 nodes in play at any time: the original node and the node that does the selection.

Once the last cut gets deleted, that is when we need to remove the additional ('selection') node.
So this needs to happen when the final cut has been deleted.

Does that make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think I get it now.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the explanation as a comment in the code

nvaytet and others added 2 commits April 28, 2026 19:56
Co-authored-by: Jan-Lukas Wynen <j-l.wynen@hotmail.de>
@nvaytet nvaytet merged commit ab4fe97 into main Apr 30, 2026
6 checks passed
@nvaytet nvaytet deleted the scatter3d-pos-update branch April 30, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scatter3d plot: positions do not update

2 participants