我正在使用suplot2grid来绘制6个子图,每个子图中都有2个时间序列。这些子图中的每一个都应显示不同Y(垂直)轴的值 我当前的输出,接近我的目标,但仍然是错误的,是这样的:
现在我做的是以下内容:
fig2 = plt.figure(figsize=(14,11))
# defining the axes
ax1_a = plt.subplot2grid((12,2),(0,0), rowspan=3, colspan=1) # drift
ax1_b = plt.subplot2grid((12,2),(4,0), rowspan=3, colspan=1, sharex=ax1_a) # zscore drift
ax1_b = ax1_a.twinx()
ax2_a = plt.subplot2grid((12,2),(4,0), rowspan=3, colspan=1, sharex=ax1_a)
ax2_b = plt.subplot2grid((12,2),(8,0), rowspan=3, colspan=1, sharex=ax1_a)
ax2_b = ax2_a.twinx()
ax3_a = plt.subplot2grid((12,2),(8,0), rowspan=3, colspan=1, sharex=ax1_a)
ax3_b = plt.subplot2grid((12,2),(11,0), rowspan=3, colspan=1, sharex=ax1_a)
ax3_b = ax3_a.twinx()
ax4_a = plt.subplot2grid((12,2),(0,1), rowspan=3, colspan=1)
ax4_b = plt.subplot2grid((12,2),(4,1), rowspan=3, colspan=1, sharex=ax4_a)
ax4_b = ax4_a.twinx()
ax5_a = plt.subplot2grid((12,2),(4,1), rowspan=3, colspan=1, sharex=ax4_a)
ax5_b = plt.subplot2grid((12,2),(8,1), rowspan=3, colspan=1, sharex=ax4_a)
ax5_b = ax5_a.twinx()
ax6_a = plt.subplot2grid((12,2),(8,1), rowspan=3, colspan=1, sharex=ax4_a)
ax6_b = plt.subplot2grid((12,2),(11,1), rowspan=3, colspan=1, sharex=ax4_a)
ax6_b = ax6_a.twinx()
#定义绘图功能
def plot_drift(axx,label):
axx.plot(df.index[-lenght:], df[label][-lenght:], linestyle='-', lw=2,
label=label,color='b',alpha=1.00)
def plot_zscore(axx,label):
axx.plot(df.index[-lenght:], df[label][-lenght:], linestyle='-', lw=2,
label=label,color='g',alpha=1.00)
def vertical_labels_drift(axx):
axx.set_ylabel('Vols')
def vertical_labels_Zscore(axx):
axx.set_ylabel('Zscore')
def stdev(axx):
axx.axhline(2,linewidth=2,color='yellow') # standard deviations
axx.axhline(-2,linewidth=2,color='yellow') # standard deviations
axx.axhline(3,linewidth=2,color='red')
axx.axhline(-3,linewidth=2,color='red')
# plotting the drift
for i,j in zip([ax1_a,ax2_a,ax3_a,ax4_a,ax5_a,ax6_a],cols_drift):
plot_drift(i,j)
vertical_labels_drift(i)
# plotting the zscore
for i,j in zip([ax1_b,ax2_b,ax3_b,ax4_b,ax5_b,ax6_b], cols_drift_Z):
plot_zscore(i,j)
stdev(i)
vertical_labels_Zscore(i)
所以我的问题是,在子图中定义新图的正确方法是什么?
因为如果您为ax1_a
和ax1_b
放置相同的位置,则ax1_a
会覆盖ax1_b
,并且只有ax1_b
会被映射。换句话说,如果你这样做:
ax1_a = plt.subplot2grid((12,2),(0,0), rowspan=3, colspan=1) # drift
ax1_b = plt.subplot2grid((12,2),(0,0), rowspan=3, colspan=1, sharex=ax1_a) # zscore drift
ax1_b = ax1_a.twinx()
ax1_a
不会显示。
另外,我不明白为什么我的图表即使在显示的第一个代码中输入错误的位置也显示出来。即使您在执行ax1_b
时将其他位置添加到ax2_b
,.twinx()
等,它也会在执行.twinx()
时将该图表重置为图表
答案 0 :(得分:1)
在我看来,你误解了axes.twinx()
的角色,你必须首先实例化一个轴,用于第一组曲线(左边的刻度线)和稍后使用.twinx()
来克隆轴,在其上绘制第二组曲线。
一个更简单的例子,您可以适应您的问题
import matplotlib.pyplot as plt
import numpy as np
t = np.linspace(0,1,101)
nr, nc = 3, 2
fig, axes_array = plt.subplots(nrows=nr, ncols=nc)
for row_of_axes in axes_array:
for ax in row_of_axes:
ax.plot(t,np.sin(np.pi*t), color='black')
ax.twinx().plot(t,2*np.sin(np.pi*t)/(1.1-t), color='red')
fig.tight_layout()
P.S。更接近你的编码风格
...
for r, row_of_axes in enumerate(axes_array):
for c, ax_a in enumerate(row_of_axes):
ax_b = ax_a.twinx()
ax_a.plot(t,np.sin(np.pi*t), color='black', label='a %d %d'%(r,c))
ax_b.plot(t,2*np.sin(np.pi*t)/(1.1-t), color='red', label='b %d %d'%(r,c))
ax_a.legend(loc=1)
ax_b.legend(loc=3)
fig.tight_layout()
解决OP的评论/请求
代替ndarray
,您只需使用列表清单
nr, nc = 3, 2
axes_array = [[plt.subplot2grid((nr, nc), (r,c)) for c in range(nc)] for r in range(nr)]
请注意,这与我之前的代码不同,因为它不会给你fig
- 应用紧密的布局,你可以这样继续(未经测试,警告的人)
plt.gcf().tight_layout()