Describe the bug
Saving a figure that contains matplotlib mathtext (e.g. r"$\alpha$ (effect size)") to SVG produces a visually broken result in any browser-based SVG renderer (VSCode preview, web browsers). Characters in mixed math/text labels overlap or are incorrectly spaced. The same
figure looks correct in the Jupyter notebook inline preview.
To reproduce
import arcadia_pycolor.mpl as apc_mpl
import matplotlib.pyplot as plt
apc_mpl.setup()
fig, ax = plt.subplots()
ax.set_xlabel(r"$\alpha$ (effect size)")
ax.set_ylabel(r"$R^2$")
ax.plot([1, 2, 3], [1, 4, 9])
apc_mpl.save_figure("test.svg", size="half_square")
Open test.svg in VSCode or any browser. The x- and y-axis labels are garbled.
Root cause
Two possible interacting issues:
-
Font name compaction breaks browser font lookup.
_fix_svg_fonts_for_illustrator replaces 'Atkinson Hyperlegible Next' (CSS family name, with spaces) with 'AtkinsonHyperlegibleNext' (PostScript name, compact). Illustrator resolves fonts by PostScript name, but browsers resolve by CSS family name. After the fix runs, browsers cannot find the font and fall back to a system default.
-
Mathtext pre-positions every character individually.
When a label mixes mathtext and regular text, matplotlib's SVG backend emits each character as a separate with an explicit x offset calculated from Atkinson's glyph metrics. When the browser substitutes a fallback font with different character widths, those pre-calculated offsets are wrong and the text overlaps. This is why the problem only surfaces with mathtext — ordinary labels are stored as a single string and tolerate font substitution gracefully.
Workaround
import matplotlib as mpl
mpl.rcParams['svg.fonttype'] = 'path'
mpl.rcParams['mathtext.default'] = 'regular'
svg.fonttype = 'path' embeds all glyphs as vector paths, eliminating font lookup entirely. mathtext.default = 'regular' makes math characters use the same Atkinson font as surrounding text instead of DejaVu Sans, ensuring visual consistency. The trade-off is that text becomes outlined paths in Illustrator and is no longer live-editable.
Environment
- arcadia-pycolor version: 0.7.3
- matplotlib version: 3.10.0
- Platform: Linux
Describe the bug
Saving a figure that contains matplotlib mathtext (e.g.
r"$\alpha$ (effect size)") to SVG produces a visually broken result in any browser-based SVG renderer (VSCode preview, web browsers). Characters in mixed math/text labels overlap or are incorrectly spaced. The samefigure looks correct in the Jupyter notebook inline preview.
To reproduce
Open test.svg in VSCode or any browser. The x- and y-axis labels are garbled.
Root cause
Two possible interacting issues:
Font name compaction breaks browser font lookup.
_fix_svg_fonts_for_illustrator replaces 'Atkinson Hyperlegible Next' (CSS family name, with spaces) with 'AtkinsonHyperlegibleNext' (PostScript name, compact). Illustrator resolves fonts by PostScript name, but browsers resolve by CSS family name. After the fix runs, browsers cannot find the font and fall back to a system default.
Mathtext pre-positions every character individually.
When a label mixes mathtext and regular text, matplotlib's SVG backend emits each character as a separate with an explicit x offset calculated from Atkinson's glyph metrics. When the browser substitutes a fallback font with different character widths, those pre-calculated offsets are wrong and the text overlaps. This is why the problem only surfaces with mathtext — ordinary labels are stored as a single string and tolerate font substitution gracefully.
Workaround
import matplotlib as mpl
mpl.rcParams['svg.fonttype'] = 'path'
mpl.rcParams['mathtext.default'] = 'regular'
svg.fonttype = 'path' embeds all glyphs as vector paths, eliminating font lookup entirely. mathtext.default = 'regular' makes math characters use the same Atkinson font as surrounding text instead of DejaVu Sans, ensuring visual consistency. The trade-off is that text becomes outlined paths in Illustrator and is no longer live-editable.
Environment