{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Angle annotations on bracket arrows\n\nThis example shows how to add angle annotations to bracket arrow styles\ncreated using `.FancyArrowPatch`. *angleA* and *angleB* are measured from a\nvertical line as positive (to the left) or negative (to the right). Blue\n`.FancyArrowPatch` arrows indicate the directions of *angleA* and *angleB*\nfrom the vertical and axes text annotate the angle sizes.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nfrom matplotlib.patches import FancyArrowPatch\n\n\ndef get_point_of_rotated_vertical(origin, line_length, degrees):\n    \"\"\"Return xy coordinates of the vertical line end rotated by degrees.\"\"\"\n    rad = np.deg2rad(-degrees)\n    return [origin[0] + line_length * np.sin(rad),\n            origin[1] + line_length * np.cos(rad)]\n\n\nfig, ax = plt.subplots()\nax.set(xlim=(0, 6), ylim=(-1, 5))\nax.set_title(\"Orientation of the bracket arrows relative to angleA and angleB\")\n\nstyle = ']-['\nfor i, angle in enumerate([-40, 0, 60]):\n    y = 2*i\n    arrow_centers = ((1, y), (5, y))\n    vlines = ((1, y + 0.5), (5, y + 0.5))\n    anglesAB = (angle, -angle)\n    bracketstyle = f\"{style}, angleA={anglesAB[0]}, angleB={anglesAB[1]}\"\n    bracket = FancyArrowPatch(*arrow_centers, arrowstyle=bracketstyle,\n                              mutation_scale=42)\n    ax.add_patch(bracket)\n    ax.text(3, y + 0.05, bracketstyle, ha=\"center\", va=\"bottom\", fontsize=14)\n    ax.vlines([line[0] for line in vlines], [y, y], [line[1] for line in vlines],\n              linestyles=\"--\", color=\"C0\")\n    # Get the top coordinates for the drawn patches at A and B\n    patch_tops = [get_point_of_rotated_vertical(center, 0.5, angle)\n                  for center, angle in zip(arrow_centers, anglesAB)]\n    # Define the connection directions for the annotation arrows\n    connection_dirs = (1, -1) if angle > 0 else (-1, 1)\n    # Add arrows and annotation text\n    arrowstyle = \"Simple, tail_width=0.5, head_width=4, head_length=8\"\n    for vline, dir, patch_top, angle in zip(vlines, connection_dirs,\n                                            patch_tops, anglesAB):\n        kw = dict(connectionstyle=f\"arc3,rad={dir * 0.5}\",\n                  arrowstyle=arrowstyle, color=\"C0\")\n        ax.add_patch(FancyArrowPatch(vline, patch_top, **kw))\n        ax.text(vline[0] - dir * 0.15, y + 0.7, f'{angle}\u00b0', ha=\"center\",\n                va=\"center\")\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. admonition:: References\n\n   The use of the following functions, methods, classes and modules is shown\n   in this example:\n\n   - `matplotlib.patches.ArrowStyle`\n\n"
      ]
    }
  ],
  "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
}