防止网格划分子图随图形大小的变化

时间:2021-01-13 23:43:23

I am wanting to create a grid of plots with no intermediate space.

我想创建一个没有中间空间的图网格。

Which would look something like this:

大概是这样的:

防止网格划分子图随图形大小的变化

Code 1

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

However when I add data the spacing between the sub-plots is dependent on dimensions of the figure. (Which can be seen by changing the dimensions of the window opened by fig.show().)

但是,当我添加数据时,子图之间的间隔依赖于图形的维数。(通过改变fig.show()打开的窗口的尺寸可以看出。)

As an example:

作为一个例子:

防止网格划分子图随图形大小的变化

Code 2

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

So, preferably still using GridSpec, is it possible to force the plots to remain together?
The only other alternative I can think of is to access the size of the plots and use these dimensions in plt.figure(figsize=(##,##)), but I can't seem to access the numbers.

所以,最好还是使用GridSpec,是否有可能强迫这些图保持在一起?我唯一能想到的另一种方法是访问这些图的大小,并在plt.figure中使用这些维度(figsize=(##,##)),但是我似乎无法访问这些数字。

Note: The number of plots will vary as well as hight/width ratios. (e.g. GridSpec(2, 3, width_ratios=[10,10,1], wspace=0.0, hspace=0.0) where I would use the last column to hold the colour bar that is used for all the plots.)

注意:图的数量会随着高度/宽度比率的变化而变化。(例如,GridSpec(2, 3, width_比值=[10,10,1],wspace=0.0, hspace=0.0),在这里,我将使用最后一列来保存用于所有绘图的颜色栏。)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Python 2.7.10, Matplotlib 1.4.3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Python 2.7.10 Matplotlib 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

3 个解决方案

#1


3  

I have found two quick and dirty methods:

我发现了两种快速而肮脏的方法:

Method 1: Using figsize

Setting the figsize keyword argument in plt.figure with a width and height that matches the same aspect ratio as the data works reasonably well this little effort.

在plt中设置figsize关键字参数。图的宽度和高度匹配相同的宽高比,因为数据的工作相当不错。

Result from Method 1

由于方法1

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

Method 2: Using set_anchor

Using the set_anchor method for each axis gives a better result but it requires a bit more effort and from some quick tests it won't work for plot arrays greater than 3x2.

对于每个轴使用set_anchor方法可以得到更好的结果,但是这需要更多的努力,并且从一些快速测试中可以看出,对于大于3x2的绘图数组,它是不起作用的。

Result from Method 2

由于方法2

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

#2


0  

You could do a Nested GridSpec using SubplotSpec:

您可以使用SubplotSpec来执行嵌套的GridSpec:

The, above linked, matplotlib example code produces this:

上面链接的matplotlib示例代码生成以下代码:

防止网格划分子图随图形大小的变化

Code, from 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()

#3


0  

As far as I can see, gridspec does not override the default figsize that you set up like this: plt.rcParams['figure.figsize'] = (16,8).

就我所见,gridspec并没有覆盖您设置的默认图形大小:pl . rcparams['图。figsize ')=(16日8)。

#1


3  

I have found two quick and dirty methods:

我发现了两种快速而肮脏的方法:

Method 1: Using figsize

Setting the figsize keyword argument in plt.figure with a width and height that matches the same aspect ratio as the data works reasonably well this little effort.

在plt中设置figsize关键字参数。图的宽度和高度匹配相同的宽高比,因为数据的工作相当不错。

Result from Method 1

由于方法1

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

Method 2: Using set_anchor

Using the set_anchor method for each axis gives a better result but it requires a bit more effort and from some quick tests it won't work for plot arrays greater than 3x2.

对于每个轴使用set_anchor方法可以得到更好的结果,但是这需要更多的努力,并且从一些快速测试中可以看出,对于大于3x2的绘图数组,它是不起作用的。

Result from Method 2

由于方法2

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

#2


0  

You could do a Nested GridSpec using SubplotSpec:

您可以使用SubplotSpec来执行嵌套的GridSpec:

The, above linked, matplotlib example code produces this:

上面链接的matplotlib示例代码生成以下代码:

防止网格划分子图随图形大小的变化

Code, from 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()

#3


0  

As far as I can see, gridspec does not override the default figsize that you set up like this: plt.rcParams['figure.figsize'] = (16,8).

就我所见,gridspec并没有覆盖您设置的默认图形大小:pl . rcparams['图。figsize ')=(16日8)。