Consider the following simple example:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
ax.plot([0],[0])
ax.grid()
ax.set_xlim([0,10])
ax.set_ylim([0,10])
ax.annotate("", (2, 1), (4, 1), arrowprops={'arrowstyle':'<->'})
plt.show()
So, with the ax.annotate
, I want to draw an arrow from point (x=2, y=1) to point (x=4, y=1); however the output is this:
As visible on the screenshot, the arrowheads do not come to exactly the endpoints (x=2, y=1) and (x=4, y=1) - but instead, there is a small amount of whitespace "padding" or "margin".
How can I have the arrow endpoints (the tips of the arrowheads) to align exactly with the stated endpoints? To make it explicit, I tried editing the image above, and manually drawing the arrowheads (in read) where I'd want them to be:
Thanks to comment by @JodyKlymak, I looked into https://matplotlib.org/stable/tutorials/text/annotations.html - the only thing that I found obviously related to my problem here was the "shrink" parameter, however, this:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
ax.plot([0],[0])
ax.grid()
ax.set_xlim([0,10])
ax.set_ylim([0,10])
ax.annotate("", (2, 1), (4, 1), arrowprops={'arrowstyle':'<->', 'shrink': 0})
plt.show()
... fails with:
AttributeError: 'FancyArrowPatch' object has no property 'shrink'
I found finally this: Using arrowstyle causes "Unknown property shrink" · Issue #3697 · matplotlib/matplotlib:
Ah, the problem is that if you use the
simple
arrow style which, it turns out, completely changes the code path that is taken. If 'arrowstyle' is in the dictionary then thearrowprops
dictionary is used to create aFancyArrow
patch. Ifarrowstyle
is not inarrowprops
than the dictionary is used to create aYAArrow
object.
OK, so trying this:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
ax.plot([0],[0])
ax.grid()
ax.set_xlim([0,10])
ax.set_ylim([0,10])
ax.annotate("", (2, 1), (4, 1), arrowprops={'shrink': 0})
plt.show()
... and this does indeed pass - however it draws a completely different, "leftwards" arrow (instead of a left-right arrow):
So, let me reformulate - is it possible to get "correct" full-length arrow, with the default left-right arrow from ax.annotate (the one that looks just like a line, and not as a thicker filled surface)?