If you have multiple subplots containing a secondary y-axis (created using twinx
), how can you share these secondary y-axes between the subplots? I want them to scale equally in an automatic way (so not set the y-limits afterwards by hand). For the primary y-axis, this is possible by using the keyword sharey
in the call of subplot
.
Below example shows my attempt, but it fails to share the secondary y-axis of both subplots. I'm using Matplotlib:
ax = []
#create upper subplot
ax.append(subplot(211))
plot(rand(1) * rand(10),'r')
#create plot on secondary y-axis of upper subplot
ax.append(ax[0].twinx())
plot(10*rand(1) * rand(10),'b')
#create lower subplot and share y-axis with primary y-axis of upper subplot
ax.append(subplot(212, sharey = ax[0]))
plot(3*rand(1) * rand(10),'g')
#create plot on secondary y-axis of lower subplot
ax.append(ax[2].twinx())
#set twinxed axes as the current axes again,
#but now attempt to share the secondary y-axis
axes(ax[3], sharey = ax[1])
plot(10*rand(1) * rand(10),'y')
This gets me something like:
Example of two subplots with failed sharing of secondary y-axis
The reason I used the axes()
function to set the shared y-axis is that twinx
doesn't accept the sharey
keyword.
I am using Python 3.2 on Win7 x64. Matplotlib version is 1.2.0rc2.
2 Answers 2
You can use Axes.get_shared_y_axes()
like so:
from numpy.random import rand
import matplotlib
matplotlib.use('gtkagg')
import matplotlib.pyplot as plt
# create all axes we need
ax0 = plt.subplot(211)
ax1 = ax0.twinx()
ax2 = plt.subplot(212)
ax3 = ax2.twinx()
# share the secondary axes
ax1.get_shared_y_axes().join(ax1, ax3)
ax0.plot(rand(1) * rand(10),'r')
ax1.plot(10*rand(1) * rand(10),'b')
ax2.plot(3*rand(1) * rand(10),'g')
ax3.plot(10*rand(1) * rand(10),'y')
plt.show()
Here we're just joining the secondary axes together.
-
Yes, that helped me further, thanks. I also joined the primary y-axes so that they have a shared y-axis as well.Puggie– Puggie2012年10月17日 11:25:10 +00:00Commented Oct 17, 2012 at 11:25
-
3It doesn't work, the second twin scale get updated, but the second twin plot stays were it is.Mattia– Mattia2017年03月22日 14:57:43 +00:00Commented Mar 22, 2017 at 14:57
-
1Just to not have people get the wrong impression, the code as it is in this answer works fine.ImportanceOfBeingErnest– ImportanceOfBeingErnest2018年01月17日 15:49:55 +00:00Commented Jan 17, 2018 at 15:49
-
3The problem @mattia might have encountered: If you call a function like
ax1.set_ylim()
beforeAxes.get_shared_y_axes().join()
then the two axes will NOT have the same scales (until you shift the axes interactively). Callget_shared_y_axes().join()
first. BTW it works fine if you call it after callingplot()
, etc.Ralph Versteegen– Ralph Versteegen2018年07月19日 08:53:04 +00:00Commented Jul 19, 2018 at 8:53 -
3
join
is deprecated in matplotlib 3.6.piogor– piogor2023年08月21日 10:34:09 +00:00Commented Aug 21, 2023 at 10:34
@dmcdougall's solution doesn't work anymore because GrouperView
doesn't define join
method anymore. However, it defines joined
, so replacing join
by joined
in their code makes it run as expected.
However, a better solution is to use the method recommended in the docs to share y-axis: Axes.sharey(Axes)
. A working example goes as follows:
import numpy as np
import matplotlib.pyplot as plt
# create all Axes
fig, (ax0, ax2) = plt.subplots(2, sharey=True) # share the primary y-axis
ax1 = ax0.twinx()
ax3 = ax2.twinx()
ax1.sharey(ax3) # share the secondary y-axis
ax0.plot(np.random.rand(10)*1., 'r')
ax1.plot(np.random.rand(10)*10, 'b')
ax2.plot(np.random.rand(10)*3., 'g')
ax3.plot(np.random.rand(10)*10, 'y')
which plots a figure like the following:
Explore related questions
See similar questions with these tags.