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]
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.
source share