matplotlib twinx strange behavior after set_position()

Viewed 243

I'm working on a function that would make it easy for me to add parasite axes wherever I want on a plot, but I have encountered a weird situation. Take a look at the following code:

import matplotlib.pyplot as plt

plt.plot()
plt.gca().set_position([1/3, 1/3, 1/3, 1/3])
plt.gca().twinx()

plt.show()

The above code produces the following figure: enter image description here

As you can see, the twinx plot is generated using the old positions of the host plot. I would have expected the twinx plot to be generated on the new positions of the host plot.

How can I draw a twinx plot on the new positions of the host plot? (I know drawing the twinx plot beforehand "solves" this but it's not a practical solution)

Thanks for your help!

2 Answers

I figured out a way to go around the problem by trial and error. However, it should be noted that I have no idea how twinx works and I am very beginner in terms of matplotlib, so I would definitely not be able to understand any of what is happening.

What I did to solve this is I used plt.gcf().subplots_adjust() before creating the twinx. However, doing this effectively trashes the new positions, so I saved them beforehand to be able to reapply them after creating the twinx. The code becomes:

import matplotlib.pyplot as plt

plt.plot()
plt.gca().set_position([1/3, 1/3, 1/3, 1/3])
pos = plt.gca().get_position()     #added line
plt.gcf().subplots_adjust()        #added line
plt.gca().twinx()
plt.gca().set_position(pos)        #added line

plt.show()

I'm still open to reading some better answers than mine, however, so feel free to give your propositions!

NOTE: The code above seems pretty dumb (I'm setting the position just to reset it and then reapply it later), but in my actual application, the first set_position would have been executed by an earlier function call, and a later function call needs to add the twinx, so this does have a use case.

You can set the position of the axes after calling twinx, using the position data from the initial setting prior to twinx.

There are several ways to do it.

import matplotlib.pyplot as plt

# Create original plot
plt.plot()
ax = plt.gca()
ax.set_position([1/3,1/3,1/3,1/3])
# Make twin axes.
ax2 = ax.twinx()
ax2.set_position(ax.get_position())

plt.show()

Alternatively, you can do ax.set_position(ax.get_position()). But a key point is recording the original Axes to a variable because gca points to the new Axes (which have the wrong position) once you call twinx.

If you don't want to store the Axes in a variable, you can store the axes position in a variable.

import matplotlib.pyplot as plt

# Create original plot
plt.plot()
plt.gca().set_position([1/3, 1/3, 1/3, 1/3])
# Make twin axes
pos = plt.gca().get_position()
plt.gca().twinx()
plt.gca().set_position(pos)

plt.show()

It is not necessary to throw out the positions set previously.

Related