Skip to content

Three lectures render Chinese plot labels as tofu — no matplotlib font configuration #205

Open

Description

@mmcky

Three lectures set Chinese text on matplotlib figures but carry no font configuration, so matplotlib falls back to DejaVu Sans, which has no CJK coverage. The labels render as tofu — blank rectangles — in a valid PNG, and nothing fails.

Lecture Chinese plot text How it broke
divergence_measures.md 7 sites, e.g. plt.ylabel('密度'), axes[0].set_xlabel('KL散度 KL(f, g)') never had a block; labels hand-added 2025-09-12, after the blanket font pass
kesten_processes.md 4 sites, e.g. ax.set_ylabel("收益率"), ax.set_xlabel("日期") regression — block deleted by resync da7b176 (#190), labels kept
jv.md via titles = [r"$s$策略", r"$\phi$策略", "价值函数"] block stripped by resync

Fix

Add the edition's standard block to each, above first plotting use:

FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf"
mpl.font_manager.fontManager.addfont(FONTPATH)
plt.rcParams['font.family'] = ['Source Han Serif SC']

Note fonts/, not _fonts/ — this edition keeps the asset at lectures/fonts/SourceHanSerifSC-SemiBold.otf and the other 103 configured lectures all use that path.

Context

Not yet visible to readers: this edition last published 2025-11-06 and the breakage is post-dated, so the live site still serves pre-resync content. That is timing, not safety — it ships on the next publish.

Root cause and the recommendation against reverting to usetex are in the program review: project-translation reports/2026-07-24-cjk-font-rendering-review.md. Engine side is action-translation#107 — the resync drops i18n adaptations. A further ~12 lectures here use matplotlib with English labels and no config, which becomes tofu the moment anyone localises a label.

CI cannot currently catch any of this: the missing-glyph warning is raised in the kernel subprocess, so -W never sees it.

Activity

  1. mmcky commented on Jul 24, 2026

    @mmcky
    ContributorAuthor

    A runtime scan of the published site adds two pages, one of which is already fixed in main.

    bin/check-tofu in project-translation reads the missing-glyph warnings out of the published HTML, where myst-nb renders the kernel's UserWarning as stderr output. Against https://quantecon.github.io/lecture-python.zh-cn (87 pages — the deployment is behind main, which has 121):

    Page Characters lost Status
    divergence_measures 与关切叠夫密尔度散熵的系诺重 this issue, fixed in #206
    stats_examples 分布本特福 already fixed in main — its block was added by resync aa9ccb7 on 2026-07-19, after publish-2025nov06, so this resolves on the next publish
    ols 一与之亡人入关图均对平年征收数死殖民率的系者间阶险风(): not yet explained

    ols.md has carried the font block since c4c4b86 (2025-03-18), well before publish-2025nov06, so the block was live at publish and the labels still lost their glyphs. I have not diagnosed why. Worth checking for a later rcParams reset in the same document, a figure drawn before the block's cell, or an execution failure that skipped it — matplotlib.md in the programming edition turned out to be the first of those (plt.style.use() resets font.family), so that is the first thing to rule out.

    Method note

    Source-level analysis found divergence_measures, kesten_processes and jv here; the runtime scan found divergence_measures, ols and stats_examples. The overlap is one. Static analysis catches source defects including unpublished ones; runtime catches what readers actually see, plus labels built dynamically. Keep both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions