subplot2grid中有2个图

时间:2016-05-09 16:37:02

标签: python matplotlib

我正在使用suplot2grid来绘制6个子图,每个子图中都有2个时间序列。这些子图中的每一个都应显示不同Y(垂直)轴的值 我当前的输出,接近我的目标,但仍然是错误的,是这样的: enter image description here

现在我做的是以下内容:

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_aax1_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()时将该图表重置为图表

1 个答案:

答案 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()

enter image description here

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()

enter image description here

解决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()