Description
Problem
Sometimes, it would be useful if we could "fake" a text's metrics to pretend it has a different physical size than its real size. Consider for example the following example; pretend the two subfigures are actually two separate figures that I want to save an embed in a presentation on consecutive slides, so that the orange line shows up on the second one:
from pylab import *
fig = figure(layout="constrained")
sfs = fig.subfigures(2)
ax0 = sfs[0].add_subplot()
ax0.plot([1, 2], label="foo")
sfs[0].legend(loc="outside right upper")
ax1 = sfs[1].add_subplot()
ax1.plot([1, 2], label="foo")
ax1.plot([2, 1], label="a longer label")
sfs[1].legend(loc="outside right upper")
show()
As it is, doing an animation would result in everything moving around in a rather ugly manner.
Because I know a bit about the matplotlib text internals :-) I know how to temporarily patch matplotlib to fix this, the trick being to swap out the text when matplotlib is measuring its extents, but not when drawing it:
diff --git i/lib/matplotlib/text.py w/lib/matplotlib/text.py
index 40cd8c8cd6..a042555ac1 100644
--- i/lib/matplotlib/text.py
+++ w/lib/matplotlib/text.py
@@ -363,6 +363,8 @@ class Text(Artist):
"""
thisx, thisy = 0.0, 0.0
lines = self._get_wrapped_text().split("\n") # Ensures lines is not empty.
+ import sys
+ if lines == ["foo"] and sys._getframe().f_back.f_code.co_name != "draw": lines = ["a longer label"]
ws = []
hs = []
which results in
but obviously that is not a "practical" solution (even though I'm happy to have that in my toolbox).
Proposed solution
At least for mathtext strings, we could support the TeX macros \smash
, \phantom
, and their variants, which are the TeX approach for fixing such alignment problems (see e.g. https://www.tug.org/TUGboat/Articles/tb22-4/tb72perlS.pdf). It is not entirely optimal to only support this for mathtext strings, but that's the best I can think of right now -- adding an additional "faked_size" (or similar) property on Text objects seems less convenient, e.g. for the legend case above.