Matplotlib Legend高度(以像素为单位)

时间:2011-02-16 09:21:06

标签: python matplotlib legend

我需要知道图例的大小(以像素为单位)。我似乎只能从任何函数得到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,即使图例的大小发生变化!发生了什么事?

1 个答案:

答案 0 :(得分:3)

这是因为你尚未绘制画布。

在绘制画布之前,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. 推荐,但稍微复杂一点:将回调连接到绘图事件,仅在绘制图形时使用像素值。这允许您使用像素值,同时仅绘制一次图形。

  3. 作为后一种方法的一个简单例子:

    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,但这将取决于your .matplotlibrc file中的默认值)

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

    希望无论如何都有道理。