Skip to content

Updates to inspector plot: add rectangle mode and fix operation inside polygons - #528

Merged
nvaytet merged 19 commits into
mainfrom
rectangle-inspector
Feb 18, 2026
Merged

nvaytet merged 19 commits into
mainfrom
rectangle-inspector

Conversation

@nvaytet

@nvaytet nvaytet commented Feb 13, 2026 •

Copy link
Copy Markdown
Member

Some updates to the inspector plot:

  • fixed slicing when used on data with a 2d coordinate
  • small optimization to avoid converting coords to midpoints every time a polygon is modified
  • added rectangle analog to feat: polygon inspector tool #518
  • use better data in the inspector notebook (clusters3d and air temperature)
Screenshot_20260218_100505

A question arose while implementing this: there is an operation argument that decides which reduction operation to apply along the 3rd dimension into the paper. This is a sum by default, but can be a min, max or mean.
Now, when we select a region inside a rectangle or a polygon, we need to also reduce that along the x and y dimensions before sending to the 1d plot along z. The operation there is currently always a sum, and I don't think it would make sense to do anything else than sum?

So the question is: does it even make sense to have other operations along the z dimension?

Update: I decided to remove the operation in the end.

Edit: there is an example where performing a mean operation actually makes sense...
https://scipp.github.io/plopp/getting-started/numpy-pandas-xarray.html#Interactive-tools

So instead of removing the operation, we apply the same operation along the x/y dims inside a selected region.
I think this makes sense: in the 1d plot, we would want to see what is the mean temperature inside that region, as a function of datetime.

@nvaytet

nvaytet commented Feb 13, 2026 •

Copy link
Copy Markdown
Member Author

TODO: still need to write some tests

@nvaytet nvaytet changed the title Add rectangle inspector tool Updates to inspector plot: add rectangle mode and remove operation arg Feb 14, 2026
y = _coord_to_centers(da, ydim)
vx = poly['x']['value'].to(unit=x.unit).values
vy = poly['y']['value'].to(unit=y.unit).values
vx = poly['x']['value'].values

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 don't think we need to convert the unit here? By construction, the xy locations returned by the polygon info are in the correct canvas units.

@nvaytet
nvaytet marked this pull request as ready for review February 16, 2026 16:19
@nvaytet
nvaytet requested a review from jokasimr February 16, 2026 16:19


@pytest.mark.usefixtures('_use_ipympl')
@pytest.mark.parametrize(

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 found these tests rather difficult to follow, so I decided to re-write something simpler.
Please check it covers all previous cases.

@jokasimr

Copy link
Copy Markdown
Contributor

Removing operation sounds like a good call 👍

@nvaytet

nvaytet commented Feb 17, 2026 •

Copy link
Copy Markdown
Member Author

Removing operation sounds like a good call 👍

Hmm here is an example where performing a mean operation actually makes sense...
https://scipp.github.io/plopp/getting-started/numpy-pandas-xarray.html#Interactive-tools

Maybe we should only allow operation when mode='point'.
Then we don't break anyone's notebooks...

@nvaytet nvaytet changed the title Updates to inspector plot: add rectangle mode and remove operation arg Updates to inspector plot: add rectangle mode and fix operation inside polygons Feb 17, 2026
@nvaytet

nvaytet commented Feb 17, 2026

Copy link
Copy Markdown
Member Author

Update:

Instead of removing the operation or only allowing it for point mode, we apply the same operation along the x/y dims inside a selected region.
I think this makes sense: in the 1d plot, we would want to see what is the mean temperature inside that region, as a function of datetime.

@jokasimr jokasimr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good!

The tests don't cover the exact same cases, but as far as I can tell they cover the relevant cases, and I agree they are better written like this.

Comment on lines +46 to +56
try:
# If there is a 2D coordinate in the data, we need to slice the other dimension
# first. The assumption here is that there would only be one multi-dimensional
# coordinate in a given DataArray (which is very likely the case).
if da.coords[y['dim']].ndim > 1:
return da[x['dim'], x['value']][y['dim'], y['value']]
else:
return da[y['dim'], y['value']][x['dim'], x['value']]
except IndexError:
# If the index is out of bounds, return an empty DataArray
return sc.full_like(da[y['dim'], 0][x['dim'], 0], value=np.nan, dtype=float)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I didn't really understand this, what situation are we dealing with here?

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.

Maybe I should have expanded the comment a little.
Say we have a DataArray where the x coord is 2d, and the y and z coords are 1d (typically you would only have one multi-d coord in a DataArray, even though Scipp does not raise if more are present).
If we first try to slice along x, Scipp will raise an error saying 2d coords cannot be used for label-based indexing (here we are slicing using da['x', sc.scalar(15.1, unit='m')]).

But if we first slice the y dim, then it slices out the column with the correct associated x coord, which is now 1d, and can then be sliced using label-based indexing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But how can we plot with x on one axis if it is a 2D coord? 🤔

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.

See the image below. A 2d x coord means that the x position varies with y.
You typically get this in neutron data reduction when converting to d-spacing for example (see https://scipp.github.io/scippneutron/tutorials/powder-diffraction.html#From-events-to-histogram).

Did that answer your question, or did you mean something else?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see now what you mean 👍

try:
values = fix_empty_range(find_limits(x, scale=scale, pad=pad))
except ValueError:
return dict.fromkeys(keys, None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess this is what fixes the numpy issue, what was the problem?

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.

No, the numpy error was fixed in #529.
This is a fix for when we click outside the range covered by the image. It would return an array with all NaNs.
When this gets passed to the 1d figure, it raised an error saying it could not compute limits because all values were NaN.
This then meant that even adding subsequent points would not draw new lines on the 1d plot because every time a new line is added, it tries to auto-scale the axis, would loop through all lines and get the the line with all NaNs and then raise an error in the background (which you can see in the log console in debug mode).

The fix here is that if trying to computing limits fails, we return a bounding box with just Nones and this means it cleanly gets ignored when trying to compute limits for the whole axes.

This thus represents a slight change in behaviour: before, if you passed 1d data to a line plot with all nans, it raised an error. Now it does not raise, but also plots nothing on the axes. It was useful in some cases to get the error, but I could not find a good way to reconcile this and the possibility of the user clicking outside the range. This can easily happen when you have a 2D coordinate for example:
Screenshot_20260218_134846

@nvaytet
nvaytet merged commit 85a7450 into main Feb 18, 2026
4 checks passed
@nvaytet
nvaytet deleted the rectangle-inspector branch February 18, 2026 14:34
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.

2 participants