Note

Go to the endto download the full example code.

Arrow guide#

Adding arrow patches to plots.

Arrows are often used to annotate plots. This tutorial shows how to plot arrowsthat behave differently when the data limits on a plot are changed. In general,points on a plot can either be fixed in "data space" or "display space".Something plotted in data space moves when the data limits are altered - anexample would be the points in a scatter plot. Something plotted in displayspace stays static when data limits are altered - an example would be afigure title or the axis labels.

Arrows consist of a head (and possibly a tail) and a stem drawn between astart point and end point, called 'anchor points' from now on.Here we show three use cases for plotting arrows, depending on whether thehead or anchor points need to be fixed in data or display space:

  1. Head shape fixed in display space, anchor points fixed in data space

  2. Head shape and anchor points fixed in display space

  3. Entire patch fixed in data space

Below each use case is presented in turn.

importmatplotlib.pyplotaspltimportmatplotlib.patchesasmpatchesx_tail=0.1y_tail=0.5x_head=0.9y_head=0.8dx=x_head-x_taildy=y_head-y_tail

Head shape fixed in display space and anchor points fixed in data space#

This is useful if you are annotating a plot, and don't want the arrowto change shape or position if you pan or scale the plot.

In this case we usepatches.FancyArrowPatch.

Note that when the axis limits are changed, the arrow shape stays the same,but the anchor points move.

fig,axs=plt.subplots(nrows=2)arrow=mpatches.FancyArrowPatch((x_tail,y_tail),(x_head,y_head),mutation_scale=100)axs[0].add_patch(arrow)arrow=mpatches.FancyArrowPatch((x_tail,y_tail),(x_head,y_head),mutation_scale=100)axs[1].add_patch(arrow)axs[1].set(xlim=(0,2),ylim=(0,2))
arrow guide

Head shape and anchor points fixed in display space#

This is useful if you are annotating a plot, and don't want the arrow tochange shape or position if you pan or scale the plot.

In this case we usepatches.FancyArrowPatch, and pass the keyword argumenttransform=ax.transAxes whereax is the Axes we are adding the patchto.

Note that when the axis limits are changed, the arrow shape and locationstay the same.

fig,axs=plt.subplots(nrows=2)arrow=mpatches.FancyArrowPatch((x_tail,y_tail),(x_head,y_head),mutation_scale=100,transform=axs[0].transAxes)axs[0].add_patch(arrow)arrow=mpatches.FancyArrowPatch((x_tail,y_tail),(x_head,y_head),mutation_scale=100,transform=axs[1].transAxes)axs[1].add_patch(arrow)axs[1].set(xlim=(0,2),ylim=(0,2))
arrow guide

Head shape and anchor points fixed in data space#

In this case we usepatches.Arrow, orpatches.FancyArrow (the latter isin orange).

Note that when the axis limits are changed, the arrow shape and locationchange.

FancyArrow's API is relatively awkward, and requires in particular passinglength_includes_head=True so that the arrowtip is(dx,dy) awayfrom the arrow start. It is only included in this reference because it isthe arrow class returned byAxes.arrow (in green).

fig,axs=plt.subplots(nrows=2)arrow=mpatches.Arrow(x_tail,y_tail,dx,dy)axs[0].add_patch(arrow)arrow=mpatches.FancyArrow(x_tail,y_tail-.4,dx,dy,width=.1,length_includes_head=True,color="C1")axs[0].add_patch(arrow)axs[0].arrow(x_tail+1,y_tail-.4,dx,dy,width=.1,length_includes_head=True,color="C2")arrow=mpatches.Arrow(x_tail,y_tail,dx,dy)axs[1].add_patch(arrow)arrow=mpatches.FancyArrow(x_tail,y_tail-.4,dx,dy,width=.1,length_includes_head=True,color="C1")axs[1].add_patch(arrow)axs[1].arrow(x_tail+1,y_tail-.4,dx,dy,width=.1,length_includes_head=True,color="C2")axs[1].set(xlim=(0,2),ylim=(0,2))
arrow guide

Total running time of the script: (0 minutes 1.361 seconds)

Gallery generated by Sphinx-Gallery