Skip to content

Extend heatmap into 3D surface with framing and height scale - #2081

Open
NAThompson wants to merge 1 commit into
silx-kit:mainfrom
NAThompson:feat/surface-vis
Open

NAThompson wants to merge 1 commit into
silx-kit:mainfrom
NAThompson:feat/surface-vis

Conversation

@NAThompson

@NAThompson NAThompson commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1292, closes #1306. Adds a "3D" toggle to the Heatmap toolbar that extends the current slice into a surface sharing the heatmap's colour map, domain, scale and axes, with a height control and auto-framing (axes and grid in #2086). Removes the experimental Surface tab; breaking for the lib 18 beta (showPoints, SurfaceMeshGeometry removed).

Before: heatmap After: "3D" toggle on
Rotated Log scale (Storybook)

🤖 Generated with Claude Code

@NAThompson
NAThompson force-pushed the feat/surface-vis branch 2 times, most recently from a9cfc97 to 2877318 Compare October 14, 2026 01:17
@loichuder
loichuder self-requested a review October 15, 2026 12:42

@loichuder loichuder left a comment

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.

Thanks a lot, this looks fantastic!

I did a first high-level quick round of review so I plan to iterate smoothly afterwards

Comment on lines +86 to +87
export const NaNHoles = meta.story({
args: {

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.

Suggested change
export const NaNHoles = meta.story({
args: {
export const NaNHoles = meta.story({
name: 'With NaN'
args: {

The title displayed weirdly on my end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done, thanks! The story now uses name: 'With NaN'.

Comment on lines +93 to +97
{shading ? (
<meshLambertMaterial key="lit" vertexColors side={DoubleSide} />
) : (
<meshBasicMaterial key="unlit" vertexColors side={DoubleSide} />
)}

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 explain in what situations the shading is needed? On the tests I did, it seems to only lighten slightly the surface.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I noticed this as well-setting my claude off to think on it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good question. I checked pixel by pixel and shading only ever darkens: flat areas keep their colour (Viridis(0.5) = (33,145,140) off vs (32,143,138) on). My guess is that the lightening you saw was the toggle going from on to off.

The light is nearly overhead so that flat areas keep their exact colours, which makes the effect tiny on gentle relief, where it would matter most. An oblique light makes ripples readable but darkens flat areas, so they no longer match the colour bar. Left to right: off, on (this PR), oblique light (experiment, not in this PR):

When colour already shows height, shading adds little:

Since that's a design trade-off, I'd suggest removing shading from this PR and proposing it separately. Does that work for you?

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.

Thanks for the sum-up !

Sure, let's remove the shading for now and discuss it later 🙂

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done: shading is removed (plain vertex colours, no lights or normals). #2086 is rebased on top.

const invalidate = useThree((state) => state.invalidate);

const geometry = useMemo(
() => new SurfaceMeshGeometry({ dataArray, rows, cols }),

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 we not have the geometry computation kept in SurfaceMeshGeometry?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point. The geometry is back in SurfaceMeshGeometry, following the useUpdateGeometry pattern: update() builds positions, holes and normals, and a separate updateColors() means changing the colour map doesn't rebuild positions. I also fixed the second triangle's winding, which was clockwise on main and would flip normals for lighting.

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 move the axis creation out of the PR? That means, just having the surface without axes/grid for now.

Don't get me wrong, I think it is really super cool but I would like to review it separately 😉

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@loichuder : Splitting them up for ease of review.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Axes, grid and tick labels are now in #2086, stacked on this PR.

@NAThompson NAThompson changed the title Extend heatmap into 3D surface with axes, framing and height scale Extend heatmap into 3D surface with framing and height scale Oct 15, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

[SurfaceVis] Improvements roadmap surface plot in 3D

2 participants