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.
#!/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) < 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()
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.
Is there a way to fix this?
The behavior that I want to achieve is following:
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) This is all satisfied in the example above. Now I need it to be satisfied also while panning and zooming subplots.
Thanks for clarifying your question. The intended use of
twiny
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 bytwiny
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.One approach would be to create a callback that updates the limits of the secondary axis whenever the primary axis gets panned:
Unfortunately the proposed callback solution is not robust enough. Most of the time panning works fine, but zooming is a disaster. Still, too often the grids get misaligned.
Until I find out how to improve the callback solution, I decided to code a custom grid and annotate the values within the plot.