When I add twinx
and/or twiny
axes with the python library matplotlib
, the effect of a specified aspect ratio becomes inconsistent:
twinx
/twiny
, the axes are zoomed in (range is shrunk) to realise the desired aspect ratiotwinx
and/or twiny
axes, the result depends on the order in which I add twinx
and twiny
, and whether the x axis needs to be shrunk or the y axis.Below is an example of the inconsistent behaviour (left and right axes show different limits).
It will be consistent again when the twin axes are added as axes[1].twinx().twiny()
xor the y range is increased.
This gives me some headache when I want to predict what my code does, which is precisely not what I use python for ;)
Is there a way to make this behave as expected: i.e. the axes are always shrunk, whether or not twinx and/or twiny are added?
I would be even happier if it were possible to choose between the behaviours shrink/expand explicitly. Would anyone know how?
Thanks heaps!
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2)
axes[1].twinx().twiny()
for ax in axes:
ax.grid(True)
ax.set(
aspect=1,
adjustable='datalim',
)
ax.set(
ylim=(10, 20), # axes are the same when this range is larger, e.g. (10, 30)
xlim=(20, 30),
)
# so the output below shows the final values
ax.apply_aspect()
print(ax.get_xlim())
print(ax.get_ylim())
In response to the comment by Guimoute:
Good point the doc says I should not do this. However, matplotlib does not complain. When I change 'datalim'
to 'box'
, I do get a RuntimeError: Adjustable 'box' is not allowed in a twinned Axes; use 'datalim' instead
. (so the opposite of what the documentation suggests).
If I add the twin axes as
axes[1].twinx()
axes[1].twiny()
I get an error for either approach.
Curious about the suggestion that matplotlib tries to give the twinned axes an equal number of ticks, and that the specification of their limits should have an influence; I don't see that happen in the example below.
In my application, of course I would do more with the twinned axes. I left it out to keep the example simple, but a matching number of ticks was not to be expected.
The application I had in mind was e.g. lat/lon coordinates on one set of axes and northings/eastings on the other.
Anyway, here is example two:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2)
twiny = axes[1].twiny()
twiny.set(xlim=(0, .8))
for ax in axes:
ax.grid(True)
ax.set(
aspect=1,
adjustable='datalim',
)
ax.set(
ylim=(10, 30),
xlim=(20, 30),
)
ax.apply_aspect()
Maybe twinx
/twiny
was not intended for this application, but I am surprised about the results I get.
Not really an explanation, but for now I will just first finish working on the original axes, and add the twins later. That way at least the behaviour is predictable.