Matplotlib 只保存没有空格的文本
Matplotlib save only text without whitespace
所以在 python 我有以下代码,取自 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()
这会打开文本并将其导出到 png 文件就好了:
但这包括框架外空白以外的空白。您将如何裁剪图像以仅导出文本(如边界框)?
以下不是完美的解决方案,但希望能为您提供一些关于如何进行的想法:
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()
想法是您可以通过使用当前渲染器获取 window 范围来确定文本的大小。然后也可以手动指定图形大小。我虽然不确定在两者之间转换的正确方法。请注意,我为图像添加了边框,因此您可以看到剩余的填充量:
作为此问题的解决方法,以下方法仅使用 Python 的 PIL 库在保存图像之前自动裁剪图像:
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')
裁剪后的版本看起来像:
所以在 python 我有以下代码,取自 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()
这会打开文本并将其导出到 png 文件就好了:
但这包括框架外空白以外的空白。您将如何裁剪图像以仅导出文本(如边界框)?
以下不是完美的解决方案,但希望能为您提供一些关于如何进行的想法:
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()
想法是您可以通过使用当前渲染器获取 window 范围来确定文本的大小。然后也可以手动指定图形大小。我虽然不确定在两者之间转换的正确方法。请注意,我为图像添加了边框,因此您可以看到剩余的填充量:
作为此问题的解决方法,以下方法仅使用 Python 的 PIL 库在保存图像之前自动裁剪图像:
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')
裁剪后的版本看起来像: