The trick is to render the text, then get its bounding box, and finally adjust the figure size and the vertical positioning of text in the new figure. This saves the figure twice, but as is common in any text engine, the correct bounding box and other parameters can only be correctly obtained after the text has been rendered.
import pylab
formula = r'$x=3^2, y = \frac{1}{\frac{2}{3}}, %s$' % ('test' * 20)
fig = pylab.figure()
text = fig.text(0, 0, formula)
# Saving the figure will render the text.
dpi = 300
fig.savefig('formula.png', dpi=dpi)
# Now we can work with text's bounding box.
bbox = text.get_window_extent()
width, height = bbox.size / float(dpi) + 0.005
# Adjust the figure size so it can hold the entire text.
fig.set_size_inches((width, height))
# Adjust text's vertical position.
dy = (bbox.ymin/float(dpi))/height
text.set_position((0, -dy))
# Save the adjusted text.
fig.savefig('formula.png', dpi=dpi)
The 0.005
constant was added to width
and height
because, apparently, for certain texts Matplotlib is returning a slightly underestimated bounding box, i.e., smaller than required.