Skip to content

feature/SOF-7947 ZPE NB#341

Open
VsevolodX wants to merge 2 commits into
feature/SOF-7948from
feature/SOF-7947
Open

feature/SOF-7947 ZPE NB#341
VsevolodX wants to merge 2 commits into
feature/SOF-7948from
feature/SOF-7947

Conversation

@VsevolodX

@VsevolodX VsevolodX commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Added notebooks for creating solid solutions, analyzing phase stability, and running zero-point energy workflows.
    • Introduced interactive convex-hull results and visualization support for materials stability analysis.
  • Documentation
    • Updated the workflows introduction to include direct links to several completed calculations and renamed the formation energy section to phase stability.
  • Bug Fixes
    • Results tables now show stability, decomposition products, and energy-above-hull details for easier comparison.

@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@VsevolodX VsevolodX changed the base branch from main to feature/SOF-7948 July 2, 2026 18:06
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5fda283c-eff3-4a47-a86d-cf699ef7cc18

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds three new Jupyter notebooks for materials-designer workflows (solid solution creation, convex hull/phase stability analysis, and zero-point energy DFT phonon workflow), two new Python modules for phase stability analysis and convex hull plotting, and updates link references in the Introduction notebook.

Changes

Solid Solution Notebook

Layer / File(s) Summary
Notebook setup and parameters
other/materials_designer/create_solid_solution.ipynb
Adds intro markdown, configurable parameters (source/target element, concentration, site selection, seed, tolerance), package installation, and material loading.
Solid solution generation and reporting
other/materials_designer/create_solid_solution.ipynb
Calls create_solid_solution, computes composition/target-fraction, and prints results.
Visualization and export
other/materials_designer/create_solid_solution.ipynb
Visualizes the result and exports it via set_materials, plus notebook metadata.

Phase Stability / Convex Hull Analysis

Layer / File(s) Summary
Convex hull core library
src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py
Adds PhaseStabilityEntry, build_convex_hull, and get_results_table for pymatgen-based phase diagram construction and stability reporting.
Convex hull plotting library
src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py
Adds plot_convex_hull and TEXT_SHADOW, restyling PDPlotter figures with a dark theme.
Notebook setup and authentication
other/materials_designer/workflows/analyze_convex_hull.ipynb
Adds intro, package installation, search parameters, and API authentication/account selection.
Material discovery and energy retrieval
other/materials_designer/workflows/analyze_convex_hull.ipynb
Resolves material sets, searches by formula, retrieves and deduplicates total_energy properties, and builds entries_data.
Hull construction, results table, and plotting
other/materials_designer/workflows/analyze_convex_hull.ipynb
Builds the phase diagram, displays results table, renders interactive plot, and includes metadata.

Zero-Point Energy Workflow Notebook

Layer / File(s) Summary
Notebook intro, parameters, and package setup
other/materials_designer/workflows/zero_point_energy.ipynb
Adds intro markdown, package installation, and configuration parameters.
Authentication and material setup
other/materials_designer/workflows/zero_point_energy.ipynb
Authenticates, initializes API client, selects account/project, loads and saves material.
Workflow creation and modification pipeline
other/materials_designer/workflows/zero_point_energy.ipynb
Loads standard workflow, applies optional relaxation/model/k-grid modifications, and saves it.
Compute configuration and job submission
other/materials_designer/workflows/zero_point_energy.ipynb
Creates compute config, assembles/submits job, and awaits completion.
Result retrieval and metadata
other/materials_designer/workflows/zero_point_energy.ipynb
Fetches and visualizes ZPE and total energy properties, plus notebook metadata.

Introduction Notebook Link Updates

Layer / File(s) Summary
Calculations contents links update
other/materials_designer/workflows/Introduction.ipynb
Replaces placeholders with links to band structure (magnetic), surface energy, zero-point energy, and phase stability/compound formation energy notebooks.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Notebook as analyze_convex_hull.ipynb
    participant API as Mat3ra API
    participant Analysis as analysis.py
    participant Plot as plot.py

    User->>Notebook: Set FORMULAS, GROUP, PRECISION
    Notebook->>API: Authenticate and select account
    Notebook->>API: Search materials by formula
    API-->>Notebook: Matched materials
    Notebook->>API: Query total_energy properties
    API-->>Notebook: Energy data per material
    Notebook->>Notebook: Build entries_data (composition, atom count, energy)
    Notebook->>Analysis: build_convex_hull(entries_data)
    Analysis-->>Notebook: PhaseDiagram
    Notebook->>Analysis: get_results_table(phase_diagram, entries_data)
    Analysis-->>Notebook: DataFrame of stability results
    Notebook->>Plot: plot_convex_hull(phase_diagram)
    Plot-->>Notebook: Styled Plotly figure
    Notebook-->>User: Display results table and interactive plot
Loading
sequenceDiagram
    participant User
    participant Notebook as zero_point_energy.ipynb
    participant API as Mat3ra API
    participant Cluster as Compute Cluster

    User->>Notebook: Set material, workflow, and compute parameters
    Notebook->>API: Authenticate and select account/project
    Notebook->>Notebook: Load material and visualize
    Notebook->>API: Save/create material
    Notebook->>API: Load workflow from Standata
    Notebook->>Notebook: Modify workflow (relaxation, model, k-grids)
    Notebook->>API: Save/create workflow
    Notebook->>API: List clusters and create compute config
    Notebook->>API: Create job (material, workflow, project, compute)
    Notebook->>Cluster: Submit job
    Notebook->>API: Poll job status asynchronously
    Cluster-->>API: Job completion
    Notebook->>API: Fetch ZPE and total energy properties
    Notebook-->>User: Visualize results
Loading

Suggested reviewers: timurbazhirov

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is mostly a branch/task label and only loosely describes the notebook-focused changes. Rename it to a clear change summary, such as "Add zero-point energy and convex hull notebooks".
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/SOF-7947

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (7)
src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py (1)

26-27: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Silent skip when hovertext missing.

Traces without hovertext are skipped entirely (no text/textfont styling applied), which means such points may render with default (possibly hard-to-read) styling against the dark theme rather than a fallback. Low risk given current PDPlotter always emits hovertext, but worth a defensive fallback if this changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py` around lines
26 - 27, The hover-text guard in the plot styling logic is too strict and skips
traces entirely when hovertext is absent, leaving them unstyled. Update the
trace-processing path in the plot helper to use a defensive fallback for traces
without hovertext so `text`/`textfont` styling still gets applied, keeping the
behavior aligned with the existing `PDPlotter` flow and the trace styling code.
src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py (2)

50-55: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Positional pairing between entries_data and phase_diagram.all_entries is unvalidated.

get_results_table assumes entries_data[i] corresponds to phase_diagram.all_entries[i] in the same order used to build the hull. There's no length check or explicit ID-based matching; if a caller passes a different entries_data list (or pymatgen reorders/dedupes entries internally), rows would silently show wrong Material ID/metadata paired with the wrong energetics.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py` around lines
50 - 55, The pairing logic in get_results_table assumes entries_data and
phase_diagram.all_entries stay in the same order, which can silently mismatch
Material IDs and metadata. Update the function to validate that the two
collections align before iterating, or match each phase_diagram entry to its
corresponding entries_data item using a stable identifier from the entry/data
objects instead of list position. Keep the existing results loop in
get_results_table, but add a guard or lookup step around
phase_diagram.all_entries, entries_data, and the per-row data assignment.

63-64: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Magic threshold 1e-6 duplicated.

Consider extracting 1e-6 into a named constant (e.g., STABILITY_TOLERANCE) for clarity and single source of truth.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py` around lines
63 - 64, The stability check in the property analysis mapping uses the same 1e-6
threshold twice, so extract it into a single named constant such as
STABILITY_TOLERANCE near the logic in the analysis function. Update both the
“Stable” and “Decomposes to” conditions to reference that constant so the
threshold has one source of truth and the intent is clearer.
other/materials_designer/workflows/zero_point_energy.ipynb (1)

384-386: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant ADD_RELAXATION ternary.

Line 384 already guards on ... and ADD_RELAXATION, so if ADD_RELAXATION else None on line 386 is always the truthy branch and can be simplified.

♻️ Simplify
-    new_context_relax = PointsGridDataProvider(dimensions=RELAXATION_KGRID,
-                                               isEdited=True).get_context_item_data() if ADD_RELAXATION else None
+    new_context_relax = PointsGridDataProvider(dimensions=RELAXATION_KGRID,
+                                               isEdited=True).get_context_item_data()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/zero_point_energy.ipynb` around lines 384
- 386, Simplify the relaxation context setup by removing the redundant
conditional in the zero_point_energy notebook snippet: the surrounding guard
already checks RELAXATION_KGRID is not None and ADD_RELAXATION, so the
expression assigned to new_context_relax should directly use
PointsGridDataProvider(...).get_context_item_data() without an extra “if
ADD_RELAXATION else None” branch. Update the logic near the ADD_RELAXATION check
so the assignment is consistent with the existing guard and keeps the code
easier to read.
other/materials_designer/workflows/analyze_convex_hull.ipynb (3)

306-307: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Blanket warning suppression may hide legitimate hull-construction issues.

warnings.filterwarnings("ignore") suppresses all warnings for the rest of the kernel session, including potentially important pymatgen warnings (e.g. incomplete phase space, entries excluded from the hull). Consider scoping suppression to a specific category/module instead of a global blanket ignore.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/analyze_convex_hull.ipynb` around lines
306 - 307, The notebook currently uses a global warnings ignore that can hide
important convex-hull and pymatgen issues. Update the warning handling in the
analyze_convex_hull workflow so it is scoped to the specific warning category or
module instead of calling warnings.filterwarnings("ignore") broadly. Keep the
change near the existing warnings import/use so the rest of the kernel session
is not silenced.

279-280: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Inconsistent defensive access vs. the preview cell.

The preview cell (lines 211-212) reads material.get("basis", {}).get("coordinates", []) defensively, but this cell indexes directly with material["basis"]["elements"] and material["basis"]["coordinates"]. If any material in all_materials lacks a basis key, this will raise an unhandled KeyError and abort the notebook mid-run instead of failing gracefully or reporting which material is malformed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/analyze_convex_hull.ipynb` around lines
279 - 280, The access pattern in the material-processing cell is inconsistent
with the defensive preview logic and can raise a KeyError when a material lacks
basis data. Update the notebook cell that reads material["basis"]["elements"]
and material["basis"]["coordinates"] to use the same safe get-based approach as
the preview cell, ideally inside the loop over all_materials, and handle missing
or malformed basis data gracefully while preserving the material context for any
warning or skip.

236-277: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Materials missing exabyteId are silently dropped with no feedback.

Materials without an exabyteId (line 270) are skipped silently, while materials with an exabyteId but no matching total-energy property do get a warning (⚠️ ... no total energy, line 276). If several materials from the search lack exabyteId (e.g. never sent to a job), the user gets no indication why entries_data ends up small or empty, making downstream failures in build_convex_hull harder to diagnose.

🩹 Proposed fix
 for material in all_materials:
     exabyte_id = material.get("exabyteId")
-    if not exabyte_id or exabyte_id in seen_exabyte_ids:
+    if not exabyte_id:
+        print(f"⚠️  {material['formula']}: no exabyteId (never submitted to a job)")
+        continue
+    if exabyte_id in seen_exabyte_ids:
         continue
     seen_exabyte_ids.add(exabyte_id)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/analyze_convex_hull.ipynb` around lines
236 - 277, Materials without an exabyteId are being skipped silently in the
entries collection loop, which makes it hard to understand why entries_data is
smaller than expected. In the notebook cell that builds entries_data, update the
loop around all_materials to explicitly detect missing exabyteId values and
print a warning similar to the existing “no total energy” message. Use the same
material iteration logic and the seen_exabyte_ids check, but add a clear notice
before continuing so users can distinguish missing exabyteId cases from missing
property cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@other/materials_designer/workflows/Introduction.ipynb`:
- Around line 78-79: Remove the stale Formation Energy section placeholder from
the notebook’s introduction content so it no longer appears as a separate
navigation entry. Update the relevant markdown cells in Introduction.ipynb to
drop the `6.7. Formation Energy` heading and its `Compound formation energy`
subheading, since `Phase Stability` now covers that material. Keep the
surrounding section numbering consistent with the rest of the notebook and
ensure no duplicate TOC entry remains.
- Around line 75-76: The Introduction notebook TOC points to
generate_phase_diagram.ipynb, but that target is missing, so fix the broken link
by either adding the missing notebook or updating the entry to point to the
correct existing notebook. Check the table-of-contents entry in
Introduction.ipynb and the related workflow notebook names to ensure the phase
diagram section links to a valid target.

In `@other/materials_designer/workflows/zero_point_energy.ipynb`:
- Around line 334-335: The 4.3.2 note in zero_point_energy.ipynb is inconsistent
with the following model/method cell, which is currently active and runs by
default. Update the notebook so the instruction matches the implementation:
either comment out or otherwise gate the referenced model/method setup cell, or
revise the markdown text to state that the parameters are applied automatically.
Use the surrounding 4.3.2 markdown and the adjacent model/method cell to keep
the optional behavior clear.
- Around line 466-476: The cluster selection logic in the notebook can leave
cluster as None when CLUSTER_NAME does not match any entry, or crash with
IndexError when clusters is empty; add an explicit validation before
constructing Compute. Update the cluster-selection block that uses CLUSTER_NAME,
clusters, and Compute so it checks for an empty clusters list and for a failed
hostname match, then fail fast with a clear message instead of letting
compute.cluster.hostname blow up later.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py`:
- Line 39: The Plotly text styling in plot.py uses trace.textfont.shadow, but
the current dependency floor still allows versions that do not support this
property. Update the compatibility by either raising the Plotly minimum version
requirement to 5.23+ or removing the shadow entry from the textfont dict in the
code that builds the trace.
- Around line 25-33: The label generation in the hover-text processing loop is
relying on the rendered string format from PDPlotter, which is brittle. Update
the logic in the figure/trace handling code that iterates over fig.data to
derive formula and energy/status from structured phase-diagram data or trace
metadata instead of splitting trace.hovertext. Use the relevant trace attributes
or source data passed into the plotting function to build labels directly, so
the display does not depend on pymatgen’s internal hover-text layout.

---

Nitpick comments:
In `@other/materials_designer/workflows/analyze_convex_hull.ipynb`:
- Around line 306-307: The notebook currently uses a global warnings ignore that
can hide important convex-hull and pymatgen issues. Update the warning handling
in the analyze_convex_hull workflow so it is scoped to the specific warning
category or module instead of calling warnings.filterwarnings("ignore") broadly.
Keep the change near the existing warnings import/use so the rest of the kernel
session is not silenced.
- Around line 279-280: The access pattern in the material-processing cell is
inconsistent with the defensive preview logic and can raise a KeyError when a
material lacks basis data. Update the notebook cell that reads
material["basis"]["elements"] and material["basis"]["coordinates"] to use the
same safe get-based approach as the preview cell, ideally inside the loop over
all_materials, and handle missing or malformed basis data gracefully while
preserving the material context for any warning or skip.
- Around line 236-277: Materials without an exabyteId are being skipped silently
in the entries collection loop, which makes it hard to understand why
entries_data is smaller than expected. In the notebook cell that builds
entries_data, update the loop around all_materials to explicitly detect missing
exabyteId values and print a warning similar to the existing “no total energy”
message. Use the same material iteration logic and the seen_exabyte_ids check,
but add a clear notice before continuing so users can distinguish missing
exabyteId cases from missing property cases.

In `@other/materials_designer/workflows/zero_point_energy.ipynb`:
- Around line 384-386: Simplify the relaxation context setup by removing the
redundant conditional in the zero_point_energy notebook snippet: the surrounding
guard already checks RELAXATION_KGRID is not None and ADD_RELAXATION, so the
expression assigned to new_context_relax should directly use
PointsGridDataProvider(...).get_context_item_data() without an extra “if
ADD_RELAXATION else None” branch. Update the logic near the ADD_RELAXATION check
so the assignment is consistent with the existing guard and keeps the code
easier to read.

In `@src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py`:
- Around line 50-55: The pairing logic in get_results_table assumes entries_data
and phase_diagram.all_entries stay in the same order, which can silently
mismatch Material IDs and metadata. Update the function to validate that the two
collections align before iterating, or match each phase_diagram entry to its
corresponding entries_data item using a stable identifier from the entry/data
objects instead of list position. Keep the existing results loop in
get_results_table, but add a guard or lookup step around
phase_diagram.all_entries, entries_data, and the per-row data assignment.
- Around line 63-64: The stability check in the property analysis mapping uses
the same 1e-6 threshold twice, so extract it into a single named constant such
as STABILITY_TOLERANCE near the logic in the analysis function. Update both the
“Stable” and “Decomposes to” conditions to reference that constant so the
threshold has one source of truth and the intent is clearer.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py`:
- Around line 26-27: The hover-text guard in the plot styling logic is too
strict and skips traces entirely when hovertext is absent, leaving them
unstyled. Update the trace-processing path in the plot helper to use a defensive
fallback for traces without hovertext so `text`/`textfont` styling still gets
applied, keeping the behavior aligned with the existing `PDPlotter` flow and the
trace styling code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b381a712-8351-4402-8320-c0191ef5b56d

📥 Commits

Reviewing files that changed from the base of the PR and between d6bd60c and b3e2e27.

📒 Files selected for processing (6)
  • other/materials_designer/create_solid_solution.ipynb
  • other/materials_designer/workflows/Introduction.ipynb
  • other/materials_designer/workflows/analyze_convex_hull.ipynb
  • other/materials_designer/workflows/zero_point_energy.ipynb
  • src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py
  • src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 6

🧹 Nitpick comments (7)
src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py (1)

26-27: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Silent skip when hovertext missing.

Traces without hovertext are skipped entirely (no text/textfont styling applied), which means such points may render with default (possibly hard-to-read) styling against the dark theme rather than a fallback. Low risk given current PDPlotter always emits hovertext, but worth a defensive fallback if this changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py` around lines
26 - 27, The hover-text guard in the plot styling logic is too strict and skips
traces entirely when hovertext is absent, leaving them unstyled. Update the
trace-processing path in the plot helper to use a defensive fallback for traces
without hovertext so `text`/`textfont` styling still gets applied, keeping the
behavior aligned with the existing `PDPlotter` flow and the trace styling code.
src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py (2)

50-55: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Positional pairing between entries_data and phase_diagram.all_entries is unvalidated.

get_results_table assumes entries_data[i] corresponds to phase_diagram.all_entries[i] in the same order used to build the hull. There's no length check or explicit ID-based matching; if a caller passes a different entries_data list (or pymatgen reorders/dedupes entries internally), rows would silently show wrong Material ID/metadata paired with the wrong energetics.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py` around lines
50 - 55, The pairing logic in get_results_table assumes entries_data and
phase_diagram.all_entries stay in the same order, which can silently mismatch
Material IDs and metadata. Update the function to validate that the two
collections align before iterating, or match each phase_diagram entry to its
corresponding entries_data item using a stable identifier from the entry/data
objects instead of list position. Keep the existing results loop in
get_results_table, but add a guard or lookup step around
phase_diagram.all_entries, entries_data, and the per-row data assignment.

63-64: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Magic threshold 1e-6 duplicated.

Consider extracting 1e-6 into a named constant (e.g., STABILITY_TOLERANCE) for clarity and single source of truth.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py` around lines
63 - 64, The stability check in the property analysis mapping uses the same 1e-6
threshold twice, so extract it into a single named constant such as
STABILITY_TOLERANCE near the logic in the analysis function. Update both the
“Stable” and “Decomposes to” conditions to reference that constant so the
threshold has one source of truth and the intent is clearer.
other/materials_designer/workflows/zero_point_energy.ipynb (1)

384-386: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant ADD_RELAXATION ternary.

Line 384 already guards on ... and ADD_RELAXATION, so if ADD_RELAXATION else None on line 386 is always the truthy branch and can be simplified.

♻️ Simplify
-    new_context_relax = PointsGridDataProvider(dimensions=RELAXATION_KGRID,
-                                               isEdited=True).get_context_item_data() if ADD_RELAXATION else None
+    new_context_relax = PointsGridDataProvider(dimensions=RELAXATION_KGRID,
+                                               isEdited=True).get_context_item_data()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/zero_point_energy.ipynb` around lines 384
- 386, Simplify the relaxation context setup by removing the redundant
conditional in the zero_point_energy notebook snippet: the surrounding guard
already checks RELAXATION_KGRID is not None and ADD_RELAXATION, so the
expression assigned to new_context_relax should directly use
PointsGridDataProvider(...).get_context_item_data() without an extra “if
ADD_RELAXATION else None” branch. Update the logic near the ADD_RELAXATION check
so the assignment is consistent with the existing guard and keeps the code
easier to read.
other/materials_designer/workflows/analyze_convex_hull.ipynb (3)

306-307: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Blanket warning suppression may hide legitimate hull-construction issues.

warnings.filterwarnings("ignore") suppresses all warnings for the rest of the kernel session, including potentially important pymatgen warnings (e.g. incomplete phase space, entries excluded from the hull). Consider scoping suppression to a specific category/module instead of a global blanket ignore.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/analyze_convex_hull.ipynb` around lines
306 - 307, The notebook currently uses a global warnings ignore that can hide
important convex-hull and pymatgen issues. Update the warning handling in the
analyze_convex_hull workflow so it is scoped to the specific warning category or
module instead of calling warnings.filterwarnings("ignore") broadly. Keep the
change near the existing warnings import/use so the rest of the kernel session
is not silenced.

279-280: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Inconsistent defensive access vs. the preview cell.

The preview cell (lines 211-212) reads material.get("basis", {}).get("coordinates", []) defensively, but this cell indexes directly with material["basis"]["elements"] and material["basis"]["coordinates"]. If any material in all_materials lacks a basis key, this will raise an unhandled KeyError and abort the notebook mid-run instead of failing gracefully or reporting which material is malformed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/analyze_convex_hull.ipynb` around lines
279 - 280, The access pattern in the material-processing cell is inconsistent
with the defensive preview logic and can raise a KeyError when a material lacks
basis data. Update the notebook cell that reads material["basis"]["elements"]
and material["basis"]["coordinates"] to use the same safe get-based approach as
the preview cell, ideally inside the loop over all_materials, and handle missing
or malformed basis data gracefully while preserving the material context for any
warning or skip.

236-277: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Materials missing exabyteId are silently dropped with no feedback.

Materials without an exabyteId (line 270) are skipped silently, while materials with an exabyteId but no matching total-energy property do get a warning (⚠️ ... no total energy, line 276). If several materials from the search lack exabyteId (e.g. never sent to a job), the user gets no indication why entries_data ends up small or empty, making downstream failures in build_convex_hull harder to diagnose.

🩹 Proposed fix
 for material in all_materials:
     exabyte_id = material.get("exabyteId")
-    if not exabyte_id or exabyte_id in seen_exabyte_ids:
+    if not exabyte_id:
+        print(f"⚠️  {material['formula']}: no exabyteId (never submitted to a job)")
+        continue
+    if exabyte_id in seen_exabyte_ids:
         continue
     seen_exabyte_ids.add(exabyte_id)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/analyze_convex_hull.ipynb` around lines
236 - 277, Materials without an exabyteId are being skipped silently in the
entries collection loop, which makes it hard to understand why entries_data is
smaller than expected. In the notebook cell that builds entries_data, update the
loop around all_materials to explicitly detect missing exabyteId values and
print a warning similar to the existing “no total energy” message. Use the same
material iteration logic and the seen_exabyte_ids check, but add a clear notice
before continuing so users can distinguish missing exabyteId cases from missing
property cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@other/materials_designer/workflows/Introduction.ipynb`:
- Around line 78-79: Remove the stale Formation Energy section placeholder from
the notebook’s introduction content so it no longer appears as a separate
navigation entry. Update the relevant markdown cells in Introduction.ipynb to
drop the `6.7. Formation Energy` heading and its `Compound formation energy`
subheading, since `Phase Stability` now covers that material. Keep the
surrounding section numbering consistent with the rest of the notebook and
ensure no duplicate TOC entry remains.
- Around line 75-76: The Introduction notebook TOC points to
generate_phase_diagram.ipynb, but that target is missing, so fix the broken link
by either adding the missing notebook or updating the entry to point to the
correct existing notebook. Check the table-of-contents entry in
Introduction.ipynb and the related workflow notebook names to ensure the phase
diagram section links to a valid target.

In `@other/materials_designer/workflows/zero_point_energy.ipynb`:
- Around line 334-335: The 4.3.2 note in zero_point_energy.ipynb is inconsistent
with the following model/method cell, which is currently active and runs by
default. Update the notebook so the instruction matches the implementation:
either comment out or otherwise gate the referenced model/method setup cell, or
revise the markdown text to state that the parameters are applied automatically.
Use the surrounding 4.3.2 markdown and the adjacent model/method cell to keep
the optional behavior clear.
- Around line 466-476: The cluster selection logic in the notebook can leave
cluster as None when CLUSTER_NAME does not match any entry, or crash with
IndexError when clusters is empty; add an explicit validation before
constructing Compute. Update the cluster-selection block that uses CLUSTER_NAME,
clusters, and Compute so it checks for an empty clusters list and for a failed
hostname match, then fail fast with a clear message instead of letting
compute.cluster.hostname blow up later.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py`:
- Line 39: The Plotly text styling in plot.py uses trace.textfont.shadow, but
the current dependency floor still allows versions that do not support this
property. Update the compatibility by either raising the Plotly minimum version
requirement to 5.23+ or removing the shadow entry from the textfont dict in the
code that builds the trace.
- Around line 25-33: The label generation in the hover-text processing loop is
relying on the rendered string format from PDPlotter, which is brittle. Update
the logic in the figure/trace handling code that iterates over fig.data to
derive formula and energy/status from structured phase-diagram data or trace
metadata instead of splitting trace.hovertext. Use the relevant trace attributes
or source data passed into the plotting function to build labels directly, so
the display does not depend on pymatgen’s internal hover-text layout.

---

Nitpick comments:
In `@other/materials_designer/workflows/analyze_convex_hull.ipynb`:
- Around line 306-307: The notebook currently uses a global warnings ignore that
can hide important convex-hull and pymatgen issues. Update the warning handling
in the analyze_convex_hull workflow so it is scoped to the specific warning
category or module instead of calling warnings.filterwarnings("ignore") broadly.
Keep the change near the existing warnings import/use so the rest of the kernel
session is not silenced.
- Around line 279-280: The access pattern in the material-processing cell is
inconsistent with the defensive preview logic and can raise a KeyError when a
material lacks basis data. Update the notebook cell that reads
material["basis"]["elements"] and material["basis"]["coordinates"] to use the
same safe get-based approach as the preview cell, ideally inside the loop over
all_materials, and handle missing or malformed basis data gracefully while
preserving the material context for any warning or skip.
- Around line 236-277: Materials without an exabyteId are being skipped silently
in the entries collection loop, which makes it hard to understand why
entries_data is smaller than expected. In the notebook cell that builds
entries_data, update the loop around all_materials to explicitly detect missing
exabyteId values and print a warning similar to the existing “no total energy”
message. Use the same material iteration logic and the seen_exabyte_ids check,
but add a clear notice before continuing so users can distinguish missing
exabyteId cases from missing property cases.

In `@other/materials_designer/workflows/zero_point_energy.ipynb`:
- Around line 384-386: Simplify the relaxation context setup by removing the
redundant conditional in the zero_point_energy notebook snippet: the surrounding
guard already checks RELAXATION_KGRID is not None and ADD_RELAXATION, so the
expression assigned to new_context_relax should directly use
PointsGridDataProvider(...).get_context_item_data() without an extra “if
ADD_RELAXATION else None” branch. Update the logic near the ADD_RELAXATION check
so the assignment is consistent with the existing guard and keeps the code
easier to read.

In `@src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py`:
- Around line 50-55: The pairing logic in get_results_table assumes entries_data
and phase_diagram.all_entries stay in the same order, which can silently
mismatch Material IDs and metadata. Update the function to validate that the two
collections align before iterating, or match each phase_diagram entry to its
corresponding entries_data item using a stable identifier from the entry/data
objects instead of list position. Keep the existing results loop in
get_results_table, but add a guard or lookup step around
phase_diagram.all_entries, entries_data, and the per-row data assignment.
- Around line 63-64: The stability check in the property analysis mapping uses
the same 1e-6 threshold twice, so extract it into a single named constant such
as STABILITY_TOLERANCE near the logic in the analysis function. Update both the
“Stable” and “Decomposes to” conditions to reference that constant so the
threshold has one source of truth and the intent is clearer.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py`:
- Around line 26-27: The hover-text guard in the plot styling logic is too
strict and skips traces entirely when hovertext is absent, leaving them
unstyled. Update the trace-processing path in the plot helper to use a defensive
fallback for traces without hovertext so `text`/`textfont` styling still gets
applied, keeping the behavior aligned with the existing `PDPlotter` flow and the
trace styling code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b381a712-8351-4402-8320-c0191ef5b56d

📥 Commits

Reviewing files that changed from the base of the PR and between d6bd60c and b3e2e27.

📒 Files selected for processing (6)
  • other/materials_designer/create_solid_solution.ipynb
  • other/materials_designer/workflows/Introduction.ipynb
  • other/materials_designer/workflows/analyze_convex_hull.ipynb
  • other/materials_designer/workflows/zero_point_energy.ipynb
  • src/py/mat3ra/notebooks_utils/core/entity/property/analysis.py
  • src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py
🛑 Comments failed to post (6)
other/materials_designer/workflows/Introduction.ipynb (2)

75-76: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -a 'generate_phase_diagram.ipynb' other/materials_designer/workflows

Repository: mat3ra/api-examples

Length of output: 157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check whether the target notebook exists anywhere in the repo.
fd -a 'generate_phase_diagram.ipynb' .

# Inspect nearby workflow notebooks and references to the target.
rg -n "generate_phase_diagram\.ipynb|Phase Diagram" other/materials_designer/workflows -S

# Show the relevant section of the introduction notebook.
python3 - <<'PY'
from pathlib import Path
p = Path('other/materials_designer/workflows/Introduction.ipynb')
data = p.read_text()
for i, line in enumerate(data.splitlines(), 1):
    if 'generate_phase_diagram.ipynb' in line or 'Phase Diagram' in line or 'Formation Energies and Convex Hull' in line:
        print(f"{i}: {line}")
PY

Repository: mat3ra/api-examples

Length of output: 444


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all notebooks in the workflows area to see whether the TOC points to a matching file name.
fd -a -e ipynb other/materials_designer/workflows

# Show any references to the exact notebook name across the repo.
rg -n "generate_phase_diagram\.ipynb" .

Repository: mat3ra/api-examples

Length of output: 599


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect repository paths that might use a different casing or spelling for the phase diagram notebook.
fd -a -i 'phase.*diagram.*ipynb' other/materials_designer

Repository: mat3ra/api-examples

Length of output: 157


Add the missing phase diagram notebook target. other/materials_designer/workflows/Introduction.ipynb:76 links to generate_phase_diagram.ipynb, but that file is absent from other/materials_designer/workflows, so the TOC entry will be broken unless the notebook is added or the link is updated.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/Introduction.ipynb` around lines 75 - 76,
The Introduction notebook TOC points to generate_phase_diagram.ipynb, but that
target is missing, so fix the broken link by either adding the missing notebook
or updating the entry to point to the correct existing notebook. Check the
table-of-contents entry in Introduction.ipynb and the related workflow notebook
names to ensure the phase diagram section links to a valid target.

78-79: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the stale Formation Energy heading.

Phase Stability already covers the formation-energy / convex-hull material. Keeping a separate 6.7. Formation Energy placeholder leaves duplicate navigation and conflicts with the rename in this update.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/Introduction.ipynb` around lines 78 - 79,
Remove the stale Formation Energy section placeholder from the notebook’s
introduction content so it no longer appears as a separate navigation entry.
Update the relevant markdown cells in Introduction.ipynb to drop the `6.7.
Formation Energy` heading and its `Compound formation energy` subheading, since
`Phase Stability` now covers that material. Keep the surrounding section
numbering consistent with the rest of the notebook and ensure no duplicate TOC
entry remains.
other/materials_designer/workflows/zero_point_energy.ipynb (2)

334-335: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Markdown says "Uncomment the code below," but the code cell is active.

The instruction in 4.3.2 implies the following model/method cell is commented out, but it runs unconditionally. Either comment out the code (to make it truly optional) or update the markdown to reflect that it executes by default.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/zero_point_energy.ipynb` around lines 334
- 335, The 4.3.2 note in zero_point_energy.ipynb is inconsistent with the
following model/method cell, which is currently active and runs by default.
Update the notebook so the instruction matches the implementation: either
comment out or otherwise gate the referenced model/method setup cell, or revise
the markdown text to state that the parameters are applied automatically. Use
the surrounding 4.3.2 markdown and the adjacent model/method cell to keep the
optional behavior clear.

466-476: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Guard against empty/unmatched cluster selection.

If CLUSTER_NAME is set but matches nothing, cluster becomes None; if clusters is empty, clusters[0] raises IndexError. Either path leads to a confusing failure at compute.cluster.hostname. Add an explicit check.

🛡️ Proposed guard
 if CLUSTER_NAME:
     cluster = next((c for c in clusters if CLUSTER_NAME in c["hostname"]), None)
+    if cluster is None:
+        raise ValueError(f"No cluster matching '{CLUSTER_NAME}' found in {[c['hostname'] for c in clusters]}")
 else:
+    if not clusters:
+        raise ValueError("No clusters available for the selected account.")
     cluster = clusters[0]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    "if CLUSTER_NAME:\n",
    "    cluster = next((c for c in clusters if CLUSTER_NAME in c[\"hostname\"]), None)\n",
    "    if cluster is None:\n",
    "        raise ValueError(f\"No cluster matching '{CLUSTER_NAME}' found in {[c['hostname'] for c in clusters]}\")\n",
    "else:\n",
    "    if not clusters:\n",
    "        raise ValueError(\"No clusters available for the selected account.\")\n",
    "    cluster = clusters[0]\n",
    "\n",
    "compute = Compute(\n",
    "    cluster=cluster,\n",
    "    queue=QUEUE_NAME,\n",
    "    ppn=PPN\n",
    ")\n",
    "print(f\"Using cluster: {compute.cluster.hostname}, queue: {QUEUE_NAME}, ppn: {PPN}\")"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/zero_point_energy.ipynb` around lines 466
- 476, The cluster selection logic in the notebook can leave cluster as None
when CLUSTER_NAME does not match any entry, or crash with IndexError when
clusters is empty; add an explicit validation before constructing Compute.
Update the cluster-selection block that uses CLUSTER_NAME, clusters, and Compute
so it checks for an empty clusters list and for a failed hostname match, then
fail fast with a clear message instead of letting compute.cluster.hostname blow
up later.
src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py (2)

25-33: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does pymatgen PDPlotter hover text format for get_plot (plotly backend) remain stable across recent versions (2024+)?

💡 Result:

The hover text format in the pymatgen PDPlotter plotly backend is not strictly guaranteed to remain stable across versions, as it is subject to ongoing updates, feature enhancements, and bug fixes [1][2]. While there is no explicit policy guaranteeing long-term stability of the hover text string format, the underlying code for generating these plots has received multiple functional updates between 2024 and 2026 [1][3][4]. Key points regarding stability and changes since 2024: 1. Functional Updates and Bug Fixes: The plotting logic in PDPlotter has been actively maintained. For instance, recent changes have addressed how entries are selected and displayed (e.g., ensuring only lowest-energy unstable compositions are shown), which directly affects the content of the hover information [4][2]. 2. Dependency-Driven Changes: The plotly backend itself is sensitive to changes in the underlying plotly library. For example, recent versions of pymatgen (incorporating PR #4292) required updates to maintain compatibility with plotly v6, which involved refactoring layout properties [3][4]. Such changes can influence how visual elements, including hover labels, are rendered or configured [3]. 3. Nature of Implementation: The hover text is generated programmatically within the get_plot method [5]. Because this code is part of the library's active codebase, it is prone to modification when new features (like unary plots or 2D ternary support) are added or when existing rendering logic is refactored for better performance or correctness [1]. Users relying on parsing or automating the extraction of data from these hover tooltips should be aware that the exact string formatting or structure may change in future releases [1][2]. For critical workflows, it is recommended to pin the version of pymatgen used, or programmatically extract the underlying data directly from the PhaseDiagram object rather than relying on the plot's hover output [6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the reviewed file and nearby dependency pinning/config references.
git ls-files | rg '^src/py/mat3ra/notebooks_utils/ipython/entity/property/plot\.py$|(^|/)(pyproject\.toml|requirements.*|poetry\.lock|uv\.lock|Pipfile.lock|environment\.yml)$' || true

echo
echo "=== reviewed file ==="
cat -n src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py

echo
echo "=== pymatgen references ==="
rg -n "PDPlotter|pymatgen" src/py -S || true

Repository: mat3ra/api-examples

Length of output: 6560


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== pyproject pymatgen pin ==="
rg -n "pymatgen|plotly" pyproject.toml -n -S || true

echo
echo "=== pyproject snippet ==="
sed -n '1,220p' pyproject.toml

Repository: mat3ra/api-examples

Length of output: 3772


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

text = Path('src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py').read_text()
m = re.search(r'for hover_text in trace\.hovertext:(.*?)trace\.text = tuple\(labels\)', text, re.S)
print(m.group(1).strip() if m else "no match")
PY

Repository: mat3ra/api-examples

Length of output: 380


Avoid parsing PDPlotter hover strings for labels.
This relies on pymatgen’s internal hover-text layout, so a future update can silently change the displayed formula/energy text. Use structured phase-diagram data or trace metadata instead of splitting the rendered string.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py` around lines
25 - 33, The label generation in the hover-text processing loop is relying on
the rendered string format from PDPlotter, which is brittle. Update the logic in
the figure/trace handling code that iterates over fig.data to derive formula and
energy/status from structured phase-diagram data or trace metadata instead of
splitting trace.hovertext. Use the relevant trace attributes or source data
passed into the plotting function to build labels directly, so the display does
not depend on pymatgen’s internal hover-text layout.

39-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Plotly Python textfont shadow property support scatter trace

💡 Result:

Yes, Plotly for Python supports the shadow property within the textfont attribute for scatter traces [1][2]. This feature, introduced in Plotly 5.23, allows you to apply a shadow effect to text [1]. The shadow property functions similarly to the CSS text-shadow property [1][2]. You can define it within the textfont dictionary as follows [2]: import plotly.graph_objects as go fig = go.Figure( data=go.Scatter( x=[3][1], y=[3], mode="text", text=["Label A", "Label B", "Label C"], textfont=dict( shadow="1px 1px 2px black"))) The shadow property accepts string values defining the shadow's offset, blur radius, and color [3][2]. Additionally, a value of "auto" can be used to apply a minimal shadow with a contrasting font color automatically [3][4]. Note that while standard scatter traces support this property, support can vary for other trace types; for example, it has been reported as missing for some specialized map traces like Scattermap [5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== file context ==\n'
cat -n src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py | sed -n '1,120p'

printf '\n== plotly version references ==\n'
rg -n --hidden --glob '!**/.git/**' 'plotly|Plotly' pyproject.toml poetry.lock requirements*.txt setup.* src/py -g '!**/__pycache__/**' || true

printf '\n== around the relevant lines ==\n'
sed -n '25,55p' src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py

Repository: mat3ra/api-examples

Length of output: 6019


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== plotly scatter textfont docs references in repo, if any ==\n'
rg -n 'textfont.*shadow|shadow.*textfont|TEXT_SHADOW' src/py || true

printf '\n== dependency files mentioning plotly ==\n'
fd -a 'pyproject.toml|requirements*.txt|poetry.lock|Pipfile.lock|setup.cfg|setup.py' . 2>/dev/null | sed -n '1,20p'

Repository: mat3ra/api-examples

Length of output: 804


Plotly textfont.shadow needs a 5.23+ floor in src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py plotly>=5.18 still allows versions that don’t support textfont.shadow, so this can fail on the declared minimum. Either raise the dependency floor to 5.23+ or drop the shadow key.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/ipython/entity/property/plot.py` at line 39,
The Plotly text styling in plot.py uses trace.textfont.shadow, but the current
dependency floor still allows versions that do not support this property. Update
the compatibility by either raising the Plotly minimum version requirement to
5.23+ or removing the shadow entry from the textfont dict in the code that
builds the trace.

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.

1 participant