如何获得以英寸为单位的 matplotlib 绘图区域的大小?

How do you get the size of a matplotlib plot area in inches?

我正在为一篇论文制作图表,我想在距离图表左上角一定距离处放置一个标签。 ax.text(x, y, label, transform=ax.transAxes) 几乎做到了这一点,但将位置指定为绘图大小的一小部分。如果我可以获得绘图区域的绝对大小,我可以使用它来进行转换。例如,在下面的脚本中,我如何获得高度和宽度?

编辑:我想要绘图的高度和宽度(不是整个图形的高度和宽度),不包括标签、刻度等。

from matplotlib import pyplot as plt
import numpy as np

data = np.random.rand(10,10)

fig, ax = plt.subplots()

ax.pcolormesh(data)

ax.set_aspect("equal")

# get width and height of plot here?

plt.show()

我确实设法找到了一种方法来做到这一点。它变得更加复杂,因为我使用 set_aspect() - set_aspect() 修改 ax 的边界框,但默认情况下不应用修改,直到 ax 被绘制(例如通过plt.show()),这会打乱获取边界框大小的尝试。

解决方法是:

  1. 为避免 set_aspect() 出现问题,请在尝试获取边界框大小之前调用 apply_aspect()。这使得更新后的宽高比实际上修改了边界框的大小,因此我们可以找出它是什么。

  2. 使用 ax.get_window_extent() 获取绘图区域的大小 - 这将获取绘图区域的大小,不包括轴标签、刻度等。

  3. ax.get_window_extent() 的结果在 'display units' 中,我们可以使用 fig.dpi.

    将其转换为英寸

因此添加我想要的标签类型作为示例:

from matplotlib import pyplot as plt
import numpy as np

data = np.random.rand(10,10)

fig, ax = plt.subplots()

ax.pcolormesh(data)

ax.set_aspect("equal")
ax.apply_aspect()

bbox = ax.get_window_extent()

# dpi used to convert from display units to inches
dpi = fig.dpi

height = bbox.height / dpi  # in inches
width = bbox.width / dpi  # in inches

x = 0.2 # in inches
y = 0.1 # in inches

ax.text(x / width, 1.0 - y / height, "(a)", verticalalignment="top", color="w", transform=ax.transAxes)

plt.show()

给出:

编辑:我用 matplotlib-3.3.2 测试了这个解决方案。

您上面的回答很好,但也许更好:

import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms

fig, ax = plt.subplots()

trans = (fig.dpi_scale_trans +
         mtransforms.ScaledTranslation(0, 1, ax.transAxes))

ax.set_aspect(1)
ax.text(0.1, -0.2, 'Boo', transform=trans)
plt.show()

您可以在以下位置阅读更多信息:https://matplotlib.org/tutorials/advanced/transforms_tutorial.html#plotting-in-physical-coordinates