使用subplot2grid时如何共享

时间:2014-02-09 16:15:27

标签: python matplotlib

我是最近转换为Python的Matlab用户。我自己管理的大多数Python技能,但是通过绘图,我已经碰壁了,需要一些帮助。

这就是我要做的......

我需要制作一个由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()

在同一图中。怎么做?

2 个答案:

答案 0 :(得分:29)

在创建第二个和第三个子图时,只需指定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)

答案 1 :(得分: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