So in python I have the following code, taken from this answer:
import matplotlib.pyplot as plt
import sympy
x = sympy.symbols('x')
y = 1 + sympy.sin(sympy.sqrt(x**2 + 20))
lat = sympy.latex(y)
#add text
plt.text(0, 0.6, r"$%s$" % lat, fontsize = 50)
#hide axes
fig = plt.gca()
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('out.png', bbox_inches='tight', pad_inches=0)
plt.show()
This opens the text and exports it to a png file just fine:
But this includes whitespace beyond the whitespace outside of the frame. How would you go about cropping the image to export only the text, like a bounding box, like so?
To removing white space around a saved image with Python matplotlib, we call plt. savefig with the bbox_inches argument set to 'tight' . to call savefig to save the flots to myfile. png.
Hide the Whitespaces and Borders in Matplotlib Figure To get rid of whitespace around the border, we can set bbox_inches='tight' in the savefig() method. Similarly, to remove the white border around the image while we set pad_inches = 0 in the savefig() method.
The following is not a perfect solution, but it will hopefully give you some ideas on how to progress:
import matplotlib.pyplot as plt
import sympy
x = sympy.symbols('x')
y = 1 + sympy.sin(sympy.sqrt(x**2 + 2))
lat = sympy.latex(y)
fig = plt.figure()
renderer = fig.canvas.get_renderer()
t = plt.text(0.001, 0.001, f"${lat}$", fontsize=50)
wext = t.get_window_extent(renderer=renderer)
fig.set_size_inches(wext.width / 65, wext.height / 40, forward=True)
fig.patch.set_facecolor('white')
plt.axis('off')
plt.tight_layout()
plt.savefig('out.png', bbox_inches='tight', pad_inches=0)
plt.show()
The idea being that you can determine the size of your text by getting the window extent using the current renderer. It is then also possible to manually specify a figure size. I am though not sure on the correct approach to convert between the two. Note, I added a border to the image so you can see that amount of remaining padding:
As a workaround to this problem, the following approach simply makes use of Python's PIL library to automatically crop the image before saving it:
import io
from PIL import Image, ImageOps
import matplotlib.pyplot as plt
import sympy
x = sympy.symbols('x')
y = 5 /sympy.sqrt(1 + sympy.sin(sympy.sqrt(x**2 + 2)))
lat = sympy.latex(y)
fig = plt.figure()
t = plt.text(0.001, 0.001, f"${lat}$", fontsize=50)
fig.patch.set_facecolor('white')
plt.axis('off')
plt.tight_layout()
with io.BytesIO() as png_buf:
plt.savefig(png_buf, bbox_inches='tight', pad_inches=0)
png_buf.seek(0)
image = Image.open(png_buf)
image.load()
inverted_image = ImageOps.invert(image.convert("RGB"))
cropped = image.crop(inverted_image.getbbox())
cropped.save('out.png')
The cropped version looks like:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With