通过多个子地块改善子地块大小/间距

我需要在matplotlib中生成一大堆垂直堆叠的图。结果将使用savefig保存并在网页上查看,所以我不关心最终图像有多高,只要子图之间有间隔,这样它们就不会重叠。

不管我让这个数字有多大,次要情节似乎总是重叠的。

我的代码目前看起来像

import matplotlib.pyplot as plt
import my_other_module


titles, x_lists, y_lists = my_other_module.get_data()


fig = plt.figure(figsize=(10,60))
for i, y_list in enumerate(y_lists):
plt.subplot(len(titles), 1, i)
plt.xlabel("Some X label")
plt.ylabel("Some Y label")
plt.title(titles[i])
plt.plot(x_lists[i],y_list)
fig.savefig('out.png', dpi=100)
721638 次浏览

你可以使用plt.subplots_adjust来改变子图之间的间距。

签名:

subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

参数含义(以及建议的默认值)如下:

left  = 0.125  # the left side of the subplots of the figure
right = 0.9    # the right side of the subplots of the figure
bottom = 0.1   # the bottom of the subplots of the figure
top = 0.9      # the top of the subplots of the figure
wspace = 0.2   # the amount of width reserved for blank space between subplots
hspace = 0.2   # the amount of height reserved for white space between subplots

实际的默认值由rc文件控制

使用subplots_adjust(hspace=0)或一个非常小的数字(hspace=0.001)将完全删除子图之间的空白,而hspace=None则不会。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tic


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


x = np.arange(100)
y = 3.*np.sin(x*2.*np.pi/100.)


for i in range(1, 6):
temp = 510 + i
ax = plt.subplot(temp)
plt.plot(x, y)
plt.subplots_adjust(hspace=0)
temp = tic.MaxNLocator(3)
ax.yaxis.set_major_locator(temp)
ax.set_xticklabels(())
ax.title.set_visible(False)


plt.show()

hspace=0hspace=0.001

enter image description here

hspace=None

enter image description here

请复习紧布局指南并尝试使用matplotlib.pyplot.tight_layoutmatplotlib.figure.Figure.tight_layout

举个简单的例子:

import matplotlib.pyplot as plt


fig, axes = plt.subplots(nrows=4, ncols=4, figsize=(8, 8))
fig.tight_layout() # Or equivalently,  "plt.tight_layout()"


plt.show()

布局不紧凑

enter image description here


紧凑的布局

enter image description here

import matplotlib.pyplot as plt


fig = plt.figure(figsize=(10,60))
plt.subplots_adjust( ... )

plt.subplots_adjust方法:

def subplots_adjust(*args, **kwargs):
"""
call signature::


subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=None)


Tune the subplot layout via the
:class:`matplotlib.figure.SubplotParams` mechanism.  The parameter
meanings (and suggested defaults) are::


left  = 0.125  # the left side of the subplots of the figure
right = 0.9    # the right side of the subplots of the figure
bottom = 0.1   # the bottom of the subplots of the figure
top = 0.9      # the top of the subplots of the figure
wspace = 0.2   # the amount of width reserved for blank space between subplots
hspace = 0.2   # the amount of height reserved for white space between subplots


The actual defaults are controlled by the rc file
"""
fig = gcf()
fig.subplots_adjust(*args, **kwargs)
draw_if_interactive()

fig = plt.figure(figsize=(10,60))
fig.subplots_adjust( ... )

图片的大小很重要。

“我试过改变hspace,但增加它似乎只会让所有的图变得更小,而不能解决重叠问题。”

因此,为了使更多的空白和保持子图大小,总图像需要更大。

你可以试试.subplot_tool()

plt.subplot_tool()

tight_layout类似,matplotlib现在(从2.2版开始)提供constrained_layout。与tight_layout相反,constrained_layout是一个属性,它可以在单个优化布局的代码中随时调用,它可以是活动的,并且会在每个绘制步骤之前优化布局。

因此,它需要在子图创建之前或期间被激活,例如figure(constrained_layout=True)subplots(constrained_layout=True)

例子:

import matplotlib.pyplot as plt


fig, axes = plt.subplots(4,4, constrained_layout=True)


plt.show()

enter image description here

constrained_layout也可以通过rcParams来设置

plt.rcParams['figure.constrained_layout.use'] = True

参见新条目是什么约束性布局指南

  • 在用pandas.DataFrame.plot绘制数据帧时解决这个问题,它使用matplotlib作为默认后端。
    • 以下方法适用于指定的任何kind=(例如'bar''scatter''hist'等)。
  • 测试在python 3.8.12pandas 1.3.4matplotlib 3.4.3

导入和样例数据

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt


# sinusoidal sample data
sample_length = range(1, 15+1)
rads = np.arange(0, 2*np.pi, 0.01)
data = np.array([np.sin(t*rads) for t in sample_length])
df = pd.DataFrame(data.T, index=pd.Series(rads.tolist(), name='radians'), columns=[f'freq: {i}x' for i in sample_length])


# default plot with subplots; each column is a subplot
axes = df.plot(subplots=True)

enter image description here

调整间距

  • 调整pandas.DataFrame.plot中的默认参数
    1. 改变figsize:每个subplot的宽度为5,高度为4是一个很好的开始。
    2. 改变layout:(行,列)为子情节的布局。
    3. sharey=Truesharex=True,这样每个子图上的多余标签就不会占用空间。
  • .plot方法返回一个matplotlib.axes.Axes的numpy数组,它应该被平面化以便于处理。
  • 使用.get_figure()从其中一个Axes. xml对象中提取DataFrame.plot图形对象。
  • 如果需要,可以使用fig.tight_layout()
axes = df.plot(subplots=True, layout=(3, 5), figsize=(25, 16), sharex=True, sharey=True)


# flatten the axes array to easily access any subplot
axes = axes.flat


# extract the figure object
fig = axes[0].get_figure()


# use tight_layout
fig.tight_layout()

enter image description here

df

# display(df.head(3))
freq: 1x  freq: 2x  freq: 3x  freq: 4x  freq: 5x  freq: 6x  freq: 7x  freq: 8x  freq: 9x  freq: 10x  freq: 11x  freq: 12x  freq: 13x  freq: 14x  freq: 15x
radians
0.00     0.000000  0.000000  0.000000  0.000000  0.000000  0.000000  0.000000  0.000000  0.000000   0.000000   0.000000   0.000000   0.000000   0.000000   0.000000
0.01     0.010000  0.019999  0.029996  0.039989  0.049979  0.059964  0.069943  0.079915  0.089879   0.099833   0.109778   0.119712   0.129634   0.139543   0.149438
0.02     0.019999  0.039989  0.059964  0.079915  0.099833  0.119712  0.139543  0.159318  0.179030   0.198669   0.218230   0.237703   0.257081   0.276356   0.295520
import matplotlib.pyplot as plt


# create the figure with tight_layout=True
fig, axes = plt.subplots(nrows=4, ncols=4, figsize=(8, 8), tight_layout=True)

enter image description here