Python:具有不同总大小的子图

时间:2014-04-18 14:09:58

标签: python matplotlib imshow

原帖

我需要制作几个不同大小的子图。

我有大小(x y)35x6µm39x2µm的模拟区域,我想在一个图中绘制它们。所有子图都具有相同的x-ticklabels(x轴上每5µm都有一个网格线。)

当我将子图绘制成一个图形时,具有小x区域的图形被拉伸,因此x-figuresize被完全使用。因此,x网格线不再匹配在一起。

如何实现子图不再拉伸并在左边对齐?

编辑:这是一些代码:

    size=array([[3983,229],[3933,350],[3854,454],[3750,533],[3500,600]], dtype=np.float)
    resolution=array([[1024,256],[1024,320],[1024,448],[1024,512],[1024,640]], dtype=np.float)

    aspect_ratios=(resolution[:,0]/resolution[:,1])*(size[:,1]/size[:,0])

    number_of_graphs=len(data)
    fig, ax=plt.subplots(nrows=number_of_graphs, sharex=xshare)
    fig.set_size_inches(12,figheight)

    for i in range(number_of_graphs):
        temp=np.rot90(np.loadtxt(path+'/'+data[i])) 
        img=ax[i].imshow(temp, 
                 interpolation="none",
                 cmap=mapping, 
                 norm=specific_norm,
                 aspect=aspect_ratios[i]
                 )
        ax[i].set_adjustable('box-forced')

        #Here I have to set some ticks and labels....
        ax[i].xaxis.set_ticks(np.arange(0,int(size[i,0]),stepwidth_width)*resolution[i,0]/size[i,0])
        ax[i].set_xticklabels((np.arange(0, int(size[i,0]), stepwidth_width)))
        ax[i].yaxis.set_ticks(np.arange(0,int(size[i,1]),stepwidth_height)*resolution[i,1]/size[i,1])
        ax[i].set_yticklabels((np.arange(0, int(size[i,1]), stepwidth_height)))
        ax[i].set_title(str(mag[i]))
        grid(True)


    savefig(path+'/'+name+'all.pdf', bbox_inches='tight', pad_inches=0.05) #saves graph

以下是一些例子: 如果我在for循环中绘制不同的矩阵,iPhython会生成一个非常符合我想要的输出。每个子图之间的y-distande是恒定的,每个图的大小是正确的。你可以看到,x标签相互匹配: enter image description here

当我使用子图绘制一个图中的矩阵时,情况并非如此:x-ticks不能组合在一起,并且每个子图在画布上具有相同的大小(这意味着,对于精细的子图,画布上留有更多的空白......)。 enter image description here

我只想使用子图在一个输出文件中获得iPython的第一个结果。

使用GridSpec

在社区告诉我使用GridSpec直接确定子图的大小后,我写了一个自动绘图的代码:

size=array([[3983,229],[3933,350],[3854,454],[3750,533],[3500,600]], dtype=np.float)

#total size of the figure
total_height=int(sum(size[:,1]))
total_width=int(size.max())

#determines steps of ticks
stepwidth_width=500
stepwidth_height=200


fig, ax=plt.subplots(nrows=len(size))
fig.set_size_inches(size.max()/300., total_height/200)

gs = GridSpec(total_height, total_width)
gs.update(left=0, right=0.91, hspace=0.2)

height=0
for i in range (len(size)):    
    ax[i] = plt.subplot(gs[int(height):int(height+size[i,1]), 0:int(size[i,0])])

    temp=np.rot90(np.loadtxt(path+'/'+FFTs[i])) 
    img=ax[i].imshow(temp, 
             interpolation="none", 
             vmin=-100,
             vmax=+100,
             aspect=aspect_ratios[i],
             )

    #Some rescaling            
    ax[i].xaxis.set_ticks(np.arange(0,int(size[i,0]),stepwidth_width)*resolution[i,0]/size[i,0])
    ax[i].set_xticklabels((np.arange(0, int(size[i,0]), stepwidth_width)))
    ax[i].yaxis.set_ticks(np.arange(0,int(size[i,1]),stepwidth_height)*resolution[i,1]/size[i,1])
    ax[i].set_yticklabels((np.arange(0, int(size[i,1]), stepwidth_height)))
    ax[i].axvline(antenna[i]) #at the antenna position a vertical line is plotted
    grid(True)

    #colorbar
    cbaxes = fig.add_axes([0.93, 0.2, 0.01, 0.6])  #[left, bottom, width, height]
    cbar = plt.colorbar(img, cax = cbaxes, orientation='vertical')  
    tick_locator = ticker.MaxNLocator(nbins=3)
    cbar.locator = tick_locator
    cbar.ax.yaxis.set_major_locator(matplotlib.ticker.AutoLocator())
    cbar.set_label('Intensity', 
               #fontsize=12
               )
    cbar.update_ticks()

    height=height+size[i,1]


plt.show()

这是结果...... enter image description here 你有什么想法吗?

1 个答案:

答案 0 :(得分:2)

使用matplotlib.gridspec.GridSpec怎么样? Docs

您可以尝试类似

的内容
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

gs = GridSpec(8, 39)
ax1 = plt.subplot(gs[:6, :35])
ax2 = plt.subplot(gs[6:, :])

data1 = np.random.rand(6, 35)
data2 = np.random.rand(2, 39)

ax1.imshow(data1)
ax2.imshow(data2)
plt.show()

enter image description here