Matplotlib 图例高度(以像素为单位)

Dun*_*can 4 python matplotlib legend

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

这将返回 1。

height = legend.get_frame().get_bbox_to_anchor().height
Run Code Online (Sandbox Code Playgroud)

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

box = legend.get_window_extent().get_points()
Run Code Online (Sandbox Code Playgroud)

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

box = legend.get_frame().get_bbox().get_points()
Run Code Online (Sandbox Code Playgroud)

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

Joe*_*ton 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

作为后一种方法的快速示例:

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')
Run Code Online (Sandbox Code Playgroud)

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

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

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