Metadata-Version: 2.5
Name: gatefold
Version: 1.0.0
Summary: Framework-agnostic quantum circuit diagram plotting with matplotlib
Project-URL: Homepage, https://github.com/alam-faisal/gatefold
Project-URL: Repository, https://github.com/alam-faisal/gatefold
Project-URL: Issues, https://github.com/alam-faisal/gatefold/issues
Author-email: Faisal Alam <qubitfaisal@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: circuit-diagram,matplotlib,quantum,quantum-computing,visualization
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.10
Requires-Dist: matplotlib>=3.7
Provides-Extra: dev
Requires-Dist: pytest; extra == 'dev'
Description-Content-Type: text/markdown

# gatefold

Quantum circuit diagram plotting that is:

- **Lightweight** — the only dependency is matplotlib. 
- **Adaptable** — gatefold can accept any circuit representation. Just write a small adapter converting your package's circuit objects into a `list[Layer]`.
- **Sleek** — a considered default palette, mathtext labels, auto-fit text, and clean packing.

```bash
pip install gatefold
# or
uv add gatefold
```

## Usage

`gatefold`'s whole vocabulary is `Item` (something drawn on one or more qubit
rows) grouped into `Layer`s (packed left-to-right, ASAP, with a barrier
between layers). 

Labels support matplotlib mathtext, e.g. `r"$Z_0 Z_1^\dagger$"`.
Runnable versions of the examples below are in
[`examples/examples.ipynb`](examples/examples.ipynb).

```python
from gatefold import Item, Layer, plot_circuit

layers = [
    Layer(items=[Item(("q0",), "H"), Item(("q1",), "H")]),
    Layer(items=[Item(("q0", "q1"), r"$e^{-i\theta Z_0 Z_1}$")]),
]
ax = plot_circuit(layers)
```

<br>

<img src="assets/example_basic.png" width="500">

<br>

Items can span more than two rows, and a `style` key looks up a `Palette`
entry to color-code gates (e.g. by arity):

```python
from gatefold import Item, Layer, plot_circuit, set_clean_rcparams

set_clean_rcparams()  # LaTeX-like typography, call once at import time

layers = [
    Layer(items=[Item(("q0",), "H", style="single"), Item(("q1",), "H", style="single")]),
    Layer(items=[Item(("q0", "q3"), r"$e^{-i\theta Z_0 Z_3}$")]),
    Layer(items=[Item(("q0",), "H", style="single"), Item(("q1", "q2"), "CNOT", style="multi")]),
    Layer(items=[Item(("q2",), r"$R_z(\phi)$", style="single")]),
]
ax = plot_circuit(layers, qubit_display={"q0": "$q_0$", "q1": "$q_1$", "q2": "$q_2$", "q3": "$q_3$"})
```

<br>

<img src="assets/example_layered.png" width="700">

<br>

## Writing an adapter

An adapter is a single function, `your_circuit ( + metadata) -> list[Layer]`. It's the
only place that needs to know about both your package and `gatefold`. This is what the adapter needs to do: 

- For each gate/term in the circuit you input, it must infer three things to construct an `Item`: which qubits the gate touches (`tuple`), a label (plain text or mathtext), and a `style` key. 
  
- Your package likely has methods to look up the first two properties from the gate/term objects the circuit is built from. If not, you need to pass metadata from which they can be inferred. 

- `style` is yours to define. `gatefold` just uses it to look up a
  `StyleSpec` in a `Palette` you can define. The `Palette` is a dictionary mapping the "types" of gates you want to the `StyleSpec` you want to decorate them with. For instance, you might want different styles for gates of different -arity, hardware-native vs. symbolic, etc. The adapter function must be able to infer these types and attach the appropriate style as the third argument of the `Item` class. 

- If your source representation has several sub-types (e.g. hardware gates vs.
  symbolic terms vs. encoded terms), each branch can have completely
  different internal logic captured in its own adapter function as long as every branch ends up emitting the
  same valid `list[Layer]`.

## Internals

[`ARCHITECTURE.md`](ARCHITECTURE.md) covers the module layout, the packing
algorithm, and how text auto-fit keeps large diagrams fast — worth a read
before changing the layout or drawing code.

## Versioning

Semantic versioning. The public API is the seven names re-exported from
`gatefold` — `Item`, `Layer`, `Palette`, `StyleSpec`, `DEFAULT_PALETTE`,
`plot_circuit`, `set_clean_rcparams` — and it will not break without a major
version bump. Everything in `gatefold.core` / `gatefold.style` is internal.
`plot_circuit`'s options are keyword-only, so new ones can be added without
breaking callers. Exact rendered output is not covered by this promise:
diagrams may change appearance in a minor release.

## License

MIT
