开发者

Matplotlib Legend Height in pixels

I need to know the size of the legend in pixels. I seem to only be able to get height = 1. from any function... I've tried the following

this returns 1.

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

this returns [0,0],[1.,1.]

box = legend.get_window_extent().get_points()

this also returns [0,0],[1.,1.]

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

all of these return 1, even if the size of the legend changes! wh开发者_C百科at's going on?


This is because you haven't yet drawn the canvas.

Pixel values simply don't exist in matplotlib (or rather, they exist, have no relation to the screen or other output) until the canvas is drawn.

There are a number of reasons for this, but I'll skip them at the moment. Suffice it to say that matplotlib tries to stay as general as possible, and generally avoids working with pixel values until things are drawn.

As a simple example:

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

However, this is only going to represent the height of the legend in pixels as it is drawn on the screen! If you save the figure, it will be saved with a different dpi (100, by default) than it is drawn on the screen, so the size of things in pixels will be different.

There are two ways around this:

  1. Quick and dirty: draw the figure's canvas before outputting pixel values and be sure to explicitly specify the dpi of the figure when saving (e.g. fig.savefig('temp.png', dpi=fig.dpi).

  2. Recommended, but slightly more complicated: Connect a callback to the draw event and only work with pixel values when the figure is drawn. This allows you to work with pixel values while only drawing the figure once.

As a quick example of the latter method:

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')

Notice the different in what is printed as the height of the legend for the first and second examples. (31.0 for the second vs. 24.8 for the first, on my system, but this will depend on the defaults in your .matplotlibrc file)

The difference is due to the different dpi between the default fig.dpi (80 dpi, by default) and the default resolution when saving a figure (100 dpi, by default).

Hopefully that makes some sense, anyway.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜