5

我需要知道图例的大小(以像素为单位)。我似乎只能从任何函数中获得 height = 1.... 我尝试了以下

这返回 1。

height = legend.get_frame().get_bbox_to_anchor().height

这将返回 [0,0],[1.,1.]

box = legend.get_window_extent().get_points()

这也返回 [0,0],[1.,1.]

box = legend.get_frame().get_bbox().get_points()

所有这些都返回 1,即使图例的大小发生变化!这是怎么回事?

4

1 回答 1

5

这是因为您还没有绘制画布。

在绘制画布之前,像素值根本不存在于 matplotlib 中(或者更确切地说,它们存在,与屏幕或其他输出无关)。

这有很多原因,但我现在将跳过它们。可以说 matplotlib 尽量保持一般性,并且通常会避免使用像素值,直到绘制完成为止。

举个简单的例子:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

print 'Height of legend before canvas is drawn:'
print legend.get_window_extent().height

fig.canvas.draw()

print 'Height of legend after canvas is drawn:'
print legend.get_window_extent().height

但是,这仅表示在屏幕上绘制的图例的高度(以像素为单位) !如果您保存图形,它将以不同于在屏幕上绘制的 dpi(默认为 100)保存,因此以像素为单位的事物的大小会有所不同。

有两种方法可以解决这个问题:

  1. 又快又脏:在输出像素值之前绘制图形的画布,并确保在保存时明确指定图形的 dpi(例如fig.savefig('temp.png', dpi=fig.dpi).

  2. 推荐,但稍微复杂一点:将回调连接到绘图事件,并且仅在绘制图形时使用像素值。这允许您在只绘制一次图形的同时使用像素值。

作为后一种方法的一个简单示例:

import matplotlib.pyplot as plt

def on_draw(event):
    fig = event.canvas.figure
    ax = fig.axes[0] # I'm assuming only one subplot here!!
    legend = ax.legend_ 
    print legend.get_window_extent().height

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

fig.canvas.mpl_connect('draw_event', on_draw)

fig.savefig('temp.png')

请注意第一个和第二个示例的图例高度的不同。(在我的系统上,第二个为 31.0,第一个为 24.8,但这取决于.matplotlibrc 文件中的默认值)

差异是由于fig.dpi保存图形时默认(默认为 80 dpi)和默认分辨率(默认为 100 dpi)之间的 dpi 不同。

无论如何,希望这是有道理的。

于 2011-02-16T16:21:40.127 回答