Cram sheet — Section 2: Visualize quantum circuits, measurements, and states
One-screen review layer for this section: short background primers per objective, then the key facts — each backed by an official source or by an executed proof from the question bank.
Visualize quantum circuits
Four renderers, and a signature that does not forgive typos
QuantumCircuit.draw() and the standalone circuit_drawer() are the same machinery, and output= accepts exactly four names.
output | Returns | Reach for it when |
|---|---|---|
text (default) | a TextDrawing — printable, but not a str and not None | you are in a terminal or notebook |
mpl | a matplotlib.figure.Figure | you need to style or savefig a publication figure |
latex | a PIL Image, and it needs a LaTeX toolchain | you want typeset output |
latex_source | the raw LaTeX string | you are pasting into a document |
Anything else raises VisualizationError whose message lists those four. The one exception: with your own axes, draw("mpl", ax=ax) returns None, because the caller already owns the figure.
| Keyword | Effect | Notes |
|---|---|---|
idle_wires=False | deletes any wire carrying no operations — 3 qubits with gates only on 0 and 2 draw two wires | "auto" keeps them unless the circuit carries a transpiler layout |
reverse_bits=True | draws the highest-index qubit on the top wire | works in every renderer |
initial_state=True | prefixes each wire with its starting label | |
plot_barriers=False | hides barriers | works in every renderer |
filename= | saves the rendering to disk | |
fold, scale, style | wrap width, size, styling | renderer-specific |
The signature is closed — there is no **kwargs catch-all, so a near-miss keyword is a hard TypeError, never a silently ignored option.
Sources: visualize-circuits · visualization
Must know:
- A classically-controlled gate drawn as an
Ifblock is built withwith qc.if_test((qc.clbits[0], 1)):—.c_if(), acondition=kwarg, a.conditionattribute andif_test(clbit == 1)all fail in Qiskit 2.x. — ⚙️ proven ins2-q013
Traps:
output="matplotlib"andoutput="figure"both raiseVisualizationErrorlisting the four real names, from the method andcircuit_draweralike. — ⚙️ proven ins2-q015- The standalone drawer is
circuit_drawer(qc, output="text")fromqiskit.visualization;qiskit.toolsno longer exists, and the kwarg isoutput=, neverformat=. — ⚙️ proven ins2-q014 reverse_bits=Trueis rendering-only: highest-index qubit on the top wire, with no change to the circuit, the gate order, or the endianness of the results. — ⚙️ proven ins2-q012initial_state=True(defaultFalse) draws the|0⟩labels; the pluralinitial_states=is aTypeError, andstyle={"initial_state": True}is silently ignored by the text renderer. — ⚙️ proven ins2-q016
Visualize quantum measurements
Counts in, Figure out — and the bar labels are little-endian
Both measurement plotters take a counts mapping — bitstring to integer — and return a matplotlib.figure.Figure.
counts = result[0].data.meas.get_counts() # SamplerV2 -> BitArray -> counts
plot_histogram([before, after], legend=["before", "after"])
plot_histogram | plot_distribution | |
|---|---|---|
| plots | raw counts | a normalized quasi-probability distribution |
| y-axis label | Count | Quasi-probability |
| heights add up to | the shot count | 1.0 |
| where normalization comes from | — | the counts themselves |
Display options: legend (a LIST of strings, one per execution), sort ("asc" or "desc"), number_to_keep, color, bar_labels and figsize.
Qiskit labels outcomes little-endian, q_(n−1)…q_1 q_0, with the highest-index qubit on the LEFT. When a circuit has several classical registers — measure_all appends a fresh meas register — the key is space-separated, one group per register, the LAST-declared register printed leftmost.
Sources: visualize-results · visualization
The device plots draw the hardware, not the results
Three device plots draw the same qubit graph and differ only in what they colour.
| Function | Takes | Colours |
|---|---|---|
plot_gate_map(backend) | a BackendV2 | nothing; plot_directed=True adds arrows, not error data |
plot_error_map(backend) | a BackendV2 | every qubit and every link, from calibration data |
plot_circuit_layout(isa, backend) | a transpiled circuit plus its backend | a two-tone used/unused highlight, labelled with virtual indices |
plot_gate_map is a picture of the HARDWARE: it reads the backend's qubit count and coupling map and draws one node per qubit plus one line per connected pair. Reach for this family for DEVICE questions — which qubits exist, how they connect, how good they are, where the transpiler put your circuit — never measurement outcomes.
Sources: visualization · visualize-results
Must know:
- The
SamplerV2BitArrayis not a counts mapping and has no bare.counts()method — convert withresult[0].data.meas.get_counts(). — ⚙️ proven ins2-q022 number_to_keep=2on four outcomes draws three bars — the two largest plusrest, whose height is the SUM of the folded counts (20 + 4 → 24), never their average. — ⚙️ proven ins2-q021- Overlaying runs:
legendmust be a list matching the list of counts dicts — a bare string legend raises, andlabels=does not exist. — ⚙️ proven ins2-q023 plot_circuit_layoutreadscircuit.layout, carried only by the circuittranspileRETURNS (its input is never mutated): plotting the original raisesQiskitError: 'Circuit has no layout. Perhaps it has not been transpiled.'at every optimization level. — ⚙️ proven ins2-q036Statevector.sample_counts(shots)returns aqiskit.result.Countsmapping summing toshotswith only nonzero-amplitude outcomes, so it feedsplot_histogramwith no backend or primitive involved;sample_memory(shots)is the per-shot list andsv.seed(...)makes the draw reproducible. — ⚙️ proven ins2-q039
Traps:
- Flipping qubits 0 and 2 of a 4-qubit register puts the single histogram bar at
'0101', not'1010'— qubit 0 is the rightmost character. — ⚙️ proven ins2-q019 - Neither plotter has a
shots=parameter:plot_distribution(counts, shots=1024)raisesTypeError, and the V1-eraplot_histogram(counts, shots=1024)is gone. — ⚙️ proven ins2-q020 - With no options,
plot_histogramsorts bars in ascending lexicographic bitstring order — not insertion order, not bar height. — ⚙️ proven ins2-q025 plot_gate_mapgiven a counts mapping, aCouplingMapor aTargetraisesAttributeError;plot_histogram(backend)raises too. — ⚙️ proven ins2-q037
Visualize quantum states
Each state plot answers a different question
Pick a state plot by the question it answers; each is a free function, and also a token of sv.draw(output).
| Plot | Draws | Answers |
|---|---|---|
plot_bloch_multivector(state) | one sphere per qubit, from that qubit's reduced state | where each qubit points |
plot_state_qsphere(state) | one node per nonzero amplitude, sized and coloured | which amplitudes exist, and their relative phases |
plot_state_city(state) | two 3-D bar charts, the real and imaginary parts of ρ | individual density-matrix elements |
plot_state_hinton(state) | squares whose size is the magnitude | the same matrix, at a glance |
plot_state_paulivec(state) | the expansion coefficients over Pauli strings | the Pauli decomposition |
plot_bloch_multivector takes a quantum STATE and traces out the other qubits; plot_bloch_vector is the different function that takes an explicit three-number vector [x, y, z].
On sv.draw(output), output is the first positional parameter and the valid tokens are text, latex, latex_source, qsphere, hinton, bloch, city and paulivec. Unlike the other state plots, plot_state_qsphere accepts only figsize, not title.
Sources: plot-quantum-states · visualization
Reading an arrow, reading a node
The Bloch vector is (⟨X⟩, ⟨Y⟩, ⟨Z⟩), so reading an arrow is memorization.
| Arrow | State | How you land there |
|---|---|---|
| +Z (north pole) | the zero state | the starting point |
| −Z (south pole) | the one state | — |
| +X | the plus state | h alone |
| −X | the minus state, the −1 eigenstate of X | — |
| +Y | the 'r' state, a +i relative phase | h then s, a 90° rotation about Z |
| −Y | the 'l' state, a −i relative phase | — |
Anywhere on the equator means ⟨Z⟩ = 0. It shows only single-qubit expectation values, so it cannot represent correlations between qubits.
A q-sphere encodes different information: node SIZE is the amplitude magnitude and node COLOUR is its complex phase, so a q-sphere is the plot that shows relative phase between basis states.
Sources: plot-quantum-states
Must know:
plot_bloch_multivectorpacks one sphere PER QUBIT (3 qubits → 3 spheres, idle ones included) into a single returnedFigure. — ⚙️ proven ins2-q026- For a Bell state both reduced Bloch vectors are exactly (0, 0, 0) with purity 0.5 — arrows at the centre are the visual signature of maximal entanglement. — ⚙️ proven in
s2-q030 - Two equal-magnitude q-sphere amplitudes of +0.7071 and −0.7071 give same-size nodes at phase 0 and phase π, hence two different colours. — ⚙️ proven in
s2-q032 - A q-sphere shows a node only where the amplitude is nonzero — H on qubit 0 with X on qubit 1 gives nodes at
|10⟩and|11⟩only (little-endian labels). — ⚙️ proven ins2-q031 plot_bloch_multivectordraws REDUCED states, so partial entanglement SHORTENS arrows: afterry(2π/3, 0); cx(0, 1); h(1)qubit 0 points along −z and qubit 1 along −x, both at length 0.5. Full length means a pure single-qubit state. — ⚙️ proven ins2-q047plot_state_paulivecdraws a bar only for Pauli strings with a NON-zero expectation value, labelled little-endian:x(1); h(0); s(0)gives exactly II, IY, ZI, ZY at +1, +1, −1, −1, and the qubit-swapped preparation gives YI, IZ, YZ instead. — ⚙️ proven ins1-q067
Traps:
- Passing a quantum state to
plot_bloch_vectordoes not produce per-qubit spheres — it wants an explicit[x, y, z]. — ⚙️ proven ins2-q034 sv.draw("qsphere")works;sv.qsphere(),sv.plot(...)and importingplot_qspherefail, and any other token raisesValueErrorlisting the valid ones. — ⚙️ proven ins2-q029rz(π/2)on |0⟩ changes only a global phase, so the arrow stays pinned at the north pole, whilehandh; sboth land on the equator. — ⚙️ proven ins2-q035
- Name the four
drawoutputs and the return type of each before choosing one. - Reject any drawing keyword you cannot name — the signature has no
**kwargs, so typos raise. - Convert a
SamplerV2result withresult[0].data.meas.get_counts()before plotting anything. - Read every bitstring right-to-left: the leftmost character is the highest-index qubit.
- Ask whether a plot wants counts, a quantum state, or a backend before picking it.
- Transpile first, then plot a layout — the original circuit carries none.
- Decide what the question needs: per-qubit direction, amplitudes and phases, or matrix elements.
Every fact above is sourced: 📖 links go to official documentation, ⚙️ marks facts observed by executing code against the pinned Qiskit stack (the linked section page shows the proof evidence on its practice questions).