如何获得以英寸为单位的 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()
),这会打乱获取边界框大小的尝试。
解决方法是:
为避免 set_aspect()
出现问题,请在尝试获取边界框大小之前调用 apply_aspect()
。这使得更新后的宽高比实际上修改了边界框的大小,因此我们可以找出它是什么。
使用 ax.get_window_extent()
获取绘图区域的大小 - 这将获取绘图区域的大小,不包括轴标签、刻度等。
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
我正在为一篇论文制作图表,我想在距离图表左上角一定距离处放置一个标签。 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()
),这会打乱获取边界框大小的尝试。
解决方法是:
为避免
set_aspect()
出现问题,请在尝试获取边界框大小之前调用apply_aspect()
。这使得更新后的宽高比实际上修改了边界框的大小,因此我们可以找出它是什么。使用
ax.get_window_extent()
获取绘图区域的大小 - 这将获取绘图区域的大小,不包括轴标签、刻度等。
将其转换为英寸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