feat: add 3D interactive graph visualisation with Plotly - #118
feat: add 3D interactive graph visualisation with Plotly#118yuvraajnarula wants to merge 16 commits into
Conversation
|
Here's a simple script usage with icosahedral.py and plot_3D.py: flat_mesh = create_flat_icosahedral_mesh_graph(subdivisions=2)
nx.set_edge_attributes(flat_mesh, "m2m", name="component")
fig_flat = render_with_plotly(
flat_mesh,
show=True,
title="Flat Icosahedral Mesh (subdivisions=2)",
node_size=5.0,
edge_width=1.0,
component_colors={"m2m": "#43A047"},
)
hier_mesh = create_hierarchical_icosahedral_mesh_graph(max_subdivisions=3)
for u, v, attrs in hier_mesh.edges(data=True):
edge_level = attrs.get("level", "")
if isinstance(edge_level, str) and "_to_" in edge_level:
parts = edge_level.split("_to_")
comp = "mesh_up" if int(parts[0]) > int(parts[1]) else "mesh_down"
else:
comp = "m2m"
hier_mesh[u][v]["component"] = comp
custom_colors = {
**DEFAULT_COMPONENT_COLORS,
"m2m": "#1565C0"
"mesh_up": "#E53935",
"mesh_down": "#43A047",
}
fig_hier = render_with_plotly(
hier_mesh,
show=True,
title="Hierarchical Icosahedral Mesh (max_subdivisions=3)",
node_size=4.0,
edge_width=1.2,
component_colors=custom_colors,
)
fig_flat.write_html("flat_icosahedral.html")
fig_hier.write_html("hierarchical_icosahedral.html")
print("Saved flat_icosahedral.html and hierarchical_icosahedral.html") |
@leifdenby @joeloskarsson |
|
I think the flat representation for just the individual meshes are fine for the most part but I dont think its going overboard with the globe based visualization. At the least a spherical representation would be much better to understand the graph. Especially for the hierarchical flat graph its not that readable yeah? What I think is happening in the hierarchical one is that the coarser graphs are getting hidden beneath the finer graphs so theyre getting fully hidden, maybe trying to have those above would make it more readable? Overall for hierarchical having a concentric spherical representation is much better if not a proper globe one right now |
|
@Joltsy10 You were absolutely right: the flat layout (x=lon, y=lat, z=level) was hiding coarser mesh levels in hierarchical graphs. To fix that, I’ve added a concentric spherical layout as an option in plot_3d.py. Now you can call I also kept all the performance tricks you liked (edge batching, None separators, and optional plotly dependency). So, the concentric version stays just as browser-friendly. If you have a chance to test it on your graphs or have ideas for further improvements (e.g., textured Earth or different colour schemes), I’d love to hear them. Happy to collaborate on polishing it further. Thanks again for pushing this in the right direction. I really appreciate your input! This is the output I got while I am trying to work more on the 3d globe approach before pushing it. I hope @leifdenby considers this under the domain. |
|
usage : fig_hier_concentric = render_with_plotly(
hier_mesh,
show=True,
title="Hierarchical Icosahedral Mesh (concentric layout)",
node_size=4.0,
edge_width=1.2,
component_colors=custom_colors,
layout="concentric",
sphere_base_radius=1.0,
sphere_radius_step=0.5,
) |
|
Hi @yuvraajnarula @Joltsy10, the concentric layout is a game-changer for visibility! To follow up on the '3D globe approach' mentioned, I'd love to contribute by adding a background map layer (coastlines/borders). Having the Earth's geometry rendered just below the grid nodes (at a slightly smaller radius) would provide essential geographical context for analyzing meteorological features. I can work on integrating a lightweight coastline trace into the render_with_plotly function. What do you think? |
One thing to keep in mind: adding coastlines/borders can increase the complexity of the rendering, especially file size and load time, if we embed vector data directly. It might be worth considering an optional mode (e.g., If you open a separate issue or draft PR for this, I’d be happy to help think through how to keep the performance (batched traces) while adding the map layer. Looking forward to seeing what you come up with! |
Removed co-authors from the 3D interactive graph visualisation entry.
|
@leifdenby |
Mohit-Lakra
left a comment
There was a problem hiding this comment.
Planning to use this in the neural-lam documentation notebooks exactly the cross-repo integration @leifdenby suggested in #20.
|
@yuvraajnarula, I'm now moving forward to the next technical gaps. Let me know if you need any specific adjustments to the visualization engine! |



Describe your changes
Adds
weather_model_graphs.visualise.plot_3dwith a single public entry point:Node positions are read from the existing
posnode attribute (x, y). The vertical axis (z) is derived from the integerlevelnode attribute present on mesh nodes in hierarchical and multiscale graphs. Grid nodes that carry noleveland are placed atz = -1so they always appear below all mesh levels, matching the convention agreed in #20.All edges of the same component (
g2m,m2m,m2g) are batched into a singleScatter3dtrace withNoneseparators between segments. This is the key performance fix discussed in #20: instead of one trace per edge (which produces >100 MB HTML files for global graphs), the entire component is one trace object, keeping output small and browser-friendly even for dense graphs.Node kinds (grid, mesh level 0, mesh level 1, …) are split into separate traces so the user gets independent legend toggles per level in the interactive figure.
plotlyis guarded as an optional dependency, and the rest ofweather_model_graphscan be imported without it. The function raises a clearImportErrorwith install instructions if plotly is absent, following the same pattern as the existingHAS_PYGguard insave.py.Two small edits are required in existing files:
src/weather_model_graphs/visualise/__init__.py— expose the new function:pyproject.toml— add plotly to an optional dependency group:Dependencies:
plotly(install withpip install weather-model-graphs[visualisation])numpy,networkx(already in core dependencies)Issue Link
Closes #20
Type of change
Checklist before requesting a review
pullwith--rebaseoption if possible).Checklist for reviewers
Each PR comes with its own improvements and flaws. The reviewer should check the following:
Author checklist after completed review
reflecting type of change (add section where missing):
Checklist for assignee