Skip to content

feature: add interactive Plotly circuit visualization#1292

Open
spital wants to merge 1 commit into
amazon-braket:feature/graphical-visualizationfrom
spital:plotly-interactive-circuit-1250
Open

feature: add interactive Plotly circuit visualization#1292
spital wants to merge 1 commit into
amazon-braket:feature/graphical-visualizationfrom
spital:plotly-interactive-circuit-1250

Conversation

@spital

@spital spital commented Jun 7, 2026

Copy link
Copy Markdown

Summary

Closes #1250
(edited - would github link issue now?)

This adds PlotlyCircuitDiagram, an optional interactive renderer for Braket circuits. It reuses the graphical circuit layout used by the Matplotlib renderer and returns a plotly.graph_objects.Figure from Circuit.show("interactive") or Circuit.show("plotly"). The existing default Circuit.show() Matplotlib behavior is unchanged.

What changed

  • Added PlotlyCircuitDiagram under graphical_diagram_builders.
  • Added Circuit.show("interactive") / Circuit.show("plotly") aliases that return a Plotly figure.
  • Added hover text for gates, controls, swaps, barriers, result types, parameters, and optional caller-provided device metadata.
  • Added collapsed-by-default verbatim rendering with expand/collapse buttons implemented with Plotly updatemenus.
  • Added the amazon-braket-sdk[interactive] optional extra and lazy Plotly import handling.
  • Added a short usage example in examples/plotly_circuit_visualization.py.
  • Added unit coverage for rendering, hover text, verbatim toggling, result types, empty/global-phase circuits, and larger circuit serialization.

Correctness note

While wiring the global-phase footer into the renderers, I found that powered GPhase instructions were not reflected in the public Circuit.global_phase value: the current value used only the raw angle and ignored the instruction power. This PR updates the public value and the text/graphical footers to use the effective phase angle * power, matching the unitary behavior. Powered GPhase instructions are also suppressed as standalone gate boxes so they appear only in the global-phase footer.

Testing

After final formatting, I ran:

  • python -m pytest -p no:randomly test/unit_tests/braket/circuits/test_plotly_circuit_diagram.py -q
  • python -m pytest -p no:randomly test/unit_tests -q
  • ruff format --check .
  • ruff check src

AI assistance disclosure

I used AI assistants (Codex, Claude, and Hermes) to help draft and review parts of the renderer, tests, and PR text. I manually reviewed the implementation against #1250, refined the generated suggestions, and verified the final code locally with the tests and lint checks above.

Merge Checklist

General

Tests

  • I have added tests that prove my fix is effective or that my feature works (if appropriate)
  • I have checked that my tests are not configured for a specific region or account (if appropriate)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@spital

spital commented Jun 8, 2026

Copy link
Copy Markdown
Author

not linked, maybe a keyword fixes #1250 missing

@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.98681% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.83%. Comparing base (9dedb48) to head (742b747).

Files with missing lines Patch % Lines
...aphical_diagram_builders/plotly_circuit_diagram.py 94.72% 12 Missing and 5 partials ⚠️
...ical_diagram_builders/graphical_circuit_diagram.py 93.75% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@                         Coverage Diff                         @@
##           feature/graphical-visualization    #1292      +/-   ##
===================================================================
- Coverage                           100.00%   99.83%   -0.17%     
===================================================================
  Files                                  173      174       +1     
  Lines                                11375    11743     +368     
  Branches                              1472     1536      +64     
===================================================================
+ Hits                                 11375    11724     +349     
- Misses                                   0       13      +13     
- Partials                                 0        6       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@spital

spital commented Jun 9, 2026

Copy link
Copy Markdown
Author

thank you, I'll look into it

@spital spital force-pushed the plotly-interactive-circuit-1250 branch from 742b747 to 1242555 Compare June 10, 2026 07:44
@spital

spital commented Jun 10, 2026

Copy link
Copy Markdown
Author

Pushed a follow-up to bring patch coverage back to 100%.
I added 9 targeted unit tests.
Tested locally with:

source .venv/bin/activate
coverage erase
pytest test/unit_tests --cov=braket --cov-report=term-missing

pytest -p no:randomly -n0     test/unit_tests/braket/circuits/test_plotly_circuit_diagram.py     test/unit_tests/braket/circuits/test_matplotlib_circuit_diagram.py     test/unit_tests/braket/circuits/test_circuit.py     test/unit_tests/braket/circuits/test_ascii_circuit_diagram.py     test/unit_tests/braket/circuits/test_unicode_circuit_diagram.py     --cov=src/braket/circuits/graphical_diagram_builders     --cov-report=term-missing

ruff format --check .
ruff check src

@kawacukennedy

Copy link
Copy Markdown

Thanks for picking this up, @spital — I also have an implementation open in #1284 for the same issue, so it's good to compare approaches.

A few things that stood out in your PR:

Nice catches:

  • Fixing global_phase to use angle * power instead of just angle — that's a genuine correctness bug. I missed that in feat: add interactive Plotly circuit diagram visualization #1284, good find.
  • Suppressing powered GPhase as standalone gate boxes is a clean UX choice.
  • The text diagram builder updates (ascii/unicode) for GPhase consistency are thorough.

Design divergence worth discussing:

  • Your show() signature uses type | str union which requires Python 3.10+. The Braket SDK still supports 3.9 in its CI matrix — might need a TYPE_CHECKING guard or similar depending on how strict the pre-commit hooks are.
  • device_metadata as a Mapping is more flexible than a raw dict but callers typically pass a dict anyway — either works.

I'd suggest the maintainers (@speller26 @krneta) compare #1284 and #1292 side by side. They overlap significantly but each has unique strengths — #1284 is lighter (~68 tests, minimal base-class changes), #1292 is more comprehensive (GPhase fix, text-diagram consistency, 426 tests). Might be worth cherry-picking the best parts of both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants