{"id":5557,"date":"2020-11-29T09:38:29","date_gmt":"2020-11-29T04:08:29","guid":{"rendered":"http:\/\/www.pythonpool.com\/?p=5557"},"modified":"2026-07-13T12:28:55","modified_gmt":"2026-07-13T06:58:55","slug":"matplotlib-arrow","status":"publish","type":"post","link":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/","title":{"rendered":"Matplotlib Arrow: Add, Style, and Annotate Arrows"},"content":{"rendered":"<p><strong>Quick answer:<\/strong> Matplotlib arrows are usually easiest to draw with annotate, where xy is the arrow target and xytext is the start. Choose the coordinate system deliberately, style the arrowhead with arrowprops, and leave enough plot margin for labels and saved output.<\/p>\n<figure class=\"pythonpool-article-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrow.png\" alt=\"Python Pool infographic showing Matplotlib arrow start end annotation style and coordinate choices\" width=\"1536\" height=\"1024\" loading=\"lazy\" decoding=\"async\"><figcaption>An arrow communicates direction between two data points; define its coordinates, head style, and label placement together.<\/figcaption><\/figure>\n<p>Matplotlib arrows are useful for pointing to peaks, showing direction, connecting two points, or marking a change on a plot. The important update is that <code>matplotlib.pyplot.arrow()<\/code> still exists, but the Matplotlib documentation discourages it for many plots because axis limits and aspect ratio can distort the arrow. For most chart annotations, use <code>annotate()<\/code> with <code>arrowprops<\/code>.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #990303;color:#990303\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #990303;color:#990303\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Which_Matplotlib_arrow_API_should_you_use\" >Which Matplotlib arrow API should you use?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Draw_an_arrow_with_annotate\" >Draw an arrow with annotate()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Use_data_and_offset_coordinates_correctly\" >Use data and offset coordinates correctly<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Draw_an_arrow_without_text\" >Draw an arrow without text<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Style_arrows_with_arrowprops\" >Style arrows with arrowprops<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Use_FancyArrowPatch_for_custom_arrows\" >Use FancyArrowPatch for custom arrows<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#What_about_pltarrow\" >What about plt.arrow()?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Common_mistakes\" >Common mistakes<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Related_Matplotlib_guides\" >Related Matplotlib guides<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Official_references\" >Official references<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Draw_A_Data-Space_Arrow\" >Draw A Data-Space Arrow<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Control_The_Coordinate_System\" >Control The Coordinate System<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Style_The_Arrowhead\" >Style The Arrowhead<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Check_The_Exported_Figure\" >Check The Exported Figure<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#Frequently_Asked_Questions\" >Frequently Asked Questions<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Which_Matplotlib_arrow_API_should_you_use\"><\/span>Which Matplotlib arrow API should you use?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li>Use <code>ax.annotate()<\/code> when you want an arrow with a label.<\/li>\n<li>Use <code>ax.annotate(\"\", ...)<\/code> when you want only an arrow and no text.<\/li>\n<li>Use <code>FancyArrowPatch<\/code> when you need a patch object with more control over style, connection, or reuse.<\/li>\n<li>Use <code>plt.arrow()<\/code> only for simple cases where you understand the aspect-ratio limitation.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Draw_an_arrow_with_annotate\"><\/span>Draw an arrow with annotate()<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The most common pattern is to point from label text to a data point. The <code>xy<\/code> argument is the point being annotated, and <code>xytext<\/code> is where the label should appear.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">import matplotlib.pyplot as plt\n\nx = [1, 2, 3]\ny = [2, 6, 4]\n\nfig, ax = plt.subplots()\nax.plot(x, y, marker=\"o\")\n\nax.annotate(\n    \"Peak\",\n    xy=(2, 6),\n    xytext=(2.35, 7.2),\n    arrowprops=dict(arrowstyle=\"-&gt;\", linewidth=2, color=\"tab:blue\"),\n)\n\nplt.show()\n<\/code><\/pre>\n<\/div>\n<p>This approach is usually better than <code>plt.arrow()<\/code> because the arrow is drawn through the annotation system and supports text placement, coordinate choices, clipping behavior, and patch styling.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Use_data_and_offset_coordinates_correctly\"><\/span>Use data and offset coordinates correctly<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>By default, <code>xy<\/code> and <code>xytext<\/code> use data coordinates. That means <code>xy=(2, 6)<\/code> points to the data location where x is 2 and y is 6. This is usually what you want when labeling a point on a line chart, scatter plot, or bar chart.<\/p>\n<p>For labels that should sit a fixed distance away from the point, use offset coordinates. The example below places the text 25 points above and 15 points to the right of the selected point, while the arrow still points to the data location.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">ax.annotate(\n    \"Peak\",\n    xy=(2, 6),\n    xytext=(15, 25),\n    textcoords=\"offset points\",\n    arrowprops=dict(arrowstyle=\"-&gt;\"),\n)\n<\/code><\/pre>\n<\/div>\n<p>This is often easier to maintain than hard-coding another data coordinate for the label position, especially when the data scale changes.<\/p>\n<p><!-- Python Pool visual layout repair 2026-07-13 --><\/p>\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/arrow-primitive-b149.png\" alt=\"Python Pool infographic showing a Matplotlib axes, start point, end point, line, and arrowhead\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>Arrow primitive: A Matplotlib axes, start point, end point, line, and arrowhead.<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Draw_an_arrow_without_text\"><\/span>Draw an arrow without text<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If you only need an arrow, pass an empty string as the annotation text. This is the Matplotlib documentation&#8217;s recommended replacement pattern for many <code>pyplot.arrow()<\/code> examples.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">fig, ax = plt.subplots()\n\nax.annotate(\n    \"\",\n    xy=(0.8, 0.8),\n    xytext=(0.2, 0.2),\n    arrowprops=dict(arrowstyle=\"-&gt;\", linewidth=2),\n)\n\nax.set_xlim(0, 1)\nax.set_ylim(0, 1)\nplt.show()\n<\/code><\/pre>\n<\/div>\n<h2><span class=\"ez-toc-section\" id=\"Style_arrows_with_arrowprops\"><\/span>Style arrows with arrowprops<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The <code>arrowprops<\/code> dictionary controls the arrow that connects <code>xytext<\/code> to <code>xy<\/code>. Common options include <code>arrowstyle<\/code>, <code>color<\/code>, <code>linewidth<\/code>, <code>mutation_scale<\/code>, and <code>connectionstyle<\/code>.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">ax.annotate(\n    \"Change\",\n    xy=(4, 10),\n    xytext=(2.8, 12),\n    arrowprops=dict(\n        arrowstyle=\"-|&gt;\",\n        color=\"tab:green\",\n        linewidth=2,\n        mutation_scale=18,\n        connectionstyle=\"arc3,rad=0.2\",\n    ),\n)\n<\/code><\/pre>\n<\/div>\n<p>Use <code>arrowstyle=\"-&gt;\"<\/code> for a simple arrow, <code>\"&lt;-\"<\/code> to reverse the head, <code>\"&lt;-&gt;\"<\/code> for two heads, and <code>\"-|&gt;\"<\/code> for a filled head. Curved arrows are controlled through <code>connectionstyle<\/code>.<\/p>\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/arrow-style-b149.png\" alt=\"Python Pool infographic comparing arrowstyle, linewidth, color, mutation scale, and z order\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>Arrow style: Arrowstyle, linewidth, color, mutation scale, and z order.<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Use_FancyArrowPatch_for_custom_arrows\"><\/span>Use FancyArrowPatch for custom arrows<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><code>FancyArrowPatch<\/code> is the lower-level patch class behind many annotation arrows. It is useful when you want to create an arrow object directly and add it to an axes.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">from matplotlib.patches import FancyArrowPatch\n\nfig, ax = plt.subplots()\n\narrow = FancyArrowPatch(\n    (0.15, 0.25),\n    (0.85, 0.75),\n    arrowstyle=\"-|&gt;\",\n    mutation_scale=24,\n    linewidth=2,\n    color=\"tab:green\",\n)\n\nax.add_patch(arrow)\nax.set_xlim(0, 1)\nax.set_ylim(0, 1)\nplt.show()\n<\/code><\/pre>\n<\/div>\n<p>For most everyday plots, start with <code>annotate()<\/code>. Move to <code>FancyArrowPatch<\/code> when you need patch-level control.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"What_about_pltarrow\"><\/span>What about plt.arrow()?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The basic syntax is still:<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">plt.arrow(x, y, dx, dy, width=0.01)\n<\/code><\/pre>\n<\/div>\n<p>Here, <code>x<\/code> and <code>y<\/code> are the arrow base, while <code>dx<\/code> and <code>dy<\/code> are the change in x and y direction. The problem is that the arrow shape can look wrong after aspect-ratio changes, zooming, or axis-limit changes. That is why current Matplotlib guidance points users toward <code>annotate()<\/code> for reliable arrows.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Common_mistakes\"><\/span>Common mistakes<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li>Using <code>plt.arrow()<\/code> for publication plots without checking the final aspect ratio.<\/li>\n<li>Confusing <code>xy<\/code> and <code>xytext<\/code>. The arrow points from the text position toward <code>xy<\/code>.<\/li>\n<li>Forgetting to set axis limits when an arrow patch is added outside the current data range.<\/li>\n<li>Using <code>color<\/code> and <code>edgecolor<\/code> inconsistently on patch-based arrows.<\/li>\n<li>Adding arrows before deciding the final <a href=\"https:\/\/www.pythonpool.com\/matplotlib-aspect-ratio\/\">Matplotlib aspect ratio<\/a>.<\/li>\n<\/ul>\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/arrow-annotate-b149.png\" alt=\"Python Pool infographic mapping annotate coordinates through text position, arrowprops, and target point\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>Annotated arrow: Annotate coordinates through text position, arrowprops, and target point.<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Related_Matplotlib_guides\"><\/span>Related Matplotlib guides<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>For more plot annotation work, read our guides on <a href=\"https:\/\/www.pythonpool.com\/matplotlib-annotate\/\">Matplotlib annotate()<\/a>, <a href=\"https:\/\/www.pythonpool.com\/matplotlib-zorder\/\">Matplotlib zorder<\/a>, <a href=\"https:\/\/www.pythonpool.com\/matplotlib-vertical-lines\/\">Matplotlib vertical lines<\/a>, <a href=\"https:\/\/www.pythonpool.com\/matplotlib-tightlayout\/\">Matplotlib tight_layout()<\/a>, and <a href=\"https:\/\/www.pythonpool.com\/matplotlib-gca\/\">Matplotlib gca()<\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Official_references\"><\/span>Official references<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li><a href=\"https:\/\/matplotlib.org\/stable\/api\/_as_gen\/matplotlib.pyplot.arrow.html\">Matplotlib documentation for pyplot.arrow<\/a><\/li>\n<li><a href=\"https:\/\/matplotlib.org\/stable\/api\/_as_gen\/matplotlib.pyplot.annotate.html\">Matplotlib documentation for pyplot.annotate<\/a><\/li>\n<li><a href=\"https:\/\/matplotlib.org\/stable\/api\/_as_gen\/matplotlib.patches.FancyArrowPatch.html\">Matplotlib documentation for FancyArrowPatch<\/a><\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Draw_A_Data-Space_Arrow\"><\/span>Draw A Data-Space Arrow<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>annotate connects two data coordinates and keeps the arrow attached to the plotted values as the axes scale changes. Use a clear arrow style and color.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nax.plot([0, 1, 2], [1, 2, 3])\nax.annotate(\"increase\", xy=(2, 3), xytext=(1, 1.5), arrowprops={\"arrowstyle\": \"-|&gt;\"})\nprint(ax.get_xlim(), ax.get_ylim())\n<\/code><\/pre>\n<\/div>\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/arrow-check-b149.png\" alt=\"Python Pool infographic testing clipping, transforms, multiple arrows, saving, and output layout\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>Arrow checks: Clipping, transforms, multiple arrows, saving, and output layout.<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Control_The_Coordinate_System\"><\/span>Control The Coordinate System<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Data coordinates are not the same as axes-fraction or figure coordinates. If an annotation should stay in a corner, use an appropriate transform rather than guessing data values.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nax.plot([0, 1], [0, 1])\nax.annotate(\"corner\", xy=(0.95, 0.95), xycoords=\"axes fraction\", xytext=(0.7, 0.7), textcoords=\"axes fraction\", arrowprops={\"arrowstyle\": \"-&gt;\"})\nprint(\"annotation added\")\n<\/code><\/pre>\n<\/div>\n<h2><span class=\"ez-toc-section\" id=\"Style_The_Arrowhead\"><\/span>Style The Arrowhead<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>arrowprops can set style, color, line width, connection style, and shrink. Keep the head large enough to see but subordinate to the data.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nax.annotate(\"target\", xy=(4, 4), xytext=(1, 1), arrowprops={\"arrowstyle\": \"-|&gt;\", \"color\": \"darkgreen\", \"linewidth\": 2})\nprint(\"styled arrow\")\n<\/code><\/pre>\n<\/div>\n<h2><span class=\"ez-toc-section\" id=\"Check_The_Exported_Figure\"><\/span>Check The Exported Figure<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>An interactive window can hide clipping that appears in a file. Add margins, choose a suitable z-order, and render the actual output format before publishing it.<\/p>\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\">\n<pre><code class=\"language-python\">import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots(figsize=(5, 3))\nax.annotate(\"edge\", xy=(1, 1), xytext=(0.2, 0.2), arrowprops={\"arrowstyle\": \"-&gt;\"})\nfig.savefig(\"arrow-example.png\", bbox_inches=\"tight\")\nprint(\"saved\")\n<\/code><\/pre>\n<\/div>\n<p>Arrows should answer a visual question rather than decorate an otherwise ambiguous plot. Decide whether the arrow marks a data trend, points to a feature, or indicates a process step. For dense charts, use a legend or short label so several arrows do not overlap. Check the arrow after changing the axis limits, aspect ratio, figure size, or backend because those changes can affect readability. Matplotlib&#8217;s <a href=\"https:\/\/matplotlib.org\/stable\/api\/_as_gen\/matplotlib.axes.Axes.annotate.html\">Axes.annotate()<\/a> reference documents arrow properties and coordinate systems. Related references include <a href=\"https:\/\/www.pythonpool.com\/matplotlib-ylim\/\">axis limits<\/a>, <a href=\"https:\/\/www.pythonpool.com\/matplotlib-savefig\/\">figure export<\/a>, and <a href=\"https:\/\/www.pythonpool.com\/matplotlib-text\/\">text annotations<\/a>.<\/p>\n<p>For related chart controls, compare <a href=\"https:\/\/www.pythonpool.com\/matplotlib-ylim\/\">axis limits<\/a>, <a href=\"https:\/\/www.pythonpool.com\/matplotlib-savefig\/\">figure export<\/a>, and <a href=\"https:\/\/www.pythonpool.com\/matplotlib-text\/\">text annotations<\/a> when placing an arrow.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Frequently_Asked_Questions\"><\/span>Frequently Asked Questions<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3>How do I draw an arrow in Matplotlib?<\/h3>\n<p>Use annotate with an xy target and xytext start, or an arrow patch when you need lower-level control.<\/p>\n<h3>How do I add an arrowhead?<\/h3>\n<p>Pass arrowprops to annotate and choose an arrow style such as -|> along with color and width.<\/p>\n<h3>Why is my arrow in the wrong place?<\/h3>\n<p>Check whether the coordinates are data, axes-fraction, figure, or display coordinates and set the transform deliberately.<\/p>\n<h3>How do I keep an arrow visible in a saved figure?<\/h3>\n<p>Leave enough margin for the head and label, use a suitable z-order, and verify the rendered output rather than only the interactive view.<\/p>\n<p><script type=\"application\/ld+json\">{\"@context\":\"https:\/\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"How do I draw an arrow in Matplotlib?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Use annotate with an xy target and xytext start, or an arrow patch when you need lower-level control.\"}},{\"@type\":\"Question\",\"name\":\"How do I add an arrowhead?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Pass arrowprops to annotate and choose an arrow style such as -|> along with color and width.\"}},{\"@type\":\"Question\",\"name\":\"Why is my arrow in the wrong place?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Check whether the coordinates are data, axes-fraction, figure, or display coordinates and set the transform deliberately.\"}},{\"@type\":\"Question\",\"name\":\"How do I keep an arrow visible in a saved figure?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Leave enough margin for the head and label, use a suitable z-order, and verify the rendered output rather than only the interactive view.\"}}]}<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Draw Matplotlib arrows with annotate and patch controls, position arrowheads correctly, and keep labels readable across plots and responsive exports.<\/p>\n","protected":false},"author":1,"featured_media":32142,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[2071],"tags":[2576,2578,2577,2573,2575,2574],"class_list":["post-5557","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-matplotlib","tag-arrow-matplotlib","tag-arrow-python-matplotlib","tag-draw-arrow-matplotlib","tag-matplotlib-arrow","tag-matplotlib-draw-arrow","tag-plot-arrow-matplotlib","infinite-scroll-item"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.1 (Yoast SEO v28.0) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Matplotlib Arrow: Add, Style, and Annotate Arrows<\/title>\n<meta name=\"description\" content=\"Draw Matplotlib arrows with annotate and patch controls, position arrowheads correctly, and keep labels readable across plots and responsive exports.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Matplotlib Arrow: Add, Style, and Annotate Arrows\" \/>\n<meta property=\"og:description\" content=\"Draw Matplotlib arrows with annotate and patch controls, position arrowheads correctly, and keep labels readable across plots and responsive exports.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pythonpool.com\/matplotlib-arrow\/\" \/>\n<meta property=\"og:site_name\" content=\"Python Pool\" \/>\n<meta property=\"article:published_time\" content=\"2020-11-29T04:08:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-13T06:58:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrow.png\" \/>\n<meta name=\"author\" content=\"Python Pool\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Python Pool\" \/>\n<meta name=\"twitter:description\" content=\"Practical Python tutorials, error fixes, code examples, and project guides.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrow.png\" \/>\n<meta name=\"twitter:creator\" content=\"@pythonpool\" \/>\n<meta name=\"twitter:site\" content=\"@pythonpool\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Python Pool\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/\"},\"author\":{\"name\":\"Python Pool\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/person\\\/f87448ee54c0ffd2889fbf2408c18998\"},\"headline\":\"Matplotlib Arrow: Add, Style, and Annotate Arrows\",\"datePublished\":\"2020-11-29T04:08:29+00:00\",\"dateModified\":\"2026-07-13T06:58:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/\"},\"wordCount\":970,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/matplotlib-arrows-annotate-arrowprops.png\",\"keywords\":[\"arrow matplotlib\",\"arrow python matplotlib\",\"draw arrow matplotlib\",\"matplotlib arrow\",\"matplotlib draw arrow\",\"plot arrow matplotlib\"],\"articleSection\":[\"Matplotlib\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/\",\"name\":\"Matplotlib Arrow: Add, Style, and Annotate Arrows\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/matplotlib-arrows-annotate-arrowprops.png\",\"datePublished\":\"2020-11-29T04:08:29+00:00\",\"dateModified\":\"2026-07-13T06:58:55+00:00\",\"description\":\"Draw Matplotlib arrows with annotate and patch controls, position arrowheads correctly, and keep labels readable across plots and responsive exports.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/matplotlib-arrows-annotate-arrowprops.png\",\"contentUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/matplotlib-arrows-annotate-arrowprops.png\",\"width\":1350,\"height\":650,\"caption\":\"Matplotlib arrows with annotate arrowprops and FancyArrowPatch\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/matplotlib-arrow\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.pythonpool.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Matplotlib Arrow: Add, Style, and Annotate Arrows\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#website\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/\",\"name\":\"Python Pool\",\"description\":\"Practical Python tutorials, error fixes, code examples, and project guides.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.pythonpool.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#organization\",\"name\":\"Python Pool\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/aa.png\",\"contentUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/aa.png\",\"width\":452,\"height\":185,\"caption\":\"Python Pool\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/pythonpool\",\"https:\\\/\\\/www.youtube.com\\\/c\\\/pythonpool\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/person\\\/f87448ee54c0ffd2889fbf2408c18998\",\"name\":\"Python Pool\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd3cb9ad7f560324dfd481989550aa8ffce84388fd253c42beca35c999d3108?s=96&d=wavatar&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd3cb9ad7f560324dfd481989550aa8ffce84388fd253c42beca35c999d3108?s=96&d=wavatar&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd3cb9ad7f560324dfd481989550aa8ffce84388fd253c42beca35c999d3108?s=96&d=wavatar&r=g\",\"caption\":\"Python Pool\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Matplotlib Arrow: Add, Style, and Annotate Arrows","description":"Draw Matplotlib arrows with annotate and patch controls, position arrowheads correctly, and keep labels readable across plots and responsive exports.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/","og_locale":"en_US","og_type":"article","og_title":"Matplotlib Arrow: Add, Style, and Annotate Arrows","og_description":"Draw Matplotlib arrows with annotate and patch controls, position arrowheads correctly, and keep labels readable across plots and responsive exports.","og_url":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/","og_site_name":"Python Pool","article_published_time":"2020-11-29T04:08:29+00:00","article_modified_time":"2026-07-13T06:58:55+00:00","og_image":[{"url":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrow.png","type":"","width":"","height":""}],"author":"Python Pool","twitter_card":"summary_large_image","twitter_title":"Python Pool","twitter_description":"Practical Python tutorials, error fixes, code examples, and project guides.","twitter_image":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrow.png","twitter_creator":"@pythonpool","twitter_site":"@pythonpool","twitter_misc":{"Written by":"Python Pool","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#article","isPartOf":{"@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/"},"author":{"name":"Python Pool","@id":"https:\/\/www.pythonpool.com\/#\/schema\/person\/f87448ee54c0ffd2889fbf2408c18998"},"headline":"Matplotlib Arrow: Add, Style, and Annotate Arrows","datePublished":"2020-11-29T04:08:29+00:00","dateModified":"2026-07-13T06:58:55+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/"},"wordCount":970,"commentCount":0,"publisher":{"@id":"https:\/\/www.pythonpool.com\/#organization"},"image":{"@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrows-annotate-arrowprops.png","keywords":["arrow matplotlib","arrow python matplotlib","draw arrow matplotlib","matplotlib arrow","matplotlib draw arrow","plot arrow matplotlib"],"articleSection":["Matplotlib"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.pythonpool.com\/matplotlib-arrow\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/","url":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/","name":"Matplotlib Arrow: Add, Style, and Annotate Arrows","isPartOf":{"@id":"https:\/\/www.pythonpool.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#primaryimage"},"image":{"@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrows-annotate-arrowprops.png","datePublished":"2020-11-29T04:08:29+00:00","dateModified":"2026-07-13T06:58:55+00:00","description":"Draw Matplotlib arrows with annotate and patch controls, position arrowheads correctly, and keep labels readable across plots and responsive exports.","breadcrumb":{"@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pythonpool.com\/matplotlib-arrow\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#primaryimage","url":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrows-annotate-arrowprops.png","contentUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/matplotlib-arrows-annotate-arrowprops.png","width":1350,"height":650,"caption":"Matplotlib arrows with annotate arrowprops and FancyArrowPatch"},{"@type":"BreadcrumbList","@id":"https:\/\/www.pythonpool.com\/matplotlib-arrow\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pythonpool.com\/"},{"@type":"ListItem","position":2,"name":"Matplotlib Arrow: Add, Style, and Annotate Arrows"}]},{"@type":"WebSite","@id":"https:\/\/www.pythonpool.com\/#website","url":"https:\/\/www.pythonpool.com\/","name":"Python Pool","description":"Practical Python tutorials, error fixes, code examples, and project guides.","publisher":{"@id":"https:\/\/www.pythonpool.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pythonpool.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.pythonpool.com\/#organization","name":"Python Pool","url":"https:\/\/www.pythonpool.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pythonpool.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2020\/08\/aa.png","contentUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2020\/08\/aa.png","width":452,"height":185,"caption":"Python Pool"},"image":{"@id":"https:\/\/www.pythonpool.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/pythonpool","https:\/\/www.youtube.com\/c\/pythonpool"]},{"@type":"Person","@id":"https:\/\/www.pythonpool.com\/#\/schema\/person\/f87448ee54c0ffd2889fbf2408c18998","name":"Python Pool","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/fdd3cb9ad7f560324dfd481989550aa8ffce84388fd253c42beca35c999d3108?s=96&d=wavatar&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/fdd3cb9ad7f560324dfd481989550aa8ffce84388fd253c42beca35c999d3108?s=96&d=wavatar&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fdd3cb9ad7f560324dfd481989550aa8ffce84388fd253c42beca35c999d3108?s=96&d=wavatar&r=g","caption":"Python Pool"}}]}},"_links":{"self":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts\/5557","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/comments?post=5557"}],"version-history":[{"count":24,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts\/5557\/revisions"}],"predecessor-version":[{"id":41456,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts\/5557\/revisions\/41456"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/media\/32142"}],"wp:attachment":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/media?parent=5557"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/categories?post=5557"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/tags?post=5557"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}