我正在使用 Matplotlib 生成一堆小图像以叠加在视频剪辑上(我正在添加一种速度计以及一些其他信息)。
但是,我一直无法在垂直方向精确定位一个数字(因此小数点总是完全在同一个位置)。变化非常微妙,只是在视频中看起来很奇怪,因为数字上下“跳动”了 1 个像素。
我尝试了很多方法,使用 annotate
:
va
('top'
、'bottom'
、'baseline'
等);xycoords
系统('figure points'
、'figure pixels'
、'data'
);textcoords
系统('offset points'
,'offset pixels'
);constrained_layout
与否;dpi
和大小值。但无济于事:根据是否显示某些数字,垂直位置略有变化。
真正的情节很复杂,但下面是一个最小的例子:
import matplotlib.pyplot as plt
import numpy as np
import io
from PIL import Image
def no_frame(ax):
ax.set_frame_on(False)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
def test(texts, width=1.5, height=0.5, dpi=72):
fig, ax = plt.subplots(figsize=(width, height))
no_frame(ax)
for i, text in enumerate(texts):
ax.annotate(text,
(i*40, 5), xycoords='figure points',
xytext=(0, 0), textcoords='offset points',
ha='left', va='baseline', fontsize=36)
# save as PIL Image
buf = io.BytesIO()
fig.savefig(buf, dpi=dpi, format='png', bbox_inches='tight', pad_inches=0)
plt.close(fig)
buf.seek(0)
image = Image.open(buf)
return image
那么,这是一个病态的案例,以及如何显示意外的垂直变化(文本'.1'
和'.15'
的点应该在同一高度,但数字5
造成严重破坏):
im = test(('.1', '.15'), dpi=72)
a = np.asarray(im).copy()
# make a red line at the bottom of the text
ypix = np.where(a.min(axis=1)[:, 0] == 0)[0].max()
a[ypix, :] = (255, 0, 0, 255)
fig, ax = plt.subplots(figsize=(6, 2))
no_frame(ax)
ax.imshow(a)
有没有办法强制文本完全处于相同的垂直位置? (我本来希望 va='baseline'
能够实现这一点,但显然情况并非如此)。