{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Left ventricle bullseye\n\nThis example demonstrates how to create the 17 segment model for the left\nventricle recommended by the American Heart Association (AHA).\n\n.. redirect-from:: /gallery/specialty_plots/leftventricle_bulleye\n\nSee also the :doc:`/gallery/pie_and_polar_charts/nested_pie` example.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nimport matplotlib as mpl\n\n\ndef bullseye_plot(ax, data, seg_bold=None, cmap=\"viridis\", norm=None):\n    \"\"\"\n    Bullseye representation for the left ventricle.\n\n    Parameters\n    ----------\n    ax : Axes\n    data : list[float]\n        The intensity values for each of the 17 segments.\n    seg_bold : list[int], optional\n        A list with the segments to highlight.\n    cmap : colormap, default: \"viridis\"\n        Colormap for the data.\n    norm : Normalize or None, optional\n        Normalizer for the data.\n\n    Notes\n    -----\n    This function creates the 17 segment model for the left ventricle according\n    to the American Heart Association (AHA) [1]_\n\n    References\n    ----------\n    .. [1] M. D. Cerqueira, N. J. Weissman, V. Dilsizian, A. K. Jacobs,\n        S. Kaul, W. K. Laskey, D. J. Pennell, J. A. Rumberger, T. Ryan,\n        and M. S. Verani, \"Standardized myocardial segmentation and\n        nomenclature for tomographic imaging of the heart\",\n        Circulation, vol. 105, no. 4, pp. 539-542, 2002.\n    \"\"\"\n\n    data = np.ravel(data)\n    if seg_bold is None:\n        seg_bold = []\n    if norm is None:\n        norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())\n\n    r = np.linspace(0.2, 1, 4)\n\n    ax.set(ylim=(0, 1), xticklabels=[], yticklabels=[])\n    ax.grid(False)  # Remove grid\n\n    # Fill segments 1-6, 7-12, 13-16.\n    for start, stop, r_in, r_out in [\n            (0, 6, r[2], r[3]),\n            (6, 12, r[1], r[2]),\n            (12, 16, r[0], r[1]),\n            (16, 17, 0, r[0]),\n    ]:\n        n = stop - start\n        dtheta = 2*np.pi / n\n        ax.bar(np.arange(n) * dtheta + np.pi/2, r_out - r_in, dtheta, r_in,\n               color=cmap(norm(data[start:stop])))\n\n    # Now, draw the segment borders.  In order for the outer bold borders not\n    # to be covered by inner segments, the borders are all drawn separately\n    # after the segments have all been filled.  We also disable clipping, which\n    # would otherwise affect the outermost segment edges.\n    # Draw edges of segments 1-6, 7-12, 13-16.\n    for start, stop, r_in, r_out in [\n            (0, 6, r[2], r[3]),\n            (6, 12, r[1], r[2]),\n            (12, 16, r[0], r[1]),\n    ]:\n        n = stop - start\n        dtheta = 2*np.pi / n\n        ax.bar(np.arange(n) * dtheta + np.pi/2, r_out - r_in, dtheta, r_in,\n               clip_on=False, color=\"none\", edgecolor=\"k\", linewidth=[\n                   4 if i + 1 in seg_bold else 2 for i in range(start, stop)])\n    # Draw edge of segment 17 -- here; the edge needs to be drawn differently,\n    # using plot().\n    ax.plot(np.linspace(0, 2*np.pi), np.linspace(r[0], r[0]), \"k\",\n            linewidth=(4 if 17 in seg_bold else 2))\n\n\n# Create the fake data\ndata = np.arange(17) + 1\n\n\n# Make a figure and Axes with dimensions as desired.\nfig = plt.figure(figsize=(10, 5), layout=\"constrained\")\nfig.get_layout_engine().set(wspace=.1, w_pad=.2)\naxs = fig.subplots(1, 3, subplot_kw=dict(projection='polar'))\nfig.canvas.manager.set_window_title('Left Ventricle Bulls Eyes (AHA)')\n\n\n# Set the colormap and norm to correspond to the data for which\n# the colorbar will be used.\ncmap = mpl.colormaps[\"viridis\"]\nnorm = mpl.colors.Normalize(vmin=1, vmax=17)\n# Create an empty ScalarMappable to set the colorbar's colormap and norm.\n# The following gives a basic continuous colorbar with ticks and labels.\nfig.colorbar(mpl.cm.ScalarMappable(cmap=cmap, norm=norm),\n             cax=axs[0].inset_axes([0, -.15, 1, .1]),\n             orientation='horizontal', label='Some units')\n\n\n# And again for the second colorbar.\ncmap2 = mpl.colormaps[\"cool\"]\nnorm2 = mpl.colors.Normalize(vmin=1, vmax=17)\nfig.colorbar(mpl.cm.ScalarMappable(cmap=cmap2, norm=norm2),\n             cax=axs[1].inset_axes([0, -.15, 1, .1]),\n             orientation='horizontal', label='Some other units')\n\n\n# The second example illustrates the use of a ListedColormap, a\n# BoundaryNorm, and extended ends to show the \"over\" and \"under\"\n# value colors.\ncmap3 = mpl.colors.ListedColormap(['r', 'g', 'b', 'c'], over='0.35', under='0.75')\n# If a ListedColormap is used, the length of the bounds array must be\n# one greater than the length of the color list.  The bounds must be\n# monotonically increasing.\nbounds = [2, 3, 7, 9, 15]\nnorm3 = mpl.colors.BoundaryNorm(bounds, cmap3.N)\nfig.colorbar(mpl.cm.ScalarMappable(cmap=cmap3, norm=norm3),\n             cax=axs[2].inset_axes([0, -.15, 1, .1]),\n             extend='both',\n             ticks=bounds,  # optional\n             spacing='proportional',\n             orientation='horizontal',\n             label='Discrete intervals, some other units')\n\n\n# Create the 17 segment model\nbullseye_plot(axs[0], data, cmap=cmap, norm=norm)\naxs[0].set_title('Bulls Eye (AHA)')\n\nbullseye_plot(axs[1], data, cmap=cmap2, norm=norm2)\naxs[1].set_title('Bulls Eye (AHA)')\n\nbullseye_plot(axs[2], data, seg_bold=[3, 5, 6, 11, 12, 16],\n              cmap=cmap3, norm=norm3)\naxs[2].set_title('Segments [3, 5, 6, 11, 12, 16] in bold')\n\nplt.show()"
      ]
    }
  ],
  "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.14.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}