2014-02-09 64 views
19

我是最近轉換爲Python的Matlab用戶。大多數我自己管理的Python技能,但是通過密謀我已經碰壁並需要一些幫助。如何在使用subplot2grid時共享

這就是我想要做的......

我需要做的是由3個副區具有以下屬性的人物:

  • 插曲佈局爲311,312,313
  • 的312和313的高度爲大約一半的311
  • 所有副區具有共同的X軸
  • 的副區爲0(它們彼此接觸在X軸)之間的空間

順便說一句,我知道如何使所有這一切,只在一個數字。這是我現在面臨的問題。

例如,這是我的理想副區佈局:

import numpy as np 
import matplotlib.pyplot as plt 

t = np.arange(0.0, 2.0, 0.01) 

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

fig = plt.figure() 
ax1 = plt.subplot2grid((4,3), (0,0), colspan=3, rowspan=2) 
ax2 = plt.subplot2grid((4,3), (2,0), colspan=3) 
ax3 = plt.subplot2grid((4,3), (3,0), colspan=3) 

ax1.plot(t,s1) 
ax2.plot(t[:150],s2[:150]) 
ax3.plot(t[30:],s3[30:]) 

plt.tight_layout() 

plt.show() 

通知不同副區的x軸是如何對準。我不知道如何使x軸在此圖,但如果我做這樣的事情:

import numpy as np 
import matplotlib.pyplot as plt 

t = np.arange(0.0, 2.0, 0.01) 

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

fig2, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, sharex=True) 

ax1.plot(t,s1) 
ax2.plot(t[:150],s2[:150]) 
ax3.plot(t[30:],s3[30:]) 

plt.tight_layout() 

plt.show() 

現在x軸的次要情節之間對齊,但所有次要情節是相同的尺寸(這是不我想要的)

此外,我想的是,次要情節在x軸像這樣感人:

import numpy as np 
import matplotlib.pyplot as plt 

t = np.arange(0.0, 2.0, 0.01) 

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

fig1 = plt.figure() 
plt.subplots_adjust(hspace=0) 

ax1 = plt.subplot(311) 
ax2 = plt.subplot(312, sharex=ax1) 
ax3 = plt.subplot(313, sharex=ax1) 

ax1.plot(t,s1) 
ax2.plot(t[:150],s2[:150]) 
ax3.plot(t[30:],s3[30:]) 

xticklabels = ax1.get_xticklabels()+ax2.get_xticklabels() 
plt.setp(xticklabels, visible=False) 

plt.show() 

所以要改寫我的問題:

我想用

plt.subplot2grid(..., colspan=3, rowspan=2) 
plt.subplots(..., sharex=True) 
plt.subplots_adjust(hspace=0) 

plt.tight_layout() 

一起在同一圖中。怎麼做?

回答

25

只需在創建第二個和第三個子圖時指定sharex=ax1即可。

import numpy as np 
import matplotlib.pyplot as plt 

t = np.arange(0.0, 2.0, 0.01) 

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

fig = plt.figure() 
ax1 = plt.subplot2grid((4,3), (0,0), colspan=3, rowspan=2) 
ax2 = plt.subplot2grid((4,3), (2,0), colspan=3, sharex=ax1) 
ax3 = plt.subplot2grid((4,3), (3,0), colspan=3, sharex=ax1) 

ax1.plot(t,s1) 
ax2.plot(t[:150],s2[:150]) 
ax3.plot(t[30:],s3[30:]) 

fig.subplots_adjust(hspace=0) 
for ax in [ax1, ax2]: 
    plt.setp(ax.get_xticklabels(), visible=False) 
    # The y-ticks will overlap with "hspace=0", so we'll hide the bottom tick 
    ax.set_yticks(ax.get_yticks()[1:]) 

plt.show() 

enter image description here

如果您使用fig.tight_layout()還是什麼,你需要fig.subplots_adjust(hspace=0)之前調用它。原因是tight_layout的工作原理是自動計算subplots_adjust的參數,然後調用它,因此如果subplots_adjust被手動優先調用,則第一次調用它的任何內容將被tight_layout覆蓋。

E.g.

fig.tight_layout() 
fig.subplots_adjust(hspace=0) 
+2

謝謝,這正是我所需要的。 避免重疊y-ticks的好方法。但是,我通過將中間的y軸修剪到右側來解決它。 'ax2.yaxis.tick_right()' –

1

一種可能的方案是使用add_axis方法等所示here手動創建軸:

import numpy as np 
import matplotlib.pyplot as plt 

t = np.arange(0.0, 2.0, 0.01) 

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

left, width = 0.1, 0.8 
rect1 = [left, 0.5, width, 0.4] 
rect2 = [left, 0.3, width, 0.15] 
rect3 = [left, 0.1, width, 0.15] 

fig = plt.figure() 
ax1 = fig.add_axes(rect1) #left, bottom, width, height 
ax2 = fig.add_axes(rect2, sharex=ax1) 
ax3 = fig.add_axes(rect3, sharex=ax1) 

ax1.plot(t,s1) 
ax2.plot(t[:150],s2[:150]) 
ax3.plot(t[30:],s3[30:]) 

# hide labels 
for label1,label2 in zip(ax1.get_xticklabels(),ax2.get_xticklabels()): 
    label1.set_visible(False) 
    label2.set_visible(False) 

plt.show() 

但是這種方式不能使用tight_layout你顯式地定義的每個軸的大小。