[Qiskit] 量子回路描画 QuantumCircuit.draw()の使い方

# はじめに
Qiskitでは、量子回路を視覚的に表現するために `QuantumCircuit.draw()` を使用できます。
本記事では、 `draw()` メソッドの使い方や、 output の違いによる出力の変化、スタイルのカスタマイズ方法を紹介します。ここで紹介するもの以外にも指定できるパラメータはあるので、詳細はドキュメントを参考にしてください。 

# 環境
```
qiskit == 1.3.2
matplotlib == 3.10.0
pylatexenc == 2.10 # 回路の書き出しの際にmplを用いるために必要
```

# `draw()`の基本的な使い方
適当な回路を用意します。
```python
from qiskit import QuantumCircuit

qc = QuantumCircuit(2, 2)
qc.h(0)  
qc.cx(0, 1)  
qc.measure([0, 1], [0, 1])  
``` 

## `output: str`
出力の形式を設定できます。
```python
# mplで表示。pylatxencライブラリが必要
qc.draw(output="mpl")  
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/d0131203-4cc3-4390-96b4-d5e14c3e83f6.png" width=50%>


```python
# textで表示
qc.draw(output="text") 
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/9e8ea150-2d39-48a7-bc99-7f4617318c2c.png" width=50%>

```python
# latexのsourceを表示
qc.draw(output="latex_source") 
```
> '\\documentclass[border=2px]{standalone}\n\n\\usepackage[braket, qm] ...

また、`output="latex"`でlatex形式で表示もできるようなのですが、私の環境ではうまく動きませんでした。
```python
# latexで表示
qc.draw(output="latex") 
```

## `scale: float`
出力する回路の大きさを設定できます。`< 1.0`で縮小、`> 1.0`で拡大です。
```python
# 1.5倍のスケールで表示
qc.draw(output="mpl", scale=1.5) 

# 0.5倍のスケールで表示
qc.draw(output="mpl", scale=0.5) 
```
![スクリーンショット 2025-02-16 15.30.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/f6b65a30-5cdf-47f5-9a9f-d6c8daf31c0f.png)

## `filename: str`

指定することで、実行ファイルと同じディレクトリに量子回路の画像ファイルを保存できます。ファイル名に指定した拡張子で保存されます。ざっと調べたところ、
- png 
- svg
- jpg
- pdf 
 
あたりで保存できるようです。
```python
# 拡張子を.svgとして保存
qc.draw(output="mpl", filename="circuit.svg")
```

## `plot_barrier: bool`
量子回路内のバリア（区切り線）の表示/非表示を制御できます。
```python
# 回路の定義では`qc.barrier()`が入っているが、drawでは表示されない
qc.draw(output="mpl", plot_barriers=False)
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/06e96834-43b4-4d59-ada9-cb3171b0ccba.png" width=50%>

これは、Groverのアルゴリズムなどで、ゲートの作用をわかりやすくする場面などに有効です。（barrierを入れないと、ゲートが詰まってしまうためです）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/908da0ce-4fa8-43ed-82d6-6273405411c3.png" width=70%>

## `fold: int`
長い回路の折り返しを制御できます。defaultでは25層ごとに折り返しになっており、この数字を指定できます。また、`fold=-1`にすることで、折り返しなし（回路を横に伸ばす）を指定できます。

```python
# 折り返しなしで表示
qc_fold.draw(output="mpl", fold=-1)
```
![circuit_fold.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/d1f79837-2789-4450-a127-64d7e159508c.png)

```python
# 30層で折り返す
qc_fold.draw(output="mpl", fold=30)
```
![circuit_fold_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/3030e3de-fb88-45ae-8e51-e32565789463.png)

## `initial_state: bool`
`True`にすることで、初期状態の$\ket{0}$を明示的に表示します。
```python
# |0〉を明示的に表示
qc.draw(output="mpl", initial_state=True)
```
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/223a3b34-1f1b-4e87-ade2-c18967987a61.png width=50%>

## `idle_wires: bool`
`False`にすることで、使わない量子ビットを非表示にします。
例えば、実際のビット数の多い量子回路に埋め込みを行う際のplotなどに用いると、見やすくなります。
```python
# 使用していない量子ビットを非表示にする
# 本来は127qubitだが、埋め込みの際に使用されたビット（今回は24-27）だけ表示している
qc.draw(output="mpl", idle_wires=False)
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/04927ddf-a2e8-4278-9aee-21ac02277f70.png" width=100%>


## `reverse_bits: bool`
`True`にすることで、量子ビットの表示順を逆にします。
```python
# ビットの表示順を反転する
qc.draw(output="mpl",reverse_bits=True, filename="circuit_reverse_bits.png")
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/0f200dee-9afb-4b8f-bdcc-09c66b020480.png" width=50%>



## `style :dict`
量子回路のstyleを設定できます。複数のoptionがあります。
### `name`
`name`を指定することで、事前定義されたスタイルを適用できます。
defaultのスタイルは、`style={"name":"iqp"}`となっています。
```python
# iqp（デフォルトのスタイル）で表示 
qc.draw(output="mpl", style={"name": "iqp"})
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/804c9ad3-85ca-4293-9d68-0f44d2ee589e.png" width=70%> 


その他の項目は以下のとおりです。
| スタイル名       | 説明 |
|----------------|---------------------------------------------|
| `"iqp"`       | **デフォルト** のスタイル。標準的なカラーテーマ。 |
| `"bw"`        | **白黒** (Black & White) のスタイル。印刷に最適。 |
| `"clifford"`  | **Clifford 回路** に適したスタイル。 |
| `"textbook"`  | **教科書風** のデザイン。ゲートが識別しやすい。 |
| `"iqp-dark"`  | **黒背景** の `iqp` スタイル。ダークモード向け。 |



![スクリーンショット 2025-02-16 16.13.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/62662e26-7322-4997-9753-3f6758eb1824.png)



その他、主要なoptionは以下の通りです。
### `backgroundcolor`
背景色を設定できます。

### `linecolor`
回路内の線の色を設定できます。

### `fontsize`
フォントサイズを指定できます。
```python
# 例。"white"や"red"などの色の指定でも、"#ffffff"などのカラーコードでも指定できる。
qc.draw(output="mpl", style={"backgroundcolor": "#00aaff", "linecolor": "white", "fontsize": 10})
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/e3adc56a-810c-49a1-96dd-ccd49dc7124d.png" width=70%>


### `displaycolor`
`dict`の形式で、特定の要素の色を指定できます。
```python
# H, CNOT, Measureの色を変更
qc.draw(output="mpl", style={"displaycolor": {"h": "tab:green", "cx": "tab:blue", "measure": "tab:orange"}})
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469107/3397b250-e8bd-495e-aeca-eb729b398181.png" width=70%>

### 指定可能なkey一覧
sytleで指定できるkeyを一覧でも載せておきます。参考にしてください。
`key` | 説明 | 例 |
|-----------------|----------------------------------------------------------|----------------------|
| `"name"` | スタイル名 (`"iqp"`, `"textbook"`, `"bw"`, `"clifford"` など) | `{"name": "textbook"}` |
| `"backgroundcolor"` | 背景の色 | `{"backgroundcolor": "#FFFFFF"}` |
| `"textcolor"` | ゲート外のテキストの色 | `{"textcolor": "#000000"}` |
| `"gatetextcolor"` | ゲート内部のテキストの色 | `{"gatetextcolor": "#FFFFFF"}` |
| `"subtextcolor"` | サブテキスト（例: ゲートのパラメータ）の色 | `{"subtextcolor": "#FF0000"}` |
| `"linecolor"` | 量子ビットの線の色 | `{"linecolor": "#0000FF"}` |
| `"creglinecolor"` | 古典レジスタの線の色 | `{"creglinecolor": "#778899"}` |
| `"gatefacecolor"` | ゲートの背景色 | `{"gatefacecolor": "#BB8BFF"}` |
| `"barrierfacecolor"` | バリアの背景色 | `{"barrierfacecolor": "#BDBDBD"}` |
| `"edgecolor"` | `bw` スタイル時のゲートの枠線の色 | `{"edgecolor": "#000000"}` |

####  フォント設定
| キー | 説明 | 例 |
|------|------|----|
| `"fontsize"` | フォントサイズ | `{"fontsize": 13}` |
| `"subfontsize"` | サブテキスト（ゲートパラメータなど）のフォントサイズ | `{"subfontsize": 8}` |

#### 追加オプション
| キー | 説明 | 例 |
|------|------|----|
| `"showindex"` | `True` にするとビットのインデックスを表示 | `{"showindex": True}` |
| `"figwidth"` | 画像の最大幅（インチ単位）。 `-1` なら最大表示幅 | `{"figwidth": 10}` |
| `"dpi"` | 画像の DPI | `{"dpi": 300}` |
| `"margin"` | 余白の設定 `[左, 右, 下, 上]` | `{"margin": [0.5, 0.5, 0.5, 0.5]}` |
| `"creglinestyle"` | 古典レジスタの線のスタイル (`"solid"`, `"doublet"` など) | `{"creglinestyle": "doublet"}` |

#### ゲートの表示設定
| キー | 説明 | 例 |
|------|------|----|
| `"displaytext"` | 各ゲートの表示テキスト (`LaTeX` 使用可) | `{"displaytext": {"h": "H"}}` |
| `"displaycolor"` | 各ゲートの色 (`{"ゲート名": "色コード"}` の形式) | `{"displaycolor": {"h": "red", "x": "blue"}}` |

---


# 参考
https://github.com/Qiskit/qiskit/blob/main/qiskit/visualization/circuit/circuit_visualization.py

https://docs.quantum.ibm.com/guides/visualize-circuits