我正在尝试为主轴和辅助轴启用共享。示例图由下面的代码说明。该图包含两个水平轴,主轴网格显示为绿色,而另一个轴显示红色网格。
#!/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()
在静态数字上没有问题。当问题变得明显时 您开始平移(或缩放)其中一个子图。主(绿色)轴保持完全同步并在所有子图中移动,但次级(红色)轴未对齐并仅在活动子图中移动。
有没有办法解决这个问题?
我想要实现的行为如下:
我需要一个常见的“主要”x轴(对于所有三个子图),图中底部有刻度线,另一个常见的“次要”x轴(对于所有三个子图),顶部有刻度线这个数字。主轴是标准的规则间隔轴,而副轴显示定制的刻度(例如过零点)这在上面的示例中都满足。现在我需要在平移和缩放子图时也满意。
答案 0 :(得分:2)
感谢您澄清您的问题。 twiny
的预期用途是创建第二个完全独立的x轴,它具有自己的比例和偏移,然后您可以绘制。但是在您的情况下,您只使用由twiny
创建的辅助x轴作为显示第二组自定义x刻度的方法,并且您希望此轴始终具有与父级完全相同的比例和偏移量x轴。
一种方法是创建一个callback,在主轴平移时更新辅助轴的限制:
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)
答案 1 :(得分:0)
不幸的是,建议的回调解决方案不够健壮。大部分时间平移工作正常,但缩放是一场灾难。不过,网格往往不对齐。
在我找到如何改进回调解决方案之前,我决定编写自定义网格并在图中注释值。
#!/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')
ax1primary.set_ylim(-1, 1)
ax2primary.plot(t[:150],s2[:150])
ax2primary.set_yticks(np.arange(0.3, 1, 0.2))
ax2primary.xaxis.grid(color='green')
ax2primary.set_ylim(0.2, 1)
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')
ax3primary.set_ylim(-0.6, 0.8)
INDEX = np.where(abs(s3-0.2) < 0.005)[0]
for i in range(0, len(INDEX)):
ax1primary.annotate(t[INDEX[i]], xy=(t[INDEX[i]], 0))
ax1primary.plot([t[INDEX], t[INDEX]], [-1e9 * np.ones(len(INDEX)), 1e9 * np.ones(len(INDEX))], 'r')
ax2primary.plot([t[INDEX], t[INDEX]], [-1e9 * np.ones(len(INDEX)), 1e9 * np.ones(len(INDEX))], 'r')
ax3primary.plot([t[INDEX], t[INDEX]], [-1e9 * np.ones(len(INDEX)), 1e9 * np.ones(len(INDEX))], 'r')
plt.tight_layout()
plt.subplots_adjust(hspace=0)
for ax in [ax1primary, ax2primary]:
plt.setp(ax.get_xticklabels(), visible=False)
###############################################################################
plt.show()