From 0697a8bffd4833864bcd493180fefc05ade9d813 Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Thu, 18 Apr 2024 15:47:46 +0100 Subject: [PATCH] Fit new notebooks into existing content (#1160) PRs #977 and #1099 added some new pages in anticipation of a restructure which has since been postponed. This PR fits those pages into our current content structure. --- docs/build-new/circuit-visualization.ipynb | 499 ------- docs/build/_toc.json | 4 + docs/build/circuit-visualization.ipynb | 1224 ++--------------- .../save-circuits.ipynb} | 228 +-- docs/run/_toc.json | 10 +- docs/run/save-jobs.ipynb | 203 +++ docs/{analyze => run}/visualize-results.ipynb | 0 docs/verify/_toc.json | 4 + .../plot-quantum-states.ipynb | 0 scripts/nb-tester/test-notebook.py | 2 +- 10 files changed, 342 insertions(+), 1832 deletions(-) delete mode 100644 docs/build-new/circuit-visualization.ipynb rename docs/{analyze/save-and-retrieve.ipynb => build/save-circuits.ipynb} (64%) create mode 100644 docs/run/save-jobs.ipynb rename docs/{analyze => run}/visualize-results.ipynb (100%) rename docs/{build-new => verify}/plot-quantum-states.ipynb (100%) diff --git a/docs/build-new/circuit-visualization.ipynb b/docs/build-new/circuit-visualization.ipynb deleted file mode 100644 index e6ad0e4eb48..00000000000 --- a/docs/build-new/circuit-visualization.ipynb +++ /dev/null @@ -1,499 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8d75dc24-b8d2-45f8-830b-48e45f794a31", - "metadata": {}, - "source": [ - "# Visualize circuits" - ] - }, - { - "cell_type": "markdown", - "id": "bd5865b3-adfa-4c87-be55-51f693335184", - "metadata": {}, - "source": [ - "It's often useful to see the circuits you're creating. Use the following options to display Qiskit circuits." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "488c8d7d-5615-40ec-bf84-f1fa94832fce", - "metadata": {}, - "outputs": [], - "source": [ - "from qiskit import QuantumCircuit" - ] - }, - { - "cell_type": "markdown", - "id": "8bbddcca-300c-4f20-98dd-a0723cdef026", - "metadata": {}, - "source": [ - "## Draw a quantum circuit\n", - "\n", - "The `QuantumCircuit` class supports drawing circuits through the `draw()` method, or by printing the circuit object. By default, both render an ASCII art version of the circuit diagram.\n", - "\n", - "Note that `print` returns `None` but has the side effect of printing the diagram, whereas `QuantumCircuit.draw` returns the diagram with no side effects. Since Jupyter notebooks display the output of the last line of each cell, they appear to have the same effect." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "547f07e8-7891-433c-ac53-3186196b3aa7", - "metadata": {}, - "outputs": [], - "source": [ - "# Build a quantum circuit\n", - "circuit = QuantumCircuit(3, 3)\n", - "circuit.x(1)\n", - "circuit.h(range(3))\n", - "circuit.cx(0, 1)\n", - "circuit.measure(range(3), range(3));" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "d69ae2df-c31c-414f-bba2-4c4a1012de41", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " ┌───┐ ┌─┐ \n", - "q_0: ┤ H ├───────■──┤M├───\n", - " ├───┤┌───┐┌─┴─┐└╥┘┌─┐\n", - "q_1: ┤ X ├┤ H ├┤ X ├─╫─┤M├\n", - " ├───┤└┬─┬┘└───┘ ║ └╥┘\n", - "q_2: ┤ H ├─┤M├───────╫──╫─\n", - " └───┘ └╥┘ ║ ║ \n", - "c: 3/═══════╩════════╩══╩═\n", - " 2 0 1 \n" - ] - } - ], - "source": [ - "print(circuit)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "04c91fd9-50a1-4ff3-84e4-0b51a6b1541a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
     ┌───┐          ┌─┐   \n",
-       "q_0: ┤ H ├───────■──┤M├───\n",
-       "     ├───┤┌───┐┌─┴─┐└╥┘┌─┐\n",
-       "q_1: ┤ X ├┤ H ├┤ X ├─╫─┤M├\n",
-       "     ├───┤└┬─┬┘└───┘ ║ └╥┘\n",
-       "q_2: ┤ H ├─┤M├───────╫──╫─\n",
-       "     └───┘ └╥┘       ║  ║ \n",
-       "c: 3/═══════╩════════╩══╩═\n",
-       "            2        0  1 
" - ], - "text/plain": [ - " ┌───┐ ┌─┐ \n", - "q_0: ┤ H ├───────■──┤M├───\n", - " ├───┤┌───┐┌─┴─┐└╥┘┌─┐\n", - "q_1: ┤ X ├┤ H ├┤ X ├─╫─┤M├\n", - " ├───┤└┬─┬┘└───┘ ║ └╥┘\n", - "q_2: ┤ H ├─┤M├───────╫──╫─\n", - " └───┘ └╥┘ ║ ║ \n", - "c: 3/═══════╩════════╩══╩═\n", - " 2 0 1 " - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "circuit.draw()" - ] - }, - { - "cell_type": "markdown", - "id": "2159af06-93b8-441d-b8aa-c29324d26c6e", - "metadata": {}, - "source": [ - "### Alternative renderers\n", - "\n", - "A text output is useful for quickly seeing the output while developing a circuit, but it doesn't provide the most flexibility. There are two alternative output renderers for the quantum circuit. One uses [Matplotlib](https://matplotlib.org/) and the other uses [LaTeX](https://www.latex-project.org/). The LaTeX renderer requires the [qcircuit package](https://github.com/CQuIC/qcircuit). Select these renderers by setting the \"output\" argument to the strings `mpl` and `latex`.\n", - "\n", - "\n", - " OSX users can get the required LaTeX packages through the [mactex package](https://www.tug.org/mactex/).\n", - "" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "3f9c61c9-58f9-4315-a639-455fa2e58450", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Matplotlib drawing\n", - "circuit.draw(output=\"mpl\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "94948dab-57de-45f0-8dd7-5901ae69b70a", - "metadata": {}, - "outputs": [ - { - "data": { - "image/jpeg": "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", - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Latex drawing\n", - "circuit.draw(output=\"latex\")" - ] - }, - { - "cell_type": "markdown", - "id": "78688e6c-3ed2-4ef2-b3db-80fdae35e585", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "### Control circuit drawings\n", - "\n", - "By default, the `draw()` method returns the rendered image as an object and does not output anything. The exact class returned depends on the output specified: `'text'` (the default) returns a `TextDrawer` object, `'mpl'` returns a `matplotlib.Figure` object, and `latex` returns a `PIL.Image` object. Jupyter notebooks understand these return types and render them properly, but when running outside of Jupyter, images will not display automatically.\n", - "\n", - "The `draw()` method has optional arguments to display or save the output. When specified, the `filename` kwarg takes a path to which it saves the rendered output. Alternatively, if you're using the `mpl` or `latex` outputs, you can use the `interactive` kwarg to open the image in a new window (this will not always work from within a notebook)." - ] - }, - { - "cell_type": "markdown", - "id": "fc41270b-3518-40af-8921-dfa9666fc8e0", - "metadata": {}, - "source": [ - "### Customize the output\n", - "\n", - "Depending on the output, there are also options to customize the circuit diagram.\n", - "\n", - "#### Disable plot barriers and reverse bit order\n", - "The first two options are shared among all three backends. They allow you to configure both the bit orders and whether or not you draw barriers. These can be set by the `reverse_bits` kwarg and `plot_barriers` kwarg, respectively. The following examples work with any output renderer; `mpl` is used here for brevity." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "db61dc71-4cdc-4bb7-8139-8820e7785e55", - "metadata": {}, - "outputs": [], - "source": [ - "from qiskit import QuantumRegister, ClassicalRegister\n", - "\n", - "# Draw a new circuit with barriers and more registers\n", - "q_a = QuantumRegister(3, name=\"a\")\n", - "q_b = QuantumRegister(5, name=\"b\")\n", - "c_a = ClassicalRegister(3)\n", - "c_b = ClassicalRegister(5)\n", - "\n", - "circuit = QuantumCircuit(q_a, q_b, c_a, c_b)\n", - "circuit.x(q_a[1])\n", - "circuit.x(q_b[1])\n", - "circuit.x(q_b[2])\n", - "circuit.x(q_b[4])\n", - "circuit.barrier()\n", - "circuit.h(q_a)\n", - "circuit.barrier(q_a)\n", - "circuit.h(q_b)\n", - "circuit.cswap(q_b[0], q_b[1], q_b[2])\n", - "circuit.cswap(q_b[2], q_b[3], q_b[4])\n", - "circuit.cswap(q_b[3], q_b[4], q_b[0])\n", - "circuit.barrier(q_b)\n", - "circuit.measure(q_a, c_a)\n", - "circuit.measure(q_b, c_b);" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "8e57cd43-8a48-469d-8f69-8e7c936d4a1e", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Draw the circuit\n", - "circuit.draw(output=\"mpl\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "8e7a251a-0a4f-43e0-8cf5-48493df7bad9", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Draw the circuit with reversed bit order\n", - "circuit.draw(output=\"mpl\", reverse_bits=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "b4a601ad-1c04-4b16-afbd-ac5a0ad42653", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Draw the circuit without barriers\n", - "circuit.draw(output=\"mpl\", plot_barriers=False)" - ] - }, - { - "cell_type": "markdown", - "id": "18b0bfbe-b586-4182-9a0d-b858655a9240", - "metadata": {}, - "source": [ - "### Renderer-specific customizations\n", - "\n", - "Some available customizing options are specific to a renderer.\n", - "\n", - "The `fold` argument sets a maximum width for the output. In the `text` renderer, this sets the length of the lines of the diagram before it is wrapped to the next line. When using the 'mpl' renderer, this is the number of (visual) layers before folding to the next line.\n", - "\n", - "The `mpl` renderer has the `style` kwarg, which changes the colors and outlines. See the [API documentation](/api/qiskit/qiskit.circuit.QuantumCircuit#draw) for more details.\n", - "\n", - "The `scale` option scales the output of the `mpl` and `latex` renderers." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "1e08bf74-378f-45e6-b195-a9539061013d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
   ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐»\n",
-       "q: ┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├»\n",
-       "   └───┘└───┘└───┘└───┘└───┘└───┘└───┘»\n",
-       "«   ┌───┐┌───┐┌───┐\n",
-       "«q: ┤ H ├┤ H ├┤ H ├\n",
-       "«   └───┘└───┘└───┘
" - ], - "text/plain": [ - " ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐»\n", - "q: ┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├»\n", - " └───┘└───┘└───┘└───┘└───┘└───┘└───┘»\n", - "« ┌───┐┌───┐┌───┐\n", - "«q: ┤ H ├┤ H ├┤ H ├\n", - "« └───┘└───┘└───┘" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "circuit = QuantumCircuit(1)\n", - "for _ in range(10):\n", - " circuit.h(0)\n", - "# limit line length to 40 characters\n", - "circuit.draw(output=\"text\", fold=40)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "decadf88-4866-45a0-9e2f-836c51491f9e", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Change the background color in mpl\n", - "\n", - "style = {\"backgroundcolor\": \"lightgreen\"}\n", - "circuit.draw(output=\"mpl\", style=style)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "ade9a653-3243-4ac9-bb0e-c8fb82f7a034", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Scale the mpl output to 1/2 the normal size\n", - "circuit.draw(output=\"mpl\", scale=0.5)" - ] - }, - { - "cell_type": "markdown", - "id": "495b560a-d835-448b-aa01-5025a7a0689e", - "metadata": {}, - "source": [ - "### Standalone circuit-drawing function\n", - "\n", - "If you have an application where you prefer to draw a circuit with a self-contained function instead of as a method of a circuit object, you can directly use the `circuit_drawer()` function, which is part of the public stable interface from `qiskit.visualization`. The function behaves identically to the `circuit.draw()` method, except that it takes in a circuit object as a required argument." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "256dd092-b2eb-47af-a025-0ecdf85c2d5a", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from qiskit.visualization import circuit_drawer\n", - "\n", - "circuit_drawer(circuit, output=\"mpl\", plot_barriers=False)" - ] - }, - { - "cell_type": "markdown", - "id": "0761df2f-183f-48e3-9070-766a9920c2b9", - "metadata": {}, - "source": [ - "## Next steps\n", - "\n", - "\n", - " - See an example of circuit visualization in the [Grover's Algorithm](https://learning.quantum.ibm.com/tutorial/grovers-algorithm) tutorial.\n", - " - Visualize simple circuits in the [Explore gates and circuits with the Quantum Composer](https://learning.quantum.ibm.com/tutorial/explore-gates-and-circuits-with-the-quantum-composer) tutorial.\n", - " - Review the [Qiskit visualizations API documentation](/api/qiskit/visualization).\n", - "" - ] - } - ], - "metadata": { - "description": "Create visualizations of circuits and plot job data using the Qiskit visualization module ", - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3" - }, - "title": "Visualize circuits" - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/build/_toc.json b/docs/build/_toc.json index 758060cdf81..f1a74dd1463 100644 --- a/docs/build/_toc.json +++ b/docs/build/_toc.json @@ -32,6 +32,10 @@ { "title": "Bit-ordering in the Qiskit SDK", "url": "/build/bit-ordering" + }, + { + "title": "Save circuits to disk", + "url": "/build/save-circuits" } ] }, diff --git a/docs/build/circuit-visualization.ipynb b/docs/build/circuit-visualization.ipynb index 21856a6e192..e6ad0e4eb48 100644 --- a/docs/build/circuit-visualization.ipynb +++ b/docs/build/circuit-visualization.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "b244716f-d7e8-4a48-993d-268fa5dfec01", + "id": "8d75dc24-b8d2-45f8-830b-48e45f794a31", "metadata": {}, "source": [ "# Visualize circuits" @@ -10,42 +10,43 @@ }, { "cell_type": "markdown", - "id": "6cab750e-ca5d-48c0-b69b-040eee04a506", + "id": "bd5865b3-adfa-4c87-be55-51f693335184", "metadata": {}, "source": [ - "A visualization is useful while working with quantum circuits. Below find options in the Qiskit SDK for drawing circuits, plotting data from executed jobs, seeing the state of a quantum computer, and more." + "It's often useful to see the circuits you're creating. Use the following options to display Qiskit circuits." ] }, { "cell_type": "code", "execution_count": 1, - "id": "cca49bb3-4baf-4383-89f0-61bcd5ec47f1", + "id": "488c8d7d-5615-40ec-bf84-f1fa94832fce", "metadata": {}, "outputs": [], "source": [ - "from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister" + "from qiskit import QuantumCircuit" ] }, { "cell_type": "markdown", - "id": "eceb5089-43ae-4433-98bc-6efec7e42c30", + "id": "8bbddcca-300c-4f20-98dd-a0723cdef026", "metadata": {}, "source": [ "## Draw a quantum circuit\n", "\n", - "Drawing a circuit is supported natively by a `QuantumCircuit` object. You can either call `print()` on the circuit, or call the `draw()` method on the object. This will render an ASCII art version of the circuit diagram." + "The `QuantumCircuit` class supports drawing circuits through the `draw()` method, or by printing the circuit object. By default, both render an ASCII art version of the circuit diagram.\n", + "\n", + "Note that `print` returns `None` but has the side effect of printing the diagram, whereas `QuantumCircuit.draw` returns the diagram with no side effects. Since Jupyter notebooks display the output of the last line of each cell, they appear to have the same effect." ] }, { "cell_type": "code", "execution_count": 2, - "id": "82f7d353-40a7-4e56-9269-988f89fd9416", + "id": "547f07e8-7891-433c-ac53-3186196b3aa7", "metadata": {}, "outputs": [], "source": [ "# Build a quantum circuit\n", "circuit = QuantumCircuit(3, 3)\n", - "\n", "circuit.x(1)\n", "circuit.h(range(3))\n", "circuit.cx(0, 1)\n", @@ -55,7 +56,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "83ee7af3-c7ff-46a5-8616-5c236b533662", + "id": "d69ae2df-c31c-414f-bba2-4c4a1012de41", "metadata": {}, "outputs": [ { @@ -81,7 +82,7 @@ { "cell_type": "code", "execution_count": 4, - "id": "637c0472-f196-42b3-9a84-776791cbf88d", + "id": "04c91fd9-50a1-4ff3-84e4-0b51a6b1541a", "metadata": {}, "outputs": [ { @@ -120,28 +121,28 @@ }, { "cell_type": "markdown", - "id": "5483858d-86e4-4787-baeb-a32be0234815", + "id": "2159af06-93b8-441d-b8aa-c29324d26c6e", "metadata": {}, "source": [ "### Alternative renderers\n", "\n", - "A text output is useful for quickly seeing the output while developing a circuit, but it doesn't provide the most flexibility. There are two alternative output renderers for the quantum circuit. One uses [matplotlib](https://matplotlib.org/), and the other uses [LaTeX](https://www.latex-project.org/), which leverages the [qcircuit package](https://github.com/CQuIC/qcircuit). These can be specified with `mpl` and `latex` values for the `output` kwarg on the draw() method.\n", + "A text output is useful for quickly seeing the output while developing a circuit, but it doesn't provide the most flexibility. There are two alternative output renderers for the quantum circuit. One uses [Matplotlib](https://matplotlib.org/) and the other uses [LaTeX](https://www.latex-project.org/). The LaTeX renderer requires the [qcircuit package](https://github.com/CQuIC/qcircuit). Select these renderers by setting the \"output\" argument to the strings `mpl` and `latex`.\n", "\n", "\n", - " OSX users can get the required LaTeX packages through the [mactex package](https://www.tug.org/mactex/)\n", + " OSX users can get the required LaTeX packages through the [mactex package](https://www.tug.org/mactex/).\n", "" ] }, { "cell_type": "code", "execution_count": 5, - "id": "47d122b9-e3e2-4869-8eaf-31c723acd50e", + "id": "3f9c61c9-58f9-4315-a639-455fa2e58450", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "" + "" ], "text/plain": [ "
" @@ -154,13 +155,13 @@ ], "source": [ "# Matplotlib drawing\n", - "circuit.draw(output='mpl')" + "circuit.draw(output=\"mpl\")" ] }, { "cell_type": "code", "execution_count": 6, - "id": "32e672cd-4e24-4d67-a639-682fc7e5bf40", + "id": "94948dab-57de-45f0-8dd7-5901ae69b70a", "metadata": {}, "outputs": [ { @@ -178,24 +179,26 @@ ], "source": [ "# Latex drawing\n", - "circuit.draw(output='latex')" + "circuit.draw(output=\"latex\")" ] }, { "cell_type": "markdown", - "id": "2aeca2f2-69c0-4e8b-908f-729256dab283", - "metadata": {}, + "id": "78688e6c-3ed2-4ef2-b3db-80fdae35e585", + "metadata": { + "jp-MarkdownHeadingCollapsed": true + }, "source": [ - "### Control output from circuit.draw()\n", + "### Control circuit drawings\n", "\n", - "By default, the `draw()` method returns the rendered image as an object and does not output anything. The exact class returned depends on the output specified: `'text'` (the default) returns a `TextDrawer` object, `'mpl'` returns a `matplotlib.Figure` object, and `latex` returns a `PIL.Image` object. These return types enable modifying or directly interacting with the rendered output from the drawers.\n", + "By default, the `draw()` method returns the rendered image as an object and does not output anything. The exact class returned depends on the output specified: `'text'` (the default) returns a `TextDrawer` object, `'mpl'` returns a `matplotlib.Figure` object, and `latex` returns a `PIL.Image` object. Jupyter notebooks understand these return types and render them properly, but when running outside of Jupyter, images will not display automatically.\n", "\n", - "Jupyter notebooks understand these return types and render them properly, but when running outside of Jupyter, this feature is not automatic. However, the `draw()` method has optional arguments to display or save the output. When specified, the `filename` kwarg takes a path to which it saves the rendered output. Alternatively, if you're using the `mpl` or `latex` outputs, you can leverage the `interactive` kwarg to open the image in a new window (this will not always work from within a notebook)." + "The `draw()` method has optional arguments to display or save the output. When specified, the `filename` kwarg takes a path to which it saves the rendered output. Alternatively, if you're using the `mpl` or `latex` outputs, you can use the `interactive` kwarg to open the image in a new window (this will not always work from within a notebook)." ] }, { "cell_type": "markdown", - "id": "c2d796ee-dead-45d1-a767-817ee556606a", + "id": "fc41270b-3518-40af-8921-dfa9666fc8e0", "metadata": {}, "source": [ "### Customize the output\n", @@ -203,25 +206,25 @@ "Depending on the output, there are also options to customize the circuit diagram.\n", "\n", "#### Disable plot barriers and reverse bit order\n", - "The first two options are shared among all three backends. They allow you to configure both the bit orders and whether or not you draw barriers. These can be set by the `reverse_bits` kwarg and `plot_barriers` kwarg, respectively. The examples below will work with any output renderer; `mpl` is used here for brevity." + "The first two options are shared among all three backends. They allow you to configure both the bit orders and whether or not you draw barriers. These can be set by the `reverse_bits` kwarg and `plot_barriers` kwarg, respectively. The following examples work with any output renderer; `mpl` is used here for brevity." ] }, { "cell_type": "code", "execution_count": 7, - "id": "157435e6-953e-427e-a766-f60a1fc525bc", + "id": "db61dc71-4cdc-4bb7-8139-8820e7785e55", "metadata": {}, "outputs": [], "source": [ - "# Draw a new circuit with barriers and more registers\n", + "from qiskit import QuantumRegister, ClassicalRegister\n", "\n", - "q_a = QuantumRegister(3, name='qa')\n", - "q_b = QuantumRegister(5, name='qb')\n", + "# Draw a new circuit with barriers and more registers\n", + "q_a = QuantumRegister(3, name=\"a\")\n", + "q_b = QuantumRegister(5, name=\"b\")\n", "c_a = ClassicalRegister(3)\n", "c_b = ClassicalRegister(5)\n", "\n", "circuit = QuantumCircuit(q_a, q_b, c_a, c_b)\n", - "\n", "circuit.x(q_a[1])\n", "circuit.x(q_b[1])\n", "circuit.x(q_b[2])\n", @@ -241,16 +244,16 @@ { "cell_type": "code", "execution_count": 8, - "id": "2bab2d06-527e-4771-b0c0-93b2cfdade42", + "id": "8e57cd43-8a48-469d-8f69-8e7c936d4a1e", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "" + "" ], "text/plain": [ - "
" + "
" ] }, "execution_count": 8, @@ -260,22 +263,22 @@ ], "source": [ "# Draw the circuit\n", - "circuit.draw(output='mpl')" + "circuit.draw(output=\"mpl\")" ] }, { "cell_type": "code", "execution_count": 9, - "id": "1cb97bf6-6593-4cc1-a2dc-87059bed4165", + "id": "8e7a251a-0a4f-43e0-8cf5-48493df7bad9", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "" + "" ], "text/plain": [ - "
" + "
" ] }, "execution_count": 9, @@ -285,22 +288,22 @@ ], "source": [ "# Draw the circuit with reversed bit order\n", - "circuit.draw(output='mpl', reverse_bits=True)" + "circuit.draw(output=\"mpl\", reverse_bits=True)" ] }, { "cell_type": "code", "execution_count": 10, - "id": "483bba61-33bc-40ea-8261-1d3d0909ea39", + "id": "b4a601ad-1c04-4b16-afbd-ac5a0ad42653", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "" + "" ], "text/plain": [ - "
" + "
" ] }, "execution_count": 10, @@ -310,189 +313,79 @@ ], "source": [ "# Draw the circuit without barriers\n", - "circuit.draw(output='mpl', plot_barriers=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "c5921422-6f11-4d84-975e-10d49ee1a659", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Draw the circuit without barriers and reverse bit order\n", - "circuit.draw(output='mpl', plot_barriers=False, reverse_bits=True)" + "circuit.draw(output=\"mpl\", plot_barriers=False)" ] }, { "cell_type": "markdown", - "id": "40591534-3473-41df-969b-f4bc3b46a662", + "id": "18b0bfbe-b586-4182-9a0d-b858655a9240", "metadata": {}, "source": [ "### Renderer-specific customizations\n", "\n", "Some available customizing options are specific to a renderer.\n", "\n", - "The `fold` kwarg can be used to set a maximum width for the output. In the `text` renderer, this sets the length of the lines of the diagram before it is wrapped to the next line. When using the 'mpl' renderer, this is used as the number of (visual) layers before folding to the next line.\n", - "\n", - "The `mpl` renderer has the `style` kwarg, which is used to customize the output.\n", - "\n", - "The `scale` option is used by the `mpl` and `latex` renderers to scale the size of the output image with a multiplicative adjustment factor.\n", - "\n", - "The `style` kwarg takes in a `dict` with multiple options, including specifying colors, changing rendered text for different types of gates, choosing different line styles, and more.\n", - "\n", - "Available options are:\n", + "The `fold` argument sets a maximum width for the output. In the `text` renderer, this sets the length of the lines of the diagram before it is wrapped to the next line. When using the 'mpl' renderer, this is the number of (visual) layers before folding to the next line.\n", "\n", - "- **textcolor** (str): The color code for text. Defaults to `'#000000'`\n", - "- **subtextcolor** (str): The color code for subtext. Defaults to `'#000000'`\n", - "- **linecolor** (str): The color code for lines. Defaults to `'#000000'`\n", - "- **creglinecolor** (str): The color code for classical register lines `'#778899'`\n", - "- **gatetextcolor** (str): The color code for gate text `'#000000'`\n", - "- **gatefacecolor** (str): The color code for gates. Defaults to `'#ffffff'`\n", - "- **barrierfacecolor** (str): The color code for barriers. Defaults to `'#bdbdbd'`\n", - "- **backgroundcolor** (str): The color code for the background. Defaults to `'#ffffff'`\n", - "- **fontsize** (int): The font size for text. Defaults to 13\n", - "- **subfontsize** (int): The font size for subtext. Defaults to 8\n", - "- **displaytext** (dict): A dictionary of the text for each element\n", - " type in the output visualization. The default values are:\n", + "The `mpl` renderer has the `style` kwarg, which changes the colors and outlines. See the [API documentation](/api/qiskit/qiskit.circuit.QuantumCircuit#draw) for more details.\n", "\n", - "\n", - " 'id': 'id',\n", - " 'u0': 'U_0',\n", - " 'u1': 'U_1',\n", - " 'u2': 'U_2',\n", - " 'u3': 'U_3',\n", - " 'x': 'X',\n", - " 'y': 'Y',\n", - " 'z': 'Z',\n", - " 'h': 'H',\n", - " 's': 'S',\n", - " 'sdg': 'S^\\\\dagger',\n", - " 't': 'T',\n", - " 'tdg': 'T^\\\\dagger',\n", - " 'rx': 'R_x',\n", - " 'ry': 'R_y',\n", - " 'rz': 'R_z',\n", - " 'reset': '\\\\left|0\\\\right\\\\rangle'\n", - "\n", - "\n", - " You must specify all the necessary values if using this. There is\n", - " no provision for an incomplete dict passed in.\n", - "- **displaycolor** (dict): The color codes to use for each circuit element.\n", - " By default, all values default to the value of `gatefacecolor` and\n", - " the keys are the same as `displaytext`. Also, just like\n", - " `displaytext`, there is no provision for an incomplete dict passed\n", - " in.\n", - "- **latexdrawerstyle** (bool): When set to True, enable LaTeX mode, which will\n", - " draw gates like the `latex` output modes.\n", - "- **usepiformat** (bool): When set to True, use radians for output.\n", - "- **fold** (int): The number of circuit elements at which to fold the circuit.\n", - " Defaults to 20\n", - "- **cregbundle** (bool): If set True, bundle classical registers.\n", - "- **showindex** (bool): If set True, draw an index.\n", - "- **compress** (bool): If set True, draw a compressed circuit.\n", - "- **figwidth** (int): The maximum width (in inches) for the output figure.\n", - "- **dpi** (int): The DPI to use for the output image. Defaults to 150.\n", - "- **creglinestyle** (str): The style of line to use for classical registers.\n", - " Choices are `'solid'`, `'doublet'`, or any valid matplotlib\n", - " `linestyle` kwarg value. Defaults to `doublet`." + "The `scale` option scales the output of the `mpl` and `latex` renderers." ] }, { "cell_type": "code", - "execution_count": 12, - "id": "da24ce36-713f-49f2-873d-a0f18f189e18", + "execution_count": 11, + "id": "1e08bf74-378f-45e6-b195-a9539061013d", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
            ░ ┌───┐ ░    ┌─┐                           \n",
-       "qa_0: ──────░─┤ H ├─░────┤M├───────────────────────────\n",
-       "      ┌───┐ ░ ├───┤ ░    └╥┘┌─┐                        \n",
-       "qa_1: ┤ X ├─░─┤ H ├─░─────╫─┤M├────────────────────────\n",
-       "      └───┘ ░ ├───┤ ░     ║ └╥┘┌─┐                     \n",
-       "qa_2: ──────░─┤ H ├─░─────╫──╫─┤M├─────────────────────\n",
-       "            ░ ├───┤ ░     ║  ║ └╥┘    ░ ┌─┐            \n",
-       "qb_0: ──────░─┤ H ├─■─────╫──╫──╫──X──░─┤M├────────────\n",
-       "      ┌───┐ ░ ├───┤ │     ║  ║  ║  │  ░ └╥┘┌─┐         \n",
-       "qb_1: ┤ X ├─░─┤ H ├─X─────╫──╫──╫──┼──░──╫─┤M├─────────\n",
-       "      ├───┤ ░ ├───┤ │     ║  ║  ║  │  ░  ║ └╥┘┌─┐      \n",
-       "qb_2: ┤ X ├─░─┤ H ├─X──■──╫──╫──╫──┼──░──╫──╫─┤M├──────\n",
-       "      └───┘ ░ ├───┤    │  ║  ║  ║  │  ░  ║  ║ └╥┘┌─┐   \n",
-       "qb_3: ──────░─┤ H ├────X──╫──╫──╫──■──░──╫──╫──╫─┤M├───\n",
-       "      ┌───┐ ░ ├───┤    │  ║  ║  ║  │  ░  ║  ║  ║ └╥┘┌─┐\n",
-       "qb_4: ┤ X ├─░─┤ H ├────X──╫──╫──╫──X──░──╫──╫──╫──╫─┤M├\n",
-       "      └───┘ ░ └───┘       ║  ║  ║     ░  ║  ║  ║  ║ └╥┘\n",
-       "c0: 3/════════════════════╩══╩══╩════════╬══╬══╬══╬══╬═\n",
-       "                          0  1  2        ║  ║  ║  ║  ║ \n",
-       "c1: 5/═══════════════════════════════════╩══╩══╩══╩══╩═\n",
-       "                                         0  1  2  3  4 
" + "
   ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐»\n",
+       "q: ┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├»\n",
+       "   └───┘└───┘└───┘└───┘└───┘└───┘└───┘»\n",
+       "«   ┌───┐┌───┐┌───┐\n",
+       "«q: ┤ H ├┤ H ├┤ H ├\n",
+       "«   └───┘└───┘└───┘
" ], "text/plain": [ - " ░ ┌───┐ ░ ┌─┐ \n", - "qa_0: ──────░─┤ H ├─░────┤M├───────────────────────────\n", - " ┌───┐ ░ ├───┤ ░ └╥┘┌─┐ \n", - "qa_1: ┤ X ├─░─┤ H ├─░─────╫─┤M├────────────────────────\n", - " └───┘ ░ ├───┤ ░ ║ └╥┘┌─┐ \n", - "qa_2: ──────░─┤ H ├─░─────╫──╫─┤M├─────────────────────\n", - " ░ ├───┤ ░ ║ ║ └╥┘ ░ ┌─┐ \n", - "qb_0: ──────░─┤ H ├─■─────╫──╫──╫──X──░─┤M├────────────\n", - " ┌───┐ ░ ├───┤ │ ║ ║ ║ │ ░ └╥┘┌─┐ \n", - "qb_1: ┤ X ├─░─┤ H ├─X─────╫──╫──╫──┼──░──╫─┤M├─────────\n", - " ├───┤ ░ ├───┤ │ ║ ║ ║ │ ░ ║ └╥┘┌─┐ \n", - "qb_2: ┤ X ├─░─┤ H ├─X──■──╫──╫──╫──┼──░──╫──╫─┤M├──────\n", - " └───┘ ░ ├───┤ │ ║ ║ ║ │ ░ ║ ║ └╥┘┌─┐ \n", - "qb_3: ──────░─┤ H ├────X──╫──╫──╫──■──░──╫──╫──╫─┤M├───\n", - " ┌───┐ ░ ├───┤ │ ║ ║ ║ │ ░ ║ ║ ║ └╥┘┌─┐\n", - "qb_4: ┤ X ├─░─┤ H ├────X──╫──╫──╫──X──░──╫──╫──╫──╫─┤M├\n", - " └───┘ ░ └───┘ ║ ║ ║ ░ ║ ║ ║ ║ └╥┘\n", - "c0: 3/════════════════════╩══╩══╩════════╬══╬══╬══╬══╬═\n", - " 0 1 2 ║ ║ ║ ║ ║ \n", - "c1: 5/═══════════════════════════════════╩══╩══╩══╩══╩═\n", - " 0 1 2 3 4 " + " ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐»\n", + "q: ┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├┤ H ├»\n", + " └───┘└───┘└───┘└───┘└───┘└───┘└───┘»\n", + "« ┌───┐┌───┐┌───┐\n", + "«q: ┤ H ├┤ H ├┤ H ├\n", + "« └───┘└───┘└───┘" ] }, - "execution_count": 12, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Set line length to 80 for above circuit\n", - "circuit.draw(output='text')" + "circuit = QuantumCircuit(1)\n", + "for _ in range(10):\n", + " circuit.h(0)\n", + "# limit line length to 40 characters\n", + "circuit.draw(output=\"text\", fold=40)" ] }, { "cell_type": "code", - "execution_count": 13, - "id": "9bc14130-f08d-4580-bef5-ddac19e87c30", + "execution_count": 12, + "id": "decadf88-4866-45a0-9e2f-836c51491f9e", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "" + "" ], "text/plain": [ - "
" + "
" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -500,984 +393,107 @@ "source": [ "# Change the background color in mpl\n", "\n", - "style = {'backgroundcolor': 'lightgreen'}\n", - "\n", - "circuit.draw(output='mpl', style=style)" + "style = {\"backgroundcolor\": \"lightgreen\"}\n", + "circuit.draw(output=\"mpl\", style=style)" ] }, { "cell_type": "code", - "execution_count": 14, - "id": "673ee669-2ce0-48fe-bef6-8f9df63c7f76", + "execution_count": 13, + "id": "ade9a653-3243-4ac9-bb0e-c8fb82f7a034", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "" + "" ], "text/plain": [ - "
" + "
" ] }, - "execution_count": 14, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Scale the mpl output to 1/2 the normal size\n", - "circuit.draw(output='mpl', scale=0.5)" - ] - }, - { - "cell_type": "markdown", - "id": "7ca2672c-1a3f-4115-90de-7b9ceaf365a8", - "metadata": {}, - "source": [ - "### circuit_drawer() as function\n", - "\n", - "If you have an application where you prefer to draw a circuit with a self-contained function instead of as a method of a circuit object, you can directly use the `circuit_drawer()` function, which is part of the public stable interface from `qiskit.visualization`. The function behaves identically to the `circuit.draw()` method, except that it takes in a circuit object as required argument.\n", - "\n", - "
\n", - "Note: In Qiskit Terra $<=$ 0.7, the default behavior for the circuit_drawer() from qiskit.tools.visualization import circuit_drawer function is to use the latex output backend, and in 0.6.x that includes a fallback to mpl if latex fails for any reason. Starting with release > 0.7, the default changes to the text output.\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "ac579559-4122-404c-bba3-3d2fe835af85", - "metadata": {}, - "outputs": [], - "source": [ - "from qiskit.visualization import circuit_drawer" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "2cc3fd24-9712-4cc6-9504-2fd68b809ce6", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "circuit_drawer(circuit, output='mpl', plot_barriers=False)" + "circuit.draw(output=\"mpl\", scale=0.5)" ] }, { "cell_type": "markdown", - "id": "c73d6344-26bf-41d0-875d-a3d64e508022", + "id": "495b560a-d835-448b-aa01-5025a7a0689e", "metadata": {}, "source": [ - "## Plot histogram \n", - "\n", - "The following function visualizes the data from a quantum circuit executed on a system or simulator.\n", - "\n", - "`plot_histogram(data)`\n", - "\n", - "For example, make a two-qubit Bell state:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "8d58eedc-369f-4295-bc7e-7adbc33da632", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:07:56.673595Z", - "start_time": "2021-07-31T05:07:56.670504Z" - } - }, - "outputs": [], - "source": [ - "from qiskit_aer import Aer\n", - "\n", - "from qiskit import *\n", - "from qiskit.visualization import plot_histogram" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "73ae758a-c539-4d0b-a899-5da5d13dc9e1", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:03.168385Z", - "start_time": "2021-07-31T05:08:03.152732Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'00': 512, '11': 488}\n" - ] - } - ], - "source": [ - "# quantum circuit to make a Bell state\n", - "bell = QuantumCircuit(2, 2)\n", - "bell.h(0)\n", - "bell.cx(0, 1)\n", + "### Standalone circuit-drawing function\n", "\n", - "meas = QuantumCircuit(2, 2)\n", - "meas.measure([0,1], [0,1])\n", - "\n", - "# execute the quantum circuit\n", - "backend = Aer.get_backend('qasm_simulator') # the device to run on\n", - "circ = bell.compose(meas)\n", - "result = backend.run(circ, shots=1000).result()\n", - "counts = result.get_counts(circ)\n", - "print(counts)" + "If you have an application where you prefer to draw a circuit with a self-contained function instead of as a method of a circuit object, you can directly use the `circuit_drawer()` function, which is part of the public stable interface from `qiskit.visualization`. The function behaves identically to the `circuit.draw()` method, except that it takes in a circuit object as a required argument." ] }, { "cell_type": "code", - "execution_count": 19, - "id": "1fcee2ac-3e91-4268-ba1a-e85e783d2ddd", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:04.672500Z", - "start_time": "2021-07-31T05:08:04.216126Z" - } - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_histogram(counts)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "7ef0a5df-1c00-41de-914b-e00911278fe0", + "execution_count": 14, + "id": "256dd092-b2eb-47af-a025-0ecdf85c2d5a", "metadata": {}, - "source": [ - "### Options when plotting a histogram\n", - "\n", - "Use the following options for `plot_histogram()` to adjust the output graph.\n", - "\n", - "* `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 histogram\n", - "* `sort`: Adjusts the order the bars in the histogram are rendered. It can be set to either ascending order with `asc` or descending order with `desc`\n", - "* `number_to_keep`: Takes an integer for the number of terms to show. The rest are grouped together in a single bar called \"rest\"\n", - "* `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 execution.\n", - "* `bar_labels`: Adjusts whether labels are printed above the bars\n", - "* `figsize`: Takes a tuple of the size in inches to make the output figure" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "ed3a2001-3279-49f6-81a3-d484b2c73969", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:30.989035Z", - "start_time": "2021-07-31T05:08:30.821801Z" - } - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Execute two-qubit Bell state again\n", - "second_result = backend.run(circ, shots=1000).result()\n", - "second_counts = second_result.get_counts(circ)\n", - "# Plot results with legend\n", - "legend = ['First execution', 'Second execution']\n", - "plot_histogram([counts, second_counts], legend=legend)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "a898b675-8de4-45a9-8cb1-ee516a069958", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:33.681069Z", - "start_time": "2021-07-31T05:08:33.494469Z" - } - }, "outputs": [ { "data": { "image/svg+xml": [ - "" + "" ], "text/plain": [ - "
" + "
" ] }, - "execution_count": 21, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "plot_histogram([counts, second_counts], legend=legend, sort='desc', figsize=(15,12),\n", - " color=['orange', 'black'], bar_labels=False)" - ] - }, - { - "cell_type": "markdown", - "id": "cc69259d-cc9d-4c38-9dce-578308c47847", - "metadata": {}, - "source": [ - "### Use the output from plot_histogram()\n", + "from qiskit.visualization import circuit_drawer\n", "\n", - "When using the `plot_histogram()` function, it returns a `matplotlib.Figure` for the rendered visualization. Jupyter notebooks understand this return type and render it properly, but when running outside of Jupyter,this feature is not automatic. However, the `matplotlib.Figure` class natively has methods to both display and save the visualization. You can call `.show()` on the returned object from `plot_histogram()` to open the image in a new window (assuming your configured matplotlib backend is interactive). Alternatively, call `.savefig('out.png')` to save the figure to `out.png`. The `savefig()` method takes a path so you can adjust the location and filename where you're saving the output." - ] - }, - { - "cell_type": "markdown", - "id": "d57a1931-84cd-4a4d-a849-9a50987d87a6", - "metadata": {}, - "source": [ - "## Plot state " + "circuit_drawer(circuit, output=\"mpl\", plot_barriers=False)" ] }, { "cell_type": "markdown", - "id": "164c8084-8431-4ec7-82ca-7d65d5b38b3a", + "id": "0761df2f-183f-48e3-9070-766a9920c2b9", "metadata": {}, "source": [ - "In many situations it is helpful to see the state of a quantum computer - perhaps for debugging purposes. Here we assume you have a particular state (either from simulation or state tomography), and the goal is to visualize the quantum state. This requires exponential resources, so we advise to only view the state of small quantum systems. There are several functions for generating different types of visualization of a quantum state:\n", - "\n", - "```\n", - "plot_state_city(quantum_state)\n", - "plot_state_qsphere(quantum_state)\n", - "plot_state_paulivec(quantum_state)\n", - "plot_state_hinton(quantum_state)\n", - "plot_bloch_multivector(quantum_state)\n", - "```\n", - "\n", - "A quantum state is either a density matrix $\\rho$ (Hermitian matrix) or statevector $|\\psi\\rangle$ (complex vector). The density matrix is related to the statevector by\n", - "\n", - "$$\\rho = |\\psi\\rangle\\langle \\psi|,$$\n", - "\n", - "and is more general as it can represent mixed states (positive sum of statevectors)\n", - "\n", - "$$\\rho = \\sum_k p_k |\\psi_k\\rangle\\langle \\psi_k |.$$\n", - "\n", - "The visualizations generated by the functions are:\n", - "\n", - "- `'plot_state_city'`: The standard view for quantum states where the real and imaginary (imag) parts of the density matrix are plotted like a city.\n", - "\n", - "- `'plot_state_qsphere'`: The Qiskit-unique view of a quantum state where the amplitude and phase of the state vector are plotted in a spherical ball. The amplitude is the thickness of the arrow and the phase is the color. For mixed states it will show different `'qsphere'` for each component.\n", - "\n", - "- `'plot_state_paulivec'`: The representation of the density matrix using Pauli operators as the basis $\\rho=\\sum_{q=0}^{d^2-1}p_jP_j/d$.\n", - "\n", - "- `'plot_state_hinton'`: Same as `'city'` but where the size of the element represents the value of the matrix element.\n", + "## Next steps\n", "\n", - "- `'plot_bloch_multivector'`: The projection of the quantum state onto the single-qubit space and plotting on a Bloch sphere." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "a02742b0-9a09-49a0-9488-b622bbdc5d6b", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:38.155610Z", - "start_time": "2021-07-31T05:08:38.152536Z" - } - }, - "outputs": [], - "source": [ - "from qiskit.visualization import plot_state_city, plot_bloch_multivector\n", - "from qiskit.visualization import plot_state_paulivec, plot_state_hinton\n", - "from qiskit.visualization import plot_state_qsphere" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "26328482-aa61-449e-8d13-d9112420ce77", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:53.778558Z", - "start_time": "2021-07-31T05:08:53.767409Z" - } - }, - "outputs": [], - "source": [ - "# execute the quantum circuit\n", - "backend = Aer.get_backend('statevector_simulator') # the device to run on\n", - "result = backend.run(bell).result()\n", - "psi = result.get_statevector(bell)" + "\n", + " - See an example of circuit visualization in the [Grover's Algorithm](https://learning.quantum.ibm.com/tutorial/grovers-algorithm) tutorial.\n", + " - Visualize simple circuits in the [Explore gates and circuits with the Quantum Composer](https://learning.quantum.ibm.com/tutorial/explore-gates-and-circuits-with-the-quantum-composer) tutorial.\n", + " - Review the [Qiskit visualizations API documentation](/api/qiskit/visualization).\n", + "" ] + } + ], + "metadata": { + "description": "Create visualizations of circuits and plot job data using the Qiskit visualization module ", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" }, - { - "cell_type": "code", - "execution_count": 24, - "id": "b48c0dc5-3fcb-47cd-ad16-80ef56e4da18", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:55.480726Z", - "start_time": "2021-07-31T05:08:54.964494Z" - } + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_state_city(psi)" - ] + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3" }, - { - "cell_type": "code", - "execution_count": 25, - "id": "1948ad39-e5a6-4f78-943a-53b0f32a4ec1", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:56.152890Z", - "start_time": "2021-07-31T05:08:55.944830Z" - } - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_state_hinton(psi)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "678e9add-f8e5-499c-8535-11be8071bd48", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:58.220624Z", - "start_time": "2021-07-31T05:08:56.933497Z" - }, - "tags": [ - "nbsphinx-thumbnail" - ] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_state_qsphere(psi)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "d91b2b00-794b-48e5-bfa2-3d8156d7ab3e", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:58.370300Z", - "start_time": "2021-07-31T05:08:58.223788Z" - } - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_state_paulivec(psi)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "c399a2a8-81e5-4833-aad9-068bfe0ca169", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:08:59.932552Z", - "start_time": "2021-07-31T05:08:59.518913Z" - } - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_bloch_multivector(psi)" - ] - }, - { - "cell_type": "markdown", - "id": "8a08b04a-8d53-433f-a49d-065c3903555d", - "metadata": {}, - "source": [ - "Here we see that there is no information about the quantum state in the single-qubit space as all vectors are zero." - ] - }, - { - "cell_type": "markdown", - "id": "8ad1ee6e-8677-43c0-bdc9-12d8b0516ab4", - "metadata": {}, - "source": [ - "### Options when using state plotting functions\n", - "\n", - "The various functions for plotting quantum states provide a number of options to adjust how the plots are rendered. Which options are available depends on the function being used." - ] - }, - { - "cell_type": "markdown", - "id": "3e0866d0-23a0-4b81-a476-b24d6965faca", - "metadata": {}, - "source": [ - "#### **plot_state_city()** options\n", - "\n", - "- **title** (str): a string that represents the plot title\n", - "- **figsize** (tuple): figure size in inches (width, height)\n", - "- **color** (list): a list of len=2 giving colors for real and imaginary components of matrix elements" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "d0a22ea7-2305-45e2-a983-9fc9cbfec604", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:09:02.178208Z", - "start_time": "2021-07-31T05:09:01.864008Z" - }, - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_state_city(psi, title=\"My City\", color=['black', 'orange'])" - ] - }, - { - "cell_type": "markdown", - "id": "1cb0fdaa-2096-4f72-871e-39e61298d42f", - "metadata": {}, - "source": [ - "#### **plot_state_hinton()** options\n", - "\n", - "- **title** (str): a string that represents the plot title\n", - "- **figsize** (tuple): figure size in inches (width, height)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "16e544c0-fcd2-44ef-b2f2-b853a5b75750", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:09:03.630399Z", - "start_time": "2021-07-31T05:09:03.400479Z" - }, - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_state_hinton(psi, title=\"My Hinton\")" - ] - }, - { - "cell_type": "markdown", - "id": "fc112cbf-28dd-44b2-a151-6ace7cafbbea", - "metadata": {}, - "source": [ - "#### **plot_state_paulivec()** options\n", - "\n", - "- **title** (str): a string that represents the plot title\n", - "- **figsize** (tuple): figure size in inches (width, height)\n", - "- **color** (list or str): color of the expectation value bars" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "001d6503-327c-4969-8b03-a0f1a106793c", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:09:05.915291Z", - "start_time": "2021-07-31T05:09:05.790887Z" - }, - "scrolled": false - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_state_paulivec(psi, title=\"My Paulivec\", color=['purple', 'orange', 'green'])" - ] - }, - { - "cell_type": "markdown", - "id": "ab38318f-d00e-4204-b929-33146ca439f1", - "metadata": {}, - "source": [ - "#### **plot_state_qsphere()** options\n", - "\n", - "- **figsize** (tuple): figure size in inches (width, height)" - ] - }, - { - "cell_type": "markdown", - "id": "a00a1151-7eb3-45be-b6b3-8c4466620462", - "metadata": {}, - "source": [ - "#### **plot_bloch_multivector()** options\n", - "\n", - "- **title** (str): a string that represents the plot title\n", - "- **figsize** (tuple): figure size in inches (width, height)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "8a1f316f-cd58-46cb-9898-9a236b061378", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:09:08.540562Z", - "start_time": "2021-07-31T05:09:08.227233Z" - }, - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_bloch_multivector(psi, title=\"My Bloch Spheres\")" - ] - }, - { - "cell_type": "markdown", - "id": "95ea1614-0973-40ff-bb3e-013cfee5838d", - "metadata": {}, - "source": [ - "### Use the output from state plotting functions\n", - "\n", - "The state plotting functions return a `matplotlib.Figure` for the rendered visualization. Jupyter notebooks understand this return type and render it properly, but when running outside of Jupyter, this feature is not automatic. However, the `matplotlib.Figure` class natively has methods to both display and save the visualization. You can call `.show()` on the returned object to open the image in a new window (assuming your configured matplotlib backend is interactive). Alternatively, call `.savefig('out.png')` to save the figure to `out.png` in the current working directory. The `savefig()` method takes a path so you can adjust the location and filename where you're saving the output." - ] - }, - { - "cell_type": "markdown", - "id": "ad6de1a0-9603-428d-a11a-7815ffa73aec", - "metadata": {}, - "source": [ - "## Plot Bloch vector \n", - "\n", - "A standard way to plot a quantum system is with the Bloch vector. This only works for a single qubit and takes as input the Bloch vector.\n", - "\n", - "The Bloch vector is defined as $[x = \\mathrm{Tr}[X \\rho], y = \\mathrm{Tr}[Y \\rho], z = \\mathrm{Tr}[Z \\rho]]$, where $X$, $Y$, and $Z$ are the Pauli operators for a single qubit and $\\rho$ is the density matrix." - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "05d82e69-2df0-4122-8cc8-ab563b8caf63", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:09:13.556822Z", - "start_time": "2021-07-31T05:09:13.553512Z" - } - }, - "outputs": [], - "source": [ - "from qiskit.visualization import plot_bloch_vector" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "6d5155ab-e087-4c9b-9675-623db965250e", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:09:14.078221Z", - "start_time": "2021-07-31T05:09:13.830668Z" - } - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_bloch_vector([0,1,0])" - ] - }, - { - "cell_type": "markdown", - "id": "6cb1b0d8-59cd-449b-96ec-773d69ed0f4b", - "metadata": {}, - "source": [ - "### Options for plot_bloch_vector()\n", - "\n", - "- **title** (str): a string that represents the plot title\n", - "- **figsize** (tuple): Figure size in inches (width, height)" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "26eca4ad-433c-43e7-9190-db0246807244", - "metadata": { - "ExecuteTime": { - "end_time": "2021-07-31T05:09:16.121246Z", - "start_time": "2021-07-31T05:09:15.903295Z" - } - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "
" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_bloch_vector([0,1,0], title='My Bloch Sphere')" - ] - }, - { - "cell_type": "markdown", - "id": "800fd906-0266-4c8c-8f20-7c220f3b64e8", - "metadata": {}, - "source": [ - "### Adjust the output from plot_bloch_vector()\n", - "\n", - "The `plot_bloch_vector` function returns a `matplotlib.Figure` for the rendered visualization. Jupyter notebooks understand this return type and render it properly, but when running outside of Jupyter, this feature is not automatic. However, the `matplotlib.Figure` class natively has methods to both display and save the visualization. You can call `.show()` on the returned object to open the image in a new window (assuming your configured matplotlib backend is interactive). Alternatively, call `.savefig('out.png')` to save the figure to `out.png` in the current working directory. The `savefig()` method takes a path so you can adjust the location and filename where you're saving the output." - ] - }, - { - "cell_type": "markdown", - "id": "270428f8-736f-4de4-ac54-d71bbeff106b", - "metadata": {}, - "source": [ - "## Next steps\n", - "\n", - "\n", - " - See an example of circuit visualization in the [Grover's Algorithm](https://learning.quantum.ibm.com/tutorial/grovers-algorithm) tutorial.\n", - " - Visualize simple circuits in the [Explore gates and circuits with the Quantum Composer](https://learning.quantum.ibm.com/tutorial/explore-gates-and-circuits-with-the-quantum-composer) tutorial.\n", - " - Review the [Qiskit visualizations API documentation](/api/qiskit/visualization).\n", - "" - ] - } - ], - "metadata": { - "anaconda-cloud": {}, - "celltoolbar": "Tags", - "description": "Create visualizations of circuits and plot job data using the Qiskit visualization module ", - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3" - }, - "title": "Visualize circuits", - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - }, - "vscode": { - "interpreter": { - "hash": "e6bd4a3f608106bb98e03db025c716fec5b1c45149c5607eb898d72d2cb3836e" - } - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": { - "914030e209ab418f8c633dd6e8b5e4f2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HTMLStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "2.0.0", - "_model_name": "HTMLStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "StyleView", - "background": null, - "description_width": "", - "font_size": null, - "text_color": null - } - }, - "ba8e23e94da44f7d9d779cb1bbdb0f79": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "2.0.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "2.0.0", - "_view_name": "HTMLView", - "description": "", - "description_allow_html": false, - "layout": "IPY_MODEL_f214fd1835684365922b79d6a28add28", - "placeholder": "​", - "style": "IPY_MODEL_914030e209ab418f8c633dd6e8b5e4f2", - "tabbable": null, - "tooltip": null, - "value": "

Circuit Properties

" - } - }, - "f214fd1835684365922b79d6a28add28": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": "0px 0px 10px 0px", - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - } - }, - "version_major": 2, - "version_minor": 0 - } - } + "title": "Visualize circuits" }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 4 } diff --git a/docs/analyze/save-and-retrieve.ipynb b/docs/build/save-circuits.ipynb similarity index 64% rename from docs/analyze/save-and-retrieve.ipynb rename to docs/build/save-circuits.ipynb index 463b824d8bc..5d6373bb6d0 100644 --- a/docs/analyze/save-and-retrieve.ipynb +++ b/docs/build/save-circuits.ipynb @@ -5,11 +5,7 @@ "id": "539f98fa-9ccc-472a-99da-ebe6382243dc", "metadata": {}, "source": [ - "# Save and retrieve Qiskit objects\n", - "\n", - "Quantum workflows often take a while to complete and can run over many sessions. Restarting your Python kernel means you'll lose any circuits or results stored in memory. To avoid loss of data, you can save quantum circuits to file and retrieve results of past jobs from IBM Quantum™ so your next session can continue where you left off.\n", - "\n", - "## Save circuits to file\n", + "# Save circuits to disk\n", "\n", "Use [QPY serialization](/api/qiskit/qpy) to save your circuit to file. QPY files store the full Qiskit circuit object and will be compatible with newer versions of Qiskit (although not necessarily with older versions of Qiskit).\n", "\n", @@ -102,228 +98,6 @@ "import pathlib\n", "pathlib.Path('test.qpy').unlink()" ] - }, - { - "cell_type": "markdown", - "id": "73f23256-6519-47ae-b9e3-700f52a76711", - "metadata": {}, - "source": [ - "## Retrieve jobs from IBM Quantum\n", - "\n", - "IBM Quantum automatically stores results from every job for you to retrieve at a later date. Use this feature to continue quantum programs across kernel restarts and review past results. You can get the ID of a job programmatically through its `job_id` method, or you can see all your submitted jobs and their IDs through the [Jobs dashboard](https://quantum.ibm.com/jobs).\n", - "\n", - "To demonstrate, the following cell sets up the Qiskit Runtime service and selects a backend." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "5f5aaa14-910f-401c-b109-73ffc2450f3c", - "metadata": {}, - "outputs": [], - "source": [ - "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler\n", - "service = QiskitRuntimeService()\n", - "backend = service.least_busy(operational=True, min_num_qubits=2)\n", - "sampler = Sampler(backend=backend)" - ] - }, - { - "cell_type": "markdown", - "id": "02623345-c252-4963-be89-a074d4a10f54", - "metadata": {}, - "source": [ - "The following cell submits the job and prints its ID." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "721a5198-a650-4db9-b041-b3a569c6dc20", - "metadata": { - "tags": [ - "ignore-warnings" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "co24umeh1p25p1m5nu7g\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/qiskit/.venv/python3.11/site-packages/qiskit_ibm_runtime/qiskit_runtime_service.py:879: UserWarning: Cloud simulators will be deprecated on 15 May 2024. Use the new local testing mode in qiskit-ibm-runtime version 0.22.0 or later to meet your debugging needs.\n", - " warnings.warn(warning_message)\n" - ] - } - ], - "source": [ - "from qiskit import transpile\n", - "job = sampler.run(transpile(qc, backend), shots=10)\n", - "my_id = job.job_id()\n", - "print(my_id)" - ] - }, - { - "cell_type": "markdown", - "id": "fb271ce3-3e86-476c-ae4e-66df36ba7406", - "metadata": {}, - "source": [ - "Now that you have the job's ID, you can retrieve it in a different session or at a later date using the `service.job` method." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "da02c7ca-803a-4426-8dd0-bbe062c0e9e1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "PrimitiveResult([PubResult(data=DataBin<>(meas=BitArray()), metadata={'circuit_metadata': {}})], metadata={'version': 2})" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "retrieved_job = service.job(my_id)\n", - "retrieved_job.result()" - ] - }, - { - "cell_type": "markdown", - "id": "9aae5f5a-a543-493c-9bc5-5682ba846ab5", - "metadata": {}, - "source": [ - "### Programmatically find jobs\n", - "\n", - "If you don't have a job ID and want to find it programmatically rather than visiting the [Jobs dashboard](https://quantum.ibm.com/jobs), you can use the [`QiskitRuntimeService.jobs`](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.QiskitRuntimeService#jobs) method.\n", - "\n", - "The following cell finds any jobs submitted in the last hour. The `created_after` argument must be a [`datetime.datetime`](https://docs.python.org/3.8/library/datetime.html#datetime.datetime) object." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "90133394-3259-487f-96b2-3b50e0274064", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[,\n", - " ]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import datetime\n", - "one_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)\n", - "\n", - "service = QiskitRuntimeService()\n", - "service.jobs(created_after=one_hour_ago)" - ] - }, - { - "cell_type": "markdown", - "id": "60405a95-8d79-4ece-9f36-47299cfa3311", - "metadata": {}, - "source": [ - "You can also select by backend, job state, session, and more. For more information, see [`QiskitRuntimeService.jobs`](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.QiskitRuntimeService#jobs) in the API documentation." - ] - }, - { - "cell_type": "markdown", - "id": "211b8c15-5aa3-43f6-82ee-2bd1d49ae8fc", - "metadata": {}, - "source": [ - "## Save results to disk\n", - "\n", - "You may also want to save results to disk. To do this, use Python's built-in JSON library with Qiskit IBM Runtime's encoders." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "3a3ff817-01c1-47e8-94c6-1ecf2215ef7c", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "from qiskit_ibm_runtime import RuntimeEncoder\n", - "with open(\"result.json\", \"w\") as file:\n", - " json.dump(job.result(), file, cls=RuntimeEncoder)" - ] - }, - { - "cell_type": "markdown", - "id": "40a9d8e5-c876-47a7-862e-d2ce535a6052", - "metadata": {}, - "source": [ - "You can then load this array from disk in a separate kernel." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "316aa6f7-faee-4a05-a7b4-02d7bee4d58a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[3],\n", - " [3],\n", - " [3],\n", - " [3],\n", - " [0],\n", - " [3],\n", - " [0],\n", - " [3],\n", - " [0],\n", - " [3]], dtype=uint8)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from qiskit_ibm_runtime import RuntimeDecoder\n", - "with open(\"result.json\", \"r\") as file:\n", - " result = json.load(file, cls=RuntimeDecoder)\n", - "\n", - "result[0].data.meas.array # access measurement data" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "eae94b73-157b-4751-8dd3-add4cc9efec6", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# Cleanup the file we created (this cell should be hidden from the user)\n", - "pathlib.Path('result.json').unlink()" - ] } ], "metadata": { diff --git a/docs/run/_toc.json b/docs/run/_toc.json index 87958610433..07897016605 100644 --- a/docs/run/_toc.json +++ b/docs/run/_toc.json @@ -75,9 +75,17 @@ { "title": "Maximum execution time", "url": "/run/max-execution-time" + }, + { + "title": "Save and retrieve jobs", + "url": "/run/save-jobs" } ] }, + { + "title": "Visualize results", + "url": "/run/visualize-results" + }, { "title": "Quantum Serverless workloads", "url": "/run/quantum-serverless" @@ -129,4 +137,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/docs/run/save-jobs.ipynb b/docs/run/save-jobs.ipynb new file mode 100644 index 00000000000..27422078f5f --- /dev/null +++ b/docs/run/save-jobs.ipynb @@ -0,0 +1,203 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "539f98fa-9ccc-472a-99da-ebe6382243dc", + "metadata": {}, + "source": [ + "# Save and retrieve jobs\n", + "\n", + "Quantum workflows often take a while to complete and can run over many sessions. Restarting your Python kernel means you'll lose any results stored in memory. To avoid loss of data, you can save results to file and retrieve results of past jobs from IBM Quantum™ so your next session can continue where you left off." + ] + }, + { + "cell_type": "markdown", + "id": "73f23256-6519-47ae-b9e3-700f52a76711", + "metadata": {}, + "source": [ + "## Retrieve jobs from IBM Quantum\n", + "\n", + "IBM Quantum automatically stores results from every job for you to retrieve at a later date. Use this feature to continue quantum programs across kernel restarts and review past results. You can get the ID of a job programmatically through its `job_id` method, or you can see all your submitted jobs and their IDs through the [Jobs dashboard](https://quantum.ibm.com/jobs).\n", + "\n", + "Once you have the job ID, use the `QiskitRuntimeService.jobs` method to retrieve it." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "da02c7ca-803a-4426-8dd0-bbe062c0e9e1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "PrimitiveResult([PubResult(data=DataBin(meas=BitArray()), metadata={'circuit_metadata': {}})], metadata={'version': 2})" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit_ibm_runtime import QiskitRuntimeService\n", + "\n", + "service = QiskitRuntimeService()\n", + "retrieved_job = service.job(\"cogiau7imm49f6et38a0\")\n", + "retrieved_job.result()" + ] + }, + { + "cell_type": "markdown", + "id": "9aae5f5a-a543-493c-9bc5-5682ba846ab5", + "metadata": {}, + "source": [ + "### Programmatically find jobs\n", + "\n", + "If you don't have a job ID and want to find it programmatically rather than visiting the [Jobs dashboard](https://quantum.ibm.com/jobs), you can use the [`QiskitRuntimeService.jobs`](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.QiskitRuntimeService#jobs) method.\n", + "\n", + "The following cell finds any jobs submitted in the last hour. The `created_after` argument must be a [`datetime.datetime`](https://docs.python.org/3.8/library/datetime.html#datetime.datetime) object." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "90133394-3259-487f-96b2-3b50e0274064", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ,\n", + " ]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import datetime\n", + "one_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)\n", + "\n", + "service = QiskitRuntimeService()\n", + "service.jobs(created_after=one_hour_ago)" + ] + }, + { + "cell_type": "markdown", + "id": "60405a95-8d79-4ece-9f36-47299cfa3311", + "metadata": {}, + "source": [ + "You can also select by backend, job state, session, and more. For more information, see [`QiskitRuntimeService.jobs`](/api/qiskit-ibm-runtime/qiskit_ibm_runtime.QiskitRuntimeService#jobs) in the API documentation." + ] + }, + { + "cell_type": "markdown", + "id": "211b8c15-5aa3-43f6-82ee-2bd1d49ae8fc", + "metadata": {}, + "source": [ + "## Save results to disk\n", + "\n", + "You may also want to save results to disk. To do this, use Python's built-in JSON library with Qiskit IBM Runtime's encoders." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3a3ff817-01c1-47e8-94c6-1ecf2215ef7c", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "from qiskit_ibm_runtime import RuntimeEncoder\n", + "with open(\"result.json\", \"w\") as file:\n", + " json.dump(retrieved_job.result(), file, cls=RuntimeEncoder)" + ] + }, + { + "cell_type": "markdown", + "id": "40a9d8e5-c876-47a7-862e-d2ce535a6052", + "metadata": {}, + "source": [ + "You can then load this array from disk in a separate kernel." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "316aa6f7-faee-4a05-a7b4-02d7bee4d58a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1],\n", + " [3],\n", + " [3],\n", + " [2],\n", + " [2],\n", + " [1],\n", + " [2],\n", + " [3],\n", + " [0],\n", + " [3]], dtype=uint8)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit_ibm_runtime import RuntimeDecoder\n", + "with open(\"result.json\", \"r\") as file:\n", + " result = json.load(file, cls=RuntimeDecoder)\n", + "\n", + "result[0].data.meas.array # access measurement data" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "eae94b73-157b-4751-8dd3-add4cc9efec6", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "# Cleanup the file we created (this cell should be hidden from the user)\n", + "import pathlib\n", + "pathlib.Path('result.json').unlink()" + ] + } + ], + "metadata": { + "description": "Store Qiskit objects on disk or in the cloud so you can continue where you left off", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3" + }, + "title": "Save and retrieve Qiskit objects" + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/analyze/visualize-results.ipynb b/docs/run/visualize-results.ipynb similarity index 100% rename from docs/analyze/visualize-results.ipynb rename to docs/run/visualize-results.ipynb diff --git a/docs/verify/_toc.json b/docs/verify/_toc.json index 765e883501d..67fb5946f7b 100644 --- a/docs/verify/_toc.json +++ b/docs/verify/_toc.json @@ -22,6 +22,10 @@ "title": "Build noise models", "url": "/verify/building_noise_models" }, + { + "title": "Plot quantum states", + "url": "/verify/plot-quantum-states" + }, { "title": "Efficient simulation of stabilizer circuits with Qiskit Aer primitives", "url": "/verify/stabilizer-circuit-simulation" diff --git a/docs/build-new/plot-quantum-states.ipynb b/docs/verify/plot-quantum-states.ipynb similarity index 100% rename from docs/build-new/plot-quantum-states.ipynb rename to docs/verify/plot-quantum-states.ipynb diff --git a/scripts/nb-tester/test-notebook.py b/scripts/nb-tester/test-notebook.py index 6a8b88618b5..967b0621810 100644 --- a/scripts/nb-tester/test-notebook.py +++ b/scripts/nb-tester/test-notebook.py @@ -32,7 +32,7 @@ ] NOTEBOOKS_THAT_SUBMIT_JOBS = [ "docs/start/hello-world.ipynb", - "docs/analyze/saving-and-retrieving.ipynb", + "docs/run/save-and-retrieve.ipynb", "tutorials/build-repitition-codes/notebook.ipynb", "tutorials/chsh-inequality/notebook.ipynb", "tutorials/grovers-algorithm/notebook.ipynb",