2016-01-19 21 views
2

我想創建一個沒有中間空間的圖的網格。防止GridSpec子圖分離隨圖大小變化

這將是這個樣子:

enter image description here

代碼1

import matplotlib.pyplot as plt 
from matplotlib.gridspec import GridSpec 

fig = plt.figure() 

gs = GridSpec(2, 2, wspace=0.0, hspace=0.0) 

ax1 = fig.add_subplot(gs[0, 0]) 
ax2 = fig.add_subplot(gs[0, 1]) 
ax3 = fig.add_subplot(gs[1, 0]) 
ax4 = fig.add_subplot(gs[1, 1]) 

fig.show() 

然而,當我添加數據的次要情節之間的間距是依賴於數字的尺寸。 (這可通過改變()由fig.show打開窗口的尺寸可以看出)

作爲一個例子:

enter image description here

代碼2

import matplotlib.pyplot as plt 
from matplotlib.gridspec import GridSpec 

import numpy as np 

fig = plt.figure() 

gs = GridSpec(2, 2, wspace=0.0, hspace=0.0) 

ax1 = fig.add_subplot(gs[0, 0]) 
ax2 = fig.add_subplot(gs[0, 1]) 
ax3 = fig.add_subplot(gs[1, 0]) 
ax4 = fig.add_subplot(gs[1, 1]) 

for axis in [ax1, ax2, ax3, ax4]: 
    axis.imshow(np.random.random((10,10))) 

fig.show() 

所以,優選仍然使用GridSpec,是否有可能強迫這些地塊保持在一起?
我能想到的唯一的另一種選擇是訪問圖的大小並在plt.figure(figsize=(##,##))中使用這些尺寸,但我似乎無法訪問這些數字。

注意:圖的數量會隨着高/寬比例而變化。 (例如GridSpec(2, 3, width_ratios=[10,10,1], wspace=0.0, hspace=0.0),我將使用最後一列來保存用於所有圖的顏色條。)

~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 〜 Python的2.7.10,Matplotlib 1.4.3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

回答

0

你可以做Nested GridSpec using SubplotSpec

上面鏈接的matplotlib示例代碼產生了這樣的結果:

enter image description here

代碼,從here

import matplotlib.pyplot as plt 
import matplotlib.gridspec as gridspec 
import numpy as np 

try: 
    from itertools import product 
except ImportError: 
    # product is new in v 2.6 
    def product(*args, **kwds): 
     pools = map(tuple, args) * kwds.get('repeat', 1) 
     result = [[]] 
     for pool in pools: 
      result = [x+[y] for x in result for y in pool] 
     for prod in result: 
      yield tuple(prod) 


def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)): 
    return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d) 

fig = plt.figure(figsize=(8, 8)) 

# gridspec inside gridspec 
outer_grid = gridspec.GridSpec(4, 4, wspace=0.0, hspace=0.0) 

for i in range(16): 
    inner_grid = gridspec.GridSpecFromSubplotSpec(3, 3, 
      subplot_spec=outer_grid[i], wspace=0.0, hspace=0.0) 
    a, b = int(i/4)+1,i%4+1 
    for j, (c, d) in enumerate(product(range(1, 4), repeat=2)): 
     ax = plt.Subplot(fig, inner_grid[j]) 
     ax.plot(*squiggle_xy(a, b, c, d)) 
     ax.set_xticks([]) 
     ax.set_yticks([]) 
     fig.add_subplot(ax) 

all_axes = fig.get_axes() 

#show only the outside spines 
for ax in all_axes: 
    for sp in ax.spines.values(): 
     sp.set_visible(False) 
    if ax.is_first_row(): 
     ax.spines['top'].set_visible(True) 
    if ax.is_last_row(): 
     ax.spines['bottom'].set_visible(True) 
    if ax.is_first_col(): 
     ax.spines['left'].set_visible(True) 
    if ax.is_last_col(): 
     ax.spines['right'].set_visible(True) 

plt.show() 
+0

這是我調查過的東西,但imshow有點奇怪:似乎創建的東西是一個固定大小的圖像,這似乎會導致問題。 – Haydon

2

我已經發現了兩個快速和骯髒的方法:

方法1:使用figsize

設置figsize關鍵字參數在plt.figure與寬度和高度匹配相同的長寬比作爲數據的合理工作這個小小的努力。

Result from Method 1

方法1

import matplotlib.pyplot as plt 
from matplotlib.gridspec import GridSpec 

import numpy as np 

length_x_axis = 30 
length_y_axis = 10 

rows = 3 
columns = 2 

fig_height = 5. 

height = length_y_axis * rows 
width = length_x_axis * columns 

plot_aspect_ratio= float(width)/float(height) 

fig = plt.figure(figsize=(fig_height * plot_aspect_ratio, fig_height)) 

gs = GridSpec(rows, columns, wspace=0.0, hspace=0.0) 

ax1 = fig.add_subplot(gs[0, 0]) 
ax2 = fig.add_subplot(gs[0, 1]) 
ax3 = fig.add_subplot(gs[1, 0]) 
ax4 = fig.add_subplot(gs[1, 1]) 
ax5 = fig.add_subplot(gs[2, 0]) 
ax6 = fig.add_subplot(gs[2, 1]) 

for axis in [ax1, ax2, ax3, ax4, ax5, ax6]: 
    axis.imshow(np.random.random((length_y_axis , length_x_axis))) 

fig.savefig("testing.png") 

方法2:使用set_anchor

使用set_anchor方法爲每個軸提供了一個更好的結果,但它需要更多的努力和一些快速測試它不適用於大於3x2的繪圖陣列。

Result from Method 2

方法2

import matplotlib.pyplot as plt 
from matplotlib.gridspec import GridSpec 

import numpy as np 

fig = plt.figure() 
gs = GridSpec(2, 3, wspace=0.0, hspace=0.0) 

ax1 = fig.add_subplot(gs[0, 0]) 
ax1.set_anchor("SE") 

ax2 = fig.add_subplot(gs[0, 1]) 
ax2.set_anchor("S") 

ax3 = fig.add_subplot(gs[0, 2]) 
ax3.set_anchor("SW") 

ax4 = fig.add_subplot(gs[1, 0]) 
ax4.set_anchor("NE") 

ax5 = fig.add_subplot(gs[1, 1]) 
ax5.set_anchor("N") 

ax6 = fig.add_subplot(gs[1, 2]) 
ax6.set_anchor("NW") 

for axis in [ax1, ax2, ax3, ax4, ax5, ax6]: 
    axis.imshow(np.random.random((10 , 10))) 

fig.show() 
0

據我所看到的,gridspec不會覆蓋你設置了這樣的默認figsizeplt.rcParams['figure.figsize'] = (16,8)