Skip to content

Conversation

@VsevolodX
Copy link
Member

@VsevolodX VsevolodX commented Dec 30, 2025

Summary by CodeRabbit

  • New Features

    • Inline visualization of radial distribution function plots in web-based notebooks with automatic environment detection and optimized rendering.
  • Style

    • Minor label and hover-text formatting improvements for plotted interfaces.
  • Chores

    • Standardized source attribution string in materials data.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 30, 2025

📝 Walkthrough

Walkthrough

Updates a dataset JSON source label and adds Pyodide-aware plotting to render RDF plots as inline PNGs in emscripten environments while preserving existing behavior elsewhere.

Changes

Cohort / File(s) Summary
Data Update
other/materials_designer/uploads/0-Ni.json
external.source string literal changed from "Materials Project" to "MaterialsProject".
Pyodide Rendering Enhancement
utils/plot.py
Added Pyodide/emscripten detection (hasattr(sys, 'emscripten')), switch to matplotlib.use("Agg") when detected, render figure to a BytesIO PNG and display via IPython.display.Image/display. New imports: io, sys, IPython.display.Image/display, matplotlib.pyplot as plt. Minor label formatting in plot_twisted_interface_solutions.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Caller as plot_rdf()
    participant Sys as sys (env check)
    participant MPL as matplotlib / pyplot
    participant IO as io.BytesIO
    participant IPY as IPython.display

    rect rgb(230,245,255)
    Note over Caller,IPY: Pyodide / Emscripten path
    Caller->>Sys: check hasattr(sys, 'emscripten')
    Sys-->>Caller: True
    Caller->>MPL: matplotlib.use("Agg")
    Caller->>MPL: create plot (plt.figure / plotting)
    MPL-->>Caller: Figure
    Caller->>IO: create BytesIO buffer
    Caller->>MPL: save figure to PNG into buffer
    MPL-->>IO: PNG bytes
    Caller->>IPY: display(Image(buffer.getvalue()))
    IPY-->>Caller: inline image rendered
    Caller->>MPL: plt.close()
    end

    rect rgb(240,250,240)
    Note over Caller,MPL: Standard (non-Pyodide) path
    Caller->>Sys: check hasattr(sys, 'emscripten')
    Sys-->>Caller: False
    Caller->>MPL: create plot and display normally (interactive backend)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through bytes and plotted light,
Agg brewed pixels for the browser's sight,
One string trimmed, one image shown—
I nibble code and call it home. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix/rdf plot (SOF-7807)' directly addresses the main change in the PR, which adds Pyodide-specific rendering for RDF plots in utils/plot.py.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d9469e and 96bd023.

📒 Files selected for processing (1)
  • utils/plot.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • utils/plot.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d4371d and 6fd5551.

📒 Files selected for processing (2)
  • other/materials_designer/uploads/0-Ni.json
  • utils/plot.py
🔇 Additional comments (4)
other/materials_designer/uploads/0-Ni.json (1)

55-61: LGTM!

The source string normalization from "Materials Project" to "MaterialsProject" is a reasonable standardization. This aligns with typical identifier naming conventions that avoid spaces.

utils/plot.py (3)

1-6: LGTM!

Imports are properly organized and all are used in the Pyodide rendering path.


67-68: LGTM!

The space added in "Interface {i + 1}" improves readability in hover text and trace names.


84-96: The code is safe as-is. Line 82 explicitly sets matplotlib to the Agg backend when running in Pyodide, which is a non-interactive, file-based backend. In Agg mode, plt.show() becomes a no-op and does not clear the figure, so even if plot_distribution_function calls it internally, the figure will remain available for plt.savefig() to capture on line 93. The backend selection before plotting is intentional and handles the concern.

plt.savefig(buf, format="png")
buf.seek(0)
display(Image(buf.read()))
plt.close()
Copy link
Member

Choose a reason for hiding this comment

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

What happens if it's not pyodide? How do we plot RDF??

Copy link
Member Author

Choose a reason for hiding this comment

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

the previous function plot_distribution from utils

Copy link
Member

Choose a reason for hiding this comment

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

Add a comment explaining why this is needed

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
utils/plot.py (1)

89-96: Consider making the figure reference explicit.

The current implementation relies on plt.savefig() saving the "current figure" created by plot_distribution_function. If that function creates multiple figures or changes the current figure context, this might capture the wrong figure.

Additionally, there's no error handling if the save or display operations fail.

🔎 Suggested improvement

Consider having plot_distribution_function return the figure object, then explicitly save that figure:

+    fig = plot_distribution_function(
-    plot_distribution_function(
         rdf.bin_centers, rdf.rdf, xlabel="Distance (Å)", ylabel="g(r)", title="Radial Distribution Function (RDF)"
     )

     if is_pyodide:
         import matplotlib.pyplot as plt

-        buf = io.BytesIO()
-        plt.savefig(buf, format="png")
-        buf.seek(0)
-        display(Image(buf.read()))
-        plt.close()
+        try:
+            buf = io.BytesIO()
+            fig.savefig(buf, format="png")
+            buf.seek(0)
+            display(Image(buf.read()))
+        finally:
+            plt.close(fig)

This assumes plot_distribution_function can be modified to return the figure. If not, the current approach should work as long as it's the only figure being created.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fd5551 and 5612a98.

📒 Files selected for processing (1)
  • utils/plot.py
🧰 Additional context used
🧬 Code graph analysis (1)
utils/plot.py (1)
other/generate_gifs/utils/gif_processor.py (1)
  • display (197-202)
🔇 Additional comments (1)
utils/plot.py (1)

67-68: LGTM! PEP 8 formatting improvement.

Adding spaces around the + operator improves code style consistency.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
utils/plot.py (1)

67-68: Minor: Formatting changes unrelated to PR objective.

The spacing improvements around i + 1 are fine and improve readability, but these changes in plot_twisted_interface_solutions appear unrelated to the RDF plot fix mentioned in the PR objective.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5612a98 and 1d9469e.

📒 Files selected for processing (1)
  • utils/plot.py
🧰 Additional context used
🧬 Code graph analysis (1)
utils/plot.py (1)
other/generate_gifs/utils/gif_processor.py (1)
  • display (197-202)
🔇 Additional comments (2)
utils/plot.py (2)

1-2: LGTM! Imports support the Pyodide functionality.

The new imports (io, sys, IPython.display.Image, IPython.display.display, and matplotlib.pyplot) are all necessary for the Pyodide-aware plotting implementation and are correctly placed at the module level.

Also applies to: 5-5, 10-10


76-94: Well-structured Pyodide-aware plotting logic.

The implementation correctly addresses the previous review feedback by using plt.switch_backend("Agg") (which works at runtime) instead of matplotlib.use(). The flow is sound:

  • Pyodide path: switches to non-interactive Agg backend → creates plot → captures to BytesIO buffer → displays inline → cleans up
  • Non-Pyodide path: uses default backend → plot_distribution_function handles display (as confirmed in past comments)

The Pyodide detection via sys.platform == "emscripten" is the standard approach.

Optional verification: Test this in both Pyodide (JupyterLite) and standard Jupyter environments to confirm:

  1. The RDF plot renders correctly as an inline PNG in Pyodide
  2. The plot displays normally in non-Pyodide environments
  3. No matplotlib backend warnings appear in either environment
Optional refinement (explicit figure management)

For more explicit control, you could capture the figure reference instead of relying on implicit current-figure behavior:

if is_pyodide:
    buf = io.BytesIO()
    fig = plt.gcf()  # Get current figure explicitly
    fig.savefig(buf, format="png")
    buf.seek(0)
    display(Image(buf.read()))
    plt.close(fig)

This makes the code slightly more robust but isn't necessary given the current implementation works correctly.

@VsevolodX VsevolodX changed the title Fix/rdf plot Fix/rdf plot (SOF-7807) Dec 31, 2025
@VsevolodX VsevolodX merged commit 3155151 into main Dec 31, 2025
5 checks passed
@VsevolodX VsevolodX deleted the fix/rdf-plot branch December 31, 2025 05:51
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.

3 participants