Reputation: 3934
Yesterday I asked a question based on a misconception. I now know better what actually I am asking.
I want to draw an arrow between two axeses AND have text next to it like I manually painted in here:
import matplotlib.pyplot as plt
from matplotlib import patches
import numpy as np
fig = plt.figure()
X, Y = np.mgrid[-1:1:.1, -1:1:.1]
Z = X+Y
ax1 = fig.add_subplot(311)
ax2 = fig.add_subplot(313)
ax1.contourf(X, Y, Z)
ax2.contourf(X, Y, -Z)
con = patches.ConnectionPatch((0,0),
(0,0),
coordsA="data",
coordsB="data",
arrowstyle="<|-",
mutation_scale=20,
axesA=ax2,
axesB=ax1)
ax2.add_artist(con)
fig.show()
Having arrows with text next to them within one axes can be done with ax.annotate()
. Drawing arrows between axeses can be done with ConnectionPatch
. However, the docs say:
The ConnectionPatch is like an annotation without text. While the annotate function is recommended in most situations, the ConnectionPatch is useful when you want to connect points in different axes.
So, from that it sounds like having both of these (inter-axes arrow and text) is not covered by the API in a user-friendly manner.
Okay... but there must be an at least palatable way of pulling this off, right? The answer to my question from yesterday was based on my misconception. So, I hope there is a better solution based on this my re-framed question.
So, is there a robust way to add text to an inter-axes-arrow (like ConnectionPatch
), without fiddling around with coordinates and ax.text
or such nonsense?
Upvotes: 5
Views: 1067
Reputation: 11301
A "coordinate fiddling" solution requires little code and is quite flexible:
import matplotlib.pyplot as plt
from matplotlib import patches
import numpy as np
fig = plt.figure()
X, Y = np.mgrid[-1:1:.1, -1:1:.1]
Z = X+Y
ax1 = fig.add_subplot(311)
ax2 = fig.add_subplot(313)
ax1.contourf(X, Y, Z)
ax2.contourf(X, Y, -Z)
xy1, xy2 = (0,0), (0,0)
con = patches.ConnectionPatch(xy2,
xy1,
coordsA="data",
coordsB="data",
arrowstyle="<|-",
mutation_scale=20,
axesA=ax2,
axesB=ax1)
ax2.add_artist(con)
# calculate center of inter-axes arrow in figure pixels
xy = np.mean([ax1.transData.transform(xy1), ax2.transData.transform(xy2)],
axis=0)
plt.annotate(" arrow label", xy, xycoords='figure pixels', va='center')
plt.show()
Upvotes: 3