Matplotlib Legend Pixel Height

I need to know the size of the legend in pixels. It seems I can only get height = 1. from any function ... I tried the following

this returns 1.

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

it returns [0,0], [1., 1.]

 box = legend.get_window_extent().get_points() 

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

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

they all return 1, even if the size of the legend changes! what's happening?

+4
source share
1 answer

This is because you have not drawn the canvas.

Pixel values โ€‹โ€‹simply do not exist in matplotlib (or rather, they do not apply to the screen or other output) until the canvas is drawn.

There are several reasons for this, but now I will skip them. Suffice it to say that matplotlib tries to remain as general as possible, and usually avoids working with pixel values โ€‹โ€‹until everything is 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 will only represent the height of the legend in pixels, as it is drawn on the screen! If you save the shape, it will be saved with a different resolution (100, by default) than in the image, so the size of the elements in pixels will be different.

There are two ways:

  • Quick and dirty: draw a canvas on the figure before displaying the pixel values โ€‹โ€‹and remember to explicitly specify the dpi in the drawing when saving (for example, fig.savefig('temp.png', dpi=fig.dpi) .

  • Recommended, but a bit more complicated: connect a callback to the drawing event and work only with pixel values โ€‹โ€‹when drawing. This allows you to work with pixel values โ€‹โ€‹only by drawing a picture 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') 

Pay attention to what is indicated as the legend height for the first and second examples. (31.0 for the second, compared to 24.8 for the first, on my system, but this will depend on the default values โ€‹โ€‹of your .matplotlibrc file )

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

Hope this makes sense, anyway.

+3
source

Source: https://habr.com/ru/post/1339962/


All Articles