{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "7e6b2936-3a18-4917-9c47-30e2d4ce5775",
      "metadata": {},
      "source": [
        "---\n",
        "title: Visualize results\n",
        "description: Plot quantum circuit execution results using Qiskit\n",
        "---\n",
        "\n",
        "# Visualize results\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "06a4399f-bca6-4c2e-9128-1494017d0249",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Package versions\">\n",
        "    The code on this page was developed using the following requirements.\n",
        "    We recommend using these versions or newer.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.4.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e8d0138c-fd97-49c2-88a5-1929a5a09258",
      "metadata": {},
      "source": [
        "## Plot histogram\n",
        "\n",
        "The `plot_histogram` function visualizes the result of sampling a quantum circuit on a QPU.\n",
        "\n",
        "<Admonition title=\"Using the output from functions\" type=\"tip\">\n",
        "  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.\n",
        "\n",
        "  Two options are:\n",
        "\n",
        "  * Call `.show()` on the returned object to open the image in a new window (assuming your configured matplotlib backend is interactive).\n",
        "  * 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. For example, `plot_state_city(psi).savefig(\"out.png\")`.\n",
        "</Admonition>\n",
        "\n",
        "For example, make a two-qubit Bell state:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "5cf67f92-a86d-496d-9e13-0d8a841c8dfa",
      "metadata": {
        "tags": [
          "ignore-warnings"
        ]
      },
      "outputs": [],
      "source": [
        "from qiskit.primitives import StatevectorSampler as Sampler\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "from qiskit.circuit import QuantumCircuit\n",
        "from qiskit.visualization import plot_histogram"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "938e8206-d7e8-447d-b798-b7c2507f8901",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "PrimitiveResult([SamplerPubResult(data=DataBin(meas=BitArray(<shape=(), num_shots=1024, num_bits=2>)), metadata={'shots': 1024, 'circuit_metadata': {}})], metadata={'version': 2})\n"
          ]
        }
      ],
      "source": [
        "# Quantum circuit to make a Bell state\n",
        "bell = QuantumCircuit(2)\n",
        "bell.h(0)\n",
        "bell.cx(0, 1)\n",
        "bell.measure_all()\n",
        "\n",
        "pm = generate_preset_pass_manager(optimization_level=1)\n",
        "isa_circuit = pm.run(bell)\n",
        "\n",
        "# execute the quantum circuit\n",
        "sampler = Sampler()\n",
        "job = sampler.run([isa_circuit])\n",
        "result = job.result()\n",
        "\n",
        "print(result)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "57d8053e-d030-460d-9c1f-772e53b1a49b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/visualize-results/extracted-outputs/57d8053e-d030-460d-9c1f-772e53b1a49b-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "plot_histogram(result[0].data.meas.get_counts())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e3a68e3d-21e6-45a0-bc40-f9a2214dd5b3",
      "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 of the bars in the histogram. 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\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "bd70e13f-5c52-42fb-8dde-980b15e3604a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/visualize-results/extracted-outputs/bd70e13f-5c52-42fb-8dde-980b15e3604a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Execute two-qubit Bell state again\n",
        "\n",
        "job = sampler.run([isa_circuit], shots=1000)\n",
        "second_result = job.result()\n",
        "\n",
        "# Plot results with custom options\n",
        "plot_histogram(\n",
        "    [\n",
        "        result[0].data.meas.get_counts(),\n",
        "        second_result[0].data.meas.get_counts(),\n",
        "    ],\n",
        "    legend=[\"first\", \"second\"],\n",
        "    sort=\"desc\",\n",
        "    figsize=(15, 12),\n",
        "    color=[\"orange\", \"black\"],\n",
        "    bar_labels=False,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "019ee04e-0730-4536-94cc-7e2b50d921e1",
      "metadata": {},
      "source": [
        "## Plot Estimator results\n",
        "\n",
        "Qiskit does not have a built-in function for plotting Estimator results, but you can use Matplotlib's [`bar` plot](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar.html) for a quick visualization.\n",
        "\n",
        "To demonstrate, the following cell estimates the expectation values of seven different observables on a quantum state.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "17c9893a-d1bf-4726-b444-6dce1d56805f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "PubResult(data=DataBin(evs=np.ndarray(<shape=(7, 1), dtype=float64>), stds=np.ndarray(<shape=(7, 1), dtype=float64>), shape=(7, 1)), metadata={'target_precision': 0.0, 'circuit_metadata': {}})\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<BarContainer object of 7 artists>"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/visualize-results/extracted-outputs/17c9893a-d1bf-4726-b444-6dce1d56805f-2.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import numpy as np\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.primitives import StatevectorEstimator as Estimator\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from matplotlib import pyplot as plt\n",
        "\n",
        "# Simple estimation experiment to create results\n",
        "qc = QuantumCircuit(2)\n",
        "qc.h(0)\n",
        "qc.crx(1.5, 0, 1)\n",
        "\n",
        "observables_labels = [\"ZZ\", \"XX\", \"YZ\", \"ZY\", \"XY\", \"XZ\", \"ZX\"]\n",
        "observables = [SparsePauliOp(label) for label in observables_labels]\n",
        "\n",
        "pm = generate_preset_pass_manager(optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "isa_observables = [\n",
        "    operator.apply_layout(isa_circuit.layout) for operator in observables\n",
        "]\n",
        "\n",
        "# Reshape observable array for broadcasting\n",
        "reshaped_ops = np.fromiter(isa_observables, dtype=object)\n",
        "reshaped_ops = reshaped_ops.reshape((7, 1))\n",
        "\n",
        "estimator = Estimator()\n",
        "job = estimator.run([(isa_circuit, reshaped_ops)])\n",
        "result = job.result()[0]\n",
        "exp_val = job.result()[0].data.evs\n",
        "print(result)\n",
        "\n",
        "# Since the result array is structured as a 2D array where each element is a\n",
        "# list containing a single value, you need to flatten the array.\n",
        "\n",
        "# Plot using Matplotlib\n",
        "plt.bar(observables_labels, exp_val.flatten())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a520f049-c2ee-4f14-8039-b5be671f25ae",
      "metadata": {},
      "source": [
        "The following cell uses the estimated [standard error](https://en.wikipedia.org/wiki/Standard_error) of each result and adds them as error bars. See the [`bar` plot documentation](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar.html) for a full description of the plot.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "4eb79f4b-36b5-4797-a1a0-67d881d46ca4",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "Text(0.5, 1.0, 'Expectation values (with standard errors)')"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/visualize-results/extracted-outputs/4eb79f4b-36b5-4797-a1a0-67d881d46ca4-1.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "standard_error = job.result()[0].data.stds\n",
        "\n",
        "_, ax = plt.subplots()\n",
        "ax.bar(\n",
        "    observables_labels,\n",
        "    exp_val.flatten(),\n",
        "    yerr=standard_error.flatten(),\n",
        "    capsize=2,\n",
        ")\n",
        "ax.set_title(\"Expectation values (with standard errors)\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}