How to to enable sharing for the secondary axis (twiny) in python
<p>I'm trying to enable sharing for both primary and secondary axis. The example plot is illustrated by the code below. The plot contains two horizontal axes, the primary axis grid is shown in green, while the other axis has red grid.</p>

<pre><code>#!/usr/bin/python

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt

FIRST = 0.0
LAST  = 2.0
STEP  = 0.01

t = np.arange(FIRST, LAST, STEP)

s1 = np.sin(2*np.pi*t)
s2 = np.exp(-t)
s3 = s1*s2

###############################################################################

plt.rc('axes', grid=True)
plt.rc('grid', color='0.75', linestyle='-', linewidth=0.5)

fig3 = plt.figure()
ax1primary = plt.subplot2grid((4,3), (0,0), colspan=3, rowspan=2)
ax2primary = plt.subplot2grid((4,3), (2,0), colspan=3, sharex=ax1primary)
ax3primary = plt.subplot2grid((4,3), (3,0), colspan=3, sharex=ax1primary)

ax1primary.plot(t,s1)
ax1primary.set_yticks(np.arange(-0.9, 1.0, 0.3))
ax1primary.xaxis.grid(color='green')

ax2primary.plot(t[:150],s2[:150])
ax2primary.set_yticks(np.arange(0.3, 1, 0.2))
ax2primary.xaxis.grid(color='green')

ax3primary.plot(t[30:],s3[30:])
ax3primary.plot([0,2],[0.2,0.2],'m')
ax3primary.set_yticks(np.arange(-0.4, 0.7, 0.2))
ax3primary.xaxis.grid(color='green')

INDEX = t[np.where(abs(s3-0.2) &lt; 0.005)[0]]
INDEX = np.append(INDEX, LAST)
INDEX = np.insert(INDEX, 0, FIRST)

ax1secondary = ax1primary.twiny()
ax1secondary.set_xticks(INDEX)
ax1secondary.xaxis.grid(color='red')

ax2secondary = ax2primary.twiny()
ax2secondary.set_xticks(INDEX)
ax2secondary.xaxis.grid(color='red')

ax3secondary = ax3primary.twiny()
ax3secondary.set_xticks(INDEX)
ax3secondary.xaxis.grid(color='red')

plt.tight_layout()
plt.subplots_adjust(hspace=0)

for ax in [ax1primary, ax2primary, ax2secondary, ax3secondary]:
    plt.setp(ax.get_xticklabels(), visible=False)

###############################################################################

plt.show()
</code></pre>

<p>On a static figure there is no issue. The problem becomes obvious when 
you start panning (or zooming) one of the subplots. The primary (green) axis stays perfectly in sync and moves within all subplots, but the secondary (red) axis gets misaligned and moves only within the active subplot.</p>

<p>Is there a way to fix this?</p>

<hr>

<p>The behavior that I want to achieve is following:</p>

<p>I need one common "primary" x-axis (for all three subplots) with the ticks on the bottom of the figure and another common "secondary" x-axis (for all three subplots) with the ticks on the top of the figure. The primary axis is a standard regularly spaced axis, while the secondary axis shows the customized ticks (for example zero crossings) <strong>This is all satisfied in the example above. Now I need it to be satisfied also while panning and zooming subplots.</strong></p>

<p>Thanks for clarifying your question. The intended use of <code>twiny</code> is to create a second fully independent x-axis with its own scale and offset, which you would then plot into. However in your case you are only using the secondary x-axis created by <code>twiny</code> as a way to display a second set of custom x ticks, and you want this axis to always have exactly the same scale and offset as the parent x-axis.</p>

<p>One approach would be to create a <a href="http://matplotlib.org/users/event_handling.html" rel="nofollow">callback</a> that updates the limits of the secondary axis whenever the primary axis gets panned:</p>

<pre><code>from matplotlib.backend_bases import NavigationToolbar2

parents = [ax1primary, ax2primary, ax3primary]
children = [ax1secondary, ax2secondary, ax3secondary]

def callback(event=None):
    # return immediately if the figure toolbar is not in "navigation mode"
    if not isinstance(parents[0].figure.canvas.manager.toolbar,
                      NavigationToolbar2):
        return
    for parent, child in zip(parents, children):
        child.set_xlim(*parent.get_xlim())
        child.set_ylim(*parent.get_ylim())

# connect the callback to the figure canvas
fig3.canvas.mpl_connect('motion_notify_event', callback)
</code></pre>

python matplotlib