有长标题的plt.tight_layout越野车?

时间:2017-03-31 07:22:35

标签: python matplotlib

问题:

为什么即使在plt.tight_layout()重新开始之后,每个plt.clf()如何缩小数字?

拿这个片段:

plt.figure(1).clf()
plt.plot(range(10))
plt.title("Blah")
plt.tight_layout()

for _ in range(5):
    plt.figure(2).clf()
    plt.plot(range(10))
    plt.title("Blah")
    plt.tight_layout()

正如预期的那样,数字1和2是相同的。

但是现在让标题很长:

plt.figure(3).clf()
plt.plot(range(10))
plt.title("Blahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")
plt.tight_layout()

for _ in range(5):
    plt.figure(4).clf()
    plt.plot(range(10))
    plt.title("Blahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")
    plt.tight_layout()

并且图3和图4不再相同,图4水平收缩,这种收缩随着循环次数的增加而增加。

如果有人可以对此有所了解......

一些背景信息:

你可能会问“为什么你会在for循环中放置这样的情节?”。我实际上没有,但我有一个交互式脚本,我可以用一些变化多次重新绘制相同的数字,这种收缩看起来是一样的......

我的python版本是:

Python 2.7.11 |Anaconda 4.0.0 (64-bit)| (default, Feb 16 2016, 09:58:36) [MSC v.1500 64 bit (AMD64)]

顺便说一下,如果你增加plt.tight_layout()次呼叫的次数,你最终会收到错误:

Traceback (most recent call last):

  File "<ipython-input-89-1a59da108bdf>", line 5, in <module>
    plt.tight_layout()

  File "C:\Users\julien.bernu\AppData\Local\Continuum\Anaconda2\lib\site-packages\matplotlib\pyplot.py", line 1379, in tight_layout
    fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)

  File "C:\Users\julien.bernu\AppData\Local\Continuum\Anaconda2\lib\site-packages\matplotlib\figure.py", line 1756, in tight_layout
    self.subplots_adjust(**kwargs)

  File "C:\Users\julien.bernu\AppData\Local\Continuum\Anaconda2\lib\site-packages\matplotlib\figure.py", line 1612, in subplots_adjust
    self.subplotpars.update(*args, **kwargs)

  File "C:\Users\julien.bernu\AppData\Local\Continuum\Anaconda2\lib\site-packages\matplotlib\figure.py", line 226, in update
    raise ValueError('left cannot be >= right')

ValueError: left cannot be >= right

1 个答案:

答案 0 :(得分:1)

当您清除图形时,图形保留其SubplotParams,已通过调用tight_layout进行调整。

请考虑以下代码:

import matplotlib.pyplot as plt

left = []; right = []
def print_subplotparams(sp):
    t = "left={left:.3f}, right={right:.3f}, top={top:.3f}, bottom={bottom:.3f}"
    t = t.format(left=sp.left, right=sp.right, top=sp.top, bottom=sp.bottom)
    left.append(sp.left); right.append(sp.right)
    print(t)

fig = plt.figure(1)
print_subplotparams(fig.subplotpars)
fig.clear()

for _ in range(8):
    fig = plt.figure(1)
    # uncomment to see difference
    #fig.subplots_adjust(left=0.125, right=0.900, top=0.880, bottom=0.110)
    plt.plot(range(10))
    plt.title("Blahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")
    plt.tight_layout()
    print_subplotparams(fig.subplotpars)
    fig.clear()

fig = plt.figure(2, figsize=(5,3))
plt.plot(range(len(left)), left, label="left")
plt.plot(range(len(right)), right, label="right")
plt.title("SubplotParams left/right as function of calls to tight_layout")
plt.xlabel("number of call to tight_layout")
plt.ylabel("left/right parameter")
plt.tight_layout()
plt.show()

产生:

enter image description here

可以看出,在每个循环步骤中tight_layout从已调整的参数调整并使它们更小。

为了防止人们在每一步中重置SubplotParams

fig.subplots_adjust(left=0.125, right=0.900, top=0.880, bottom=0.110)

在这种情况下,tight_layout始终以相同的初始参数开始优化,其最终值不会改变。

enter image description here