{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "7e6b2936-3a18-4917-9c47-30e2d4ce5775",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"결과 시각화\"\n",
        "description: \"Qiskit을 사용하여 양자 회로 실행 결과를 플롯합니다\"\n",
        "---\n",
        "\n",
        "<span id=\"visualize-results\" />\n",
        "\n",
        "# 결과 시각화\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=\"패키지 버전\">\n",
        "    이 페이지의 코드는 다음 요구 사항을 사용하여 개발되었습니다.\n",
        "    다음 버전 이상을 사용하는 것이 좋습니다.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.2\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e8d0138c-fd97-49c2-88a5-1929a5a09258",
      "metadata": {},
      "source": [
        "<span id=\"plot-histogram\" />\n",
        "\n",
        "## 플롯 히스토그램\n",
        "\n",
        "`plot_histogram` 함수는 QPU에서 양자 회로를 샘플링한 결과를 시각화합니다.\n",
        "\n",
        "<Admonition title=\"함수 출력 사용\" type=\"tip\">\n",
        "  이 함수는 `matplotlib.Figure` 객체를 반환합니다. 코드 셀의 마지막 줄에서 이러한 객체를 출력하면 Jupyter 노트북은 해당 객체를 셀 아래에 표시합니다. 다른 환경이나 스크립트에서 이러한 함수를 호출하는 경우 출력을 명시적으로 표시하거나 저장해야 합니다.\n",
        "\n",
        "  두 가지 옵션이 있습니다:\n",
        "\n",
        "  * 반환된 객체에서 `.show()` 을 호출하여 새 창에서 이미지를 엽니다(구성된 matplotlib 백엔드가 대화형이라고 가정).\n",
        "  * `.savefig(\"out.png\")` 으로 전화하여 현재 작업 디렉터리의 `out.png` 에 그림을 저장합니다. `savefig()` 메서드는 경로를 사용하므로 출력을 저장할 위치와 파일명을 조정할 수 있습니다. 예: `plot_state_city(psi).savefig(\"out.png\")`.\n",
        "</Admonition>\n",
        "\n",
        "예를 들어 2쿼비트 벨 상태를 만들 수 있습니다:\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": [
        "<span id=\"options-when-plotting-a-histogram\" />\n",
        "\n",
        "### 히스토그램을 그릴 때의 옵션\n",
        "\n",
        "`plot_histogram` 에 다음 옵션을 사용하여 출력 그래프를 조정합니다.\n",
        "\n",
        "* `legend`: 실행에 대한 레이블을 제공합니다. 각 실행 결과에 레이블을 지정하는 데 사용되는 문자열 목록이 필요합니다. 이 기능은 여러 실행 결과를 동일한 히스토그램에 표시할 때 주로 유용합니다\n",
        "* `sort`: 히스토그램에서 막대의 순서를 조정합니다. `asc` 를 사용하여 오름차순 또는 내림차순으로 설정할 수 있습니다 `desc`\n",
        "* `number_to_keep`: 표시할 용어의 수를 정수로 받습니다. 나머지는 \"휴식\"이라는 단일 막대에 함께 그룹화됩니다\n",
        "* `color`: 막대의 색상을 조정합니다. 각 실행에 대해 막대에 사용할 색상에 대한 문자열 또는 문자열 목록을 받습니다\n",
        "* `bar_labels`: 막대 위에 레이블을 인쇄할지 여부를 조정합니다\n",
        "* `figsize`: 출력 수치를 만들기 위해 인치 단위 크기의 튜플을 취합니다\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": [
        "<span id=\"plot-estimator-results\" />\n",
        "\n",
        "## 플롯 추정기 결과\n",
        "\n",
        "키스킷에는 추정기 결과를 플로팅하는 기능이 내장되어 있지 않지만, Matplotlib 의 [`bar` 플로팅을](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar.html) 사용하여 빠르게 시각화할 수 있습니다.\n",
        "\n",
        "이를 설명하기 위해 다음 셀은 양자 상태에 대한 7가지 관측 변수의 기대값을 추정합니다.\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": [
        "다음 셀은 각 결과의 추정 [표준 오차를](https://en.wikipedia.org/wiki/Standard_error) 사용하여 오차 막대로 추가합니다. 플롯에 대한 자세한 설명은 [`bar` 플롯 문서를](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar.html) 참조하세요.\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
}