How can one detect if an axis has a twin axis written on top of it? For example, if given ax below, how can I discover that ax2 exists?
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3])
ax2 = ax.twinx()
How can one detect if an axis has a twin axis written on top of it? For example, if given ax below, how can I discover that ax2 exists?
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3])
ax2 = ax.twinx()
I would like to propose a get_twin -> Axes function rather than has_twin -> bool, which has more applications. You can still check whether an ax has a twin by checking if get_twin(...) is None instead of if has_twin(...) so functionnality is not lost.
This is built on @ImportanceOfBeingErnest's answer. @jakevdp's is slightly less robust because it does not check explicitly for siblings.
def get_twin(ax, axis):
assert axis in ("x", "y")
siblings = getattr(ax, f"get_shared_{axis}_axes")().get_siblings(ax)
for sibling in siblings:
if sibling.bbox.bounds == ax.bbox.bounds and sibling is not ax:
return sibling
return None
fig, ax = plt.subplots()
print(get_twin(ax, "x") is None) # True
ax2 = ax.twinx()
print(get_twin(ax, "x") is ax2) # True
print(get_twin(ax2, "x") is ax) # True
One-liner for @Guimoute's answer as a lambda:
hasTwin = lambda ax, axis: \
np.sum([np.logical_and(sib != ax,\
sib.bbox.bounds==ax.bbox.bounds) for sib in \
getattr(ax, f'get_shared_{}_axes'.format(axis))().get_siblings(ax)])
where the input axis should be a string 'x' or 'y'. This will return something nonzero (probably 1) if a twin exists:
hasXtwin = hasTwin(ax, 'x')
hasXtwin = hasTwin(ax, 'y')
if not hasXtwin:
doSomething()
if not hasXtwin:
doSomethingElse()