Visualize results
Plot histogram
The plot_histogram
function visualizes the result of sampling a quantum circuit on a QPU or simulator.
This function returns a matplotlib.Figure
object. When the last line of a code cell outputs these objects, Jupyter notebooks display them below the cell. If you call these functions in some other environments or in scripts, you will need to explicitly show or save the outputs.
Two options are:
- Call
.show()
on the returned object to open the image in a new window (assuming your configured matplotlib backend is interactive). - Call
.savefig("out.png")
to save the figure toout.png
in the current working directory. Thesavefig()
method takes a path so you can adjust the location and filename where you're saving the output. For example,plot_state_city(psi).savefig("out.png")
.
For example, make a two-qubit Bell state:
[1] :from qiskit_aer.primitives import Sampler
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
# quantum circuit to make a Bell state
bell = QuantumCircuit(2)
bell.h(0)
bell.cx(0, 1)
bell.measure_all()
# execute the quantum circuit
quasi_dists = Sampler().run(bell, shots=1000).result().quasi_dists[0]
print(quasi_dists)
Output:
{0: 0.497, 3: 0.503}
plot_histogram(quasi_dists)
Output:
Options when plotting a histogram
Use the following options for plot_histogram
to adjust the output graph.
legend
: Provides a label for the executions. It takes a list of strings used to label each execution's results. This is mostly useful when plotting multiple execution results in the same histogramsort
: Adjusts the order of the bars in the histogram. It can be set to either ascending order withasc
or descending order withdesc
number_to_keep
: Takes an integer for the number of terms to show. The rest are grouped together in a single bar called "rest"color
: Adjusts the color of the bars; takes a string or a list of strings for the colors to use for the bars for each executionbar_labels
: Adjusts whether labels are printed above the barsfigsize
: Takes a tuple of the size in inches to make the output figure
# Execute two-qubit Bell state again
second_quasi_dists = Sampler().run(bell, shots=1000).result().quasi_dists[0]
# Plot results with custom options
plot_histogram(
[quasi_dists, second_quasi_dists],
legend=["first", "second"],
sort="desc",
figsize=(15, 12),
color=["orange", "black"],
bar_labels=False,
)
Output:
Plotting estimator results
Qiskit does not have a built-in function for plotting Estimator results, but you can use Matplotlib's bar
plot for a quick visualization.
To demonstrate, the following cell estimates the expectation values of seven different observables on a quantum state.
[5] :from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit_aer.primitives import Estimator
# Simple estimation experiment to create results
qc = QuantumCircuit(2)
qc.h(0)
qc.crx(1.5, 0, 1)
observables_labels = ["ZZ", "XX", "YZ", "ZY", "XY", "XZ", "ZX"]
observables = [SparsePauliOp(label) for label in observables_labels]
result = Estimator().run([qc]*7, observables).result()
print(result)
# Plot using Matplotlib
from matplotlib import pyplot as plt
plt.bar(observables_labels, result.values)
Output:
EstimatorResult(values=array([ 0.47070312, 0.015625 , 0.515625 , 0.01757812, -0.70703125,
0.01171875, 0.70507812]), metadata=[{'shots': 1024, 'variance': 0.7784385681152344, 'simulator_metadata': [{'num_bind_params': 1, 'runtime_parameter_bind': False, 'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.020288216, 'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, 'active_input_qubits': [0, 1], 'device': 'CPU', 'time_taken': 0.04090926, 'measure_sampling': True, 'num_clbits': 2, 'max_memory_mb': 32768, 'input_qubit_map': [[1, 1], [0, 0]], 'num_qubits': 2, 'method': 'statevector', 'required_memory_mb': 1, 'fusion': {'enabled': True, 'threshold': 14, 'applied': False, 'max_fused_qubits': 5}}]}, {'shots': 1024, 'variance': 0.999755859375, 'simulator_metadata': [{'num_bind_params': 1, 'runtime_parameter_bind': False, 'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.020340968, 'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, 'active_input_qubits': [0, 1], 'device': 'CPU', 'time_taken': 0.040808489, 'measure_sampling': True, 'num_clbits': 2, 'max_memory_mb': 32768, 'input_qubit_map': [[1, 1], [0, 0]], 'num_qubits': 2, 'method': 'statevector', 'required_memory_mb': 1, 'fusion': {'enabled': True, 'threshold': 14, 'applied': False, 'max_fused_qubits': 5}}]}, {'shots': 1024, 'variance': 0.734130859375, 'simulator_metadata': [{'num_bind_params': 1, 'runtime_parameter_bind': False, 'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.020251075, 'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, 'active_input_qubits': [0, 1], 'device': 'CPU', 'time_taken': 0.038300121, 'measure_sampling': True, 'num_clbits': 2, 'max_memory_mb': 32768, 'input_qubit_map': [[1, 1], [0, 0]], 'num_qubits': 2, 'method': 'statevector', 'required_memory_mb': 1, 'fusion': {'enabled': True, 'threshold': 14, 'applied': False, 'max_fused_qubits': 5}}]}, {'shots': 1024, 'variance': 0.9996910095214844, 'simulator_metadata': [{'num_bind_params': 1, 'runtime_parameter_bind': False, 'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.015676281, 'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, 'active_input_qubits': [0, 1], 'device': 'CPU', 'time_taken': 0.02706258, 'measure_sampling': True, 'num_clbits': 2, 'max_memory_mb': 32768, 'input_qubit_map': [[1, 1], [0, 0]], 'num_qubits': 2, 'method': 'statevector', 'required_memory_mb': 1, 'fusion': {'enabled': True, 'threshold': 14, 'applied': False, 'max_fused_qubits': 5}}]}, {'shots': 1024, 'variance': 0.5001068115234375, 'simulator_metadata': [{'num_bind_params': 1, 'runtime_parameter_bind': False, 'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.008310125, 'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, 'active_input_qubits': [0, 1], 'device': 'CPU', 'time_taken': 0.024550868, 'measure_sampling': True, 'num_clbits': 2, 'max_memory_mb': 32768, 'input_qubit_map': [[1, 1], [0, 0]], 'num_qubits': 2, 'method': 'statevector', 'required_memory_mb': 1, 'fusion': {'enabled': True, 'threshold': 14, 'applied': False, 'max_fused_qubits': 5}}]}, {'shots': 1024, 'variance': 0.9998626708984375, 'simulator_metadata': [{'num_bind_params': 1, 'runtime_parameter_bind': False, 'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.011214358, 'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, 'active_input_qubits': [0, 1], 'device': 'CPU', 'time_taken': 0.021865151, 'measure_sampling': True, 'num_clbits': 2, 'max_memory_mb': 32768, 'input_qubit_map': [[1, 1], [0, 0]], 'num_qubits': 2, 'method': 'statevector', 'required_memory_mb': 1, 'fusion': {'enabled': True, 'threshold': 14, 'applied': False, 'max_fused_qubits': 5}}]}, {'shots': 1024, 'variance': 0.5028648376464844, 'simulator_metadata': [{'num_bind_params': 1, 'runtime_parameter_bind': False, 'parallel_state_update': 16, 'parallel_shots': 1, 'sample_measure_time': 0.009052483, 'noise': 'ideal', 'batched_shots_optimization': False, 'remapped_qubits': False, 'active_input_qubits': [0, 1], 'device': 'CPU', 'time_taken': 0.017580494, 'measure_sampling': True, 'num_clbits': 2, 'max_memory_mb': 32768, 'input_qubit_map': [[1, 1], [0, 0]], 'num_qubits': 2, 'method': 'statevector', 'required_memory_mb': 1, 'fusion': {'enabled': True, 'threshold': 14, 'applied': False, 'max_fused_qubits': 5}}]}])
<BarContainer object of 7 artists>
The following cell estimates the standard error from the variance of each result and adds them as error bars. See the bar
plot documentation for a full description of the plot.
from math import sqrt
standard_error = [sqrt(exp_data["variance"])/sqrt(exp_data["shots"]) for exp_data in result.metadata]
_, ax = plt.subplots()
ax.bar(observables_labels, result.values, yerr=standard_error, capsize=2)
ax.set_title("Expectation values (with standard errors)")
Output:
Text(0.5, 1.0, 'Expectation values (with standard errors)')