【问题标题】:How to position suptitle?如何定位字幕?
【发布时间】:2019-09-10 01:08:19
【问题描述】:

我正在尝试在多面板图形上方调整 suptitle,但无法弄清楚如何调整 figsize 并随后定位字幕。

问题是调用plt.suptitle("my title", y=...)调整字幕位置也会调整图形尺寸。几个问题:

  1. suptitle(..., y=1.1) 实际上把标题放在哪里了?据我所知,suptitle的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);

显然,我可以在每次制作图形时调整 y,但我需要一个通常无需人工干预即可工作的解决方案。我尝试过约束布局和紧凑布局;两者都不能可靠地处理任何复杂的图形。

【问题讨论】:

  • " 我尝试过约束布局和紧凑布局;对于任何复杂的图形都不能可靠地工作。"紧凑的布局根本不适合suptitle。 constrained_layout 应该,所以如果你确实有它不起作用的情况,请在 GitHub 上打开一个问题,并用一个显示问题的最小示例。
  • Matplotlib tight_layout() doesn't take into account figure suptitlefig.tight_layout(rect=[0, 0.03, 1, 0.95])

标签: python matplotlib


【解决方案1】:

简答

对于那些来自 Google 的用于调整散点矩阵上的标题位置,您可以简单地将 y 参数设置为略低于 1 的值:

plt.suptitle('My Title', y=0.92)

【讨论】:

  • 不错!谢谢...?
  • 谢谢你好心的陌生人
【解决方案2】:

...或使用 constrained_layout:

import matplotlib.pyplot as plt
import numpy as np

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

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

【讨论】:

    【解决方案3】:

    1.图坐标是什么意思?

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

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

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

    3a。如何手动调整图形大小和间距,为每个面板添加图形标题并为整个图形添加副标题?

    首先,不会添加额外的换行符。 IE。如果您想要 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()
    

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

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

    【讨论】:

    • 这是一个很好的开始,谢谢!您对 2. 的回答对于某些后端似乎是正确的,但在 jupyter 中使用 %matplotlib inline 时不正确 - 当我 plt.savefig() 时,suptitle(...,y=1.5) 会被裁剪,但该数字经过调整以将其包含在顶部,如图所示jupyter.
    • 是否有关于图形坐标的文档,或者subplots_adjust 中的值实际上是什么意思? (文档只是说“图的子图的底部”,我可能可以从参数名称中收集到)。或者这是从 stackoverflow 增长的 matplotlib 文档的一个实例? :)
    • 关于带有内联后端的 jupyter 中显示的图像,请参阅this answer。关键是您看到的图像被裁剪或放大,但图形的大小保持不变。关于图形坐标,它真的很简单。 bottom=0.2 表示子图在图形坐标中从 y=0.2 开始,范围从 0 到 1。
    • 很好的答案!有没有办法让您的解决方案 3b 与紧凑的布局一起工作?
    • @VivekSubramanian “保持轴的大小..”和使用紧凑的布局是矛盾的,对吧?所以我不明白你的意思。
    猜你喜欢
    • 2018-06-20
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 2021-05-28
    相关资源
    最近更新 更多