如何定位字幕?

时间:2019-04-19 20:09:50

标签: python matplotlib

我试图在多面板图形上方调整suptitle,但在弄清楚如何调整figsize并随后放置字幕时遇到了麻烦。

问题在于调用plt.suptitle("my title", y=...)来调整字幕的位置也会调整图形尺寸。一些问题:

  1. suptitle(..., y=1.1)实际将标题放在何处?据我所知,y参数的标题文档指向matplotlib.text.Text,但是我不知道当您有多个子图时,图形坐标是什么意思。

  2. y中指定suptitle时对图形尺寸有什么影响?

  3. 如何手动调整图形的大小和间距(subplots_adjust?)以在每个面板上添加图形标题和整个图形的字幕,以保持图形中每个斧头的大小?

一个例子:

data = np.random.random(size=100)
f, a = plt.subplots(2, 2, figsize=(10, 5))

a[0,0].plot(data)
a[0,0].set_title("this is a really long title\n"*2)
a[0,1].plot(data)
a[1,1].plot(data)

plt.suptitle("a big long suptitle that runs into the title\n"*2, y=1.05);

enter image description here

很明显,我每次做一个图形时都可以调整,但是我需要一个通常不需要人工干预的解决方案。我已经尝试过受限布局和紧凑布局。都无法可靠地处理任何复杂的图形。

3 个答案:

答案 0 :(得分:16)

简短回答

对于那些来自Google的用户来说,它们可以调整散点矩阵上的标题位置,只需将LRESULT CALLBACK Window::HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept { if (msg == WM_NCCREATE) { const CREATESTRUCTW* const pCreate = reinterpret_cast<CREATESTRUCTW*>(lParam); Window* const pWnd = static_cast<Window*>(pCreate->lpCreateParams); SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pWnd)); SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Window::HandleMsgThunk)); return pWnd->HandleMsg(hWnd, msg, wParam, lParam); } return DefWindowProc(hWnd, msg, wParam, lParam); } 参数设置为略低于1的值即可。

y

答案 1 :(得分:1)

1。数字坐标是什么意思?

图形坐标从0到1,其中(0,0)是左下角,(1,1)是右上角。 y=1.05的坐标因此略微位于图形之外。

enter image description here

2。将y指定为字幕时,对图形大小有什么影响?

指定y为字幕对图形大小没有任何影响。

3a。如何手动调整图形尺寸和间距以在每个面板上添加图形标题并为整个图形添加字幕?

首先,不会添加其他换行符。即如果您希望有2行,请不要使用3个换行符(\n)。然后,可以根据需要调整子图参数,以为标题留出空间。例如。 fig.subplots_adjust(top=0.8),并使用y <= 1来使标题位于图中。

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random(size=100)
fig, axes = plt.subplots(2, 2, figsize=(10, 5))
fig.subplots_adjust(top=0.8)

axes[0,0].plot(data)
axes[0,0].set_title("\n".join(["this is a really long title"]*2))
axes[0,1].plot(data)
axes[1,1].plot(data)

fig.suptitle("\n".join(["a big long suptitle that runs into the title"]*2), y=0.98)

plt.show()

enter image description here

3b。 ...同时保持图中每个斧头的大小?

只有通过更改整体图形尺寸,才能保持轴的尺寸并为标题保留足够的空间。

这看起来如下所示,在这里我们定义了一个函数make_space_above,该函数将轴数组作为输入,以及新希望的以英寸为单位的上边距。因此,例如,您得出的结论是,您需要在顶部留出1英寸的空白以容纳标题:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random(size=100)
fig, axes = plt.subplots(2, 2, figsize=(10, 5), squeeze = False)

axes[0,0].plot(data)
axes[0,0].set_title("\n".join(["this is a really long title"]*2))
axes[0,1].plot(data)
axes[1,1].plot(data)

fig.suptitle("\n".join(["a big long suptitle that runs into the title"]*2), y=0.98)


def make_space_above(axes, topmargin=1):
    """ increase figure size to make topmargin (in inches) space for 
        titles, without changing the axes sizes"""
    fig = axes.flatten()[0].figure
    s = fig.subplotpars
    w, h = fig.get_size_inches()

    figh = h - (1-s.top)*h  + topmargin
    fig.subplots_adjust(bottom=s.bottom*h/figh, top=1-topmargin/figh)
    fig.set_figheight(figh)


make_space_above(axes, topmargin=1)    

plt.show()

enter image description here

(左:未调用make_space_above;右:已调用make_space_above(axes, topmargin=1)

答案 2 :(得分:0)

...或使用constrained_layout:

-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(id)change context:(void*)context {
    // ... adjust my window's height
}

enter image description here