From 06cbe09907ecd6ebfa846ff994a53a43ebcd6846 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Fri, 24 Jul 2026 12:06:29 +1000 Subject: [PATCH 1/2] Restore the CJK font block in three lectures (#205) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These three lectures set Chinese text on their figures but never register a CJK font, so matplotlib falls back to DejaVu Sans — which has no CJK coverage — and every Chinese axis label, title and legend entry renders as blank boxes ("tofu"). Nothing errors and a valid PNG is written, so the build stays green and the defect only shows up in the published output. Affected labels include 密度 / KL散度 / JS散度 / 切尔诺夫熵 in divergence_measures.md, 收益率 / 日期 / 时间 / 对数秩 / 对数规模 in kesten_processes.md, and the subplot titles 价值函数 / $s$策略 / $\phi$策略 in jv.md. Adds this edition's standard block to the first code cell that imports matplotlib in each file, immediately after `import matplotlib.pyplot as plt` so it runs before any figure is drawn: import matplotlib as mpl FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" mpl.font_manager.fontManager.addfont(FONTPATH) plt.rcParams['font.family'] = ['Source Han Serif SC'] Matches the convention already used by the other 112 lectures here (see aiyagari.md); the path resolves against lectures/, where fonts/SourceHanSerifSC-SemiBold.otf is checked in. Same class of gap as the five lectures fixed in #196 — nothing else in these files is touched. See QuantEcon/lecture-python.zh-cn#205 --- lectures/divergence_measures.md | 4 ++++ lectures/jv.md | 4 ++++ lectures/kesten_processes.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/lectures/divergence_measures.md b/lectures/divergence_measures.md index 7b537b9..2dfe7a3 100644 --- a/lectures/divergence_measures.md +++ b/lectures/divergence_measures.md @@ -63,6 +63,10 @@ translation: ```{code-cell} ipython3 import matplotlib.pyplot as plt +import matplotlib as mpl +FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" +mpl.font_manager.fontManager.addfont(FONTPATH) +plt.rcParams['font.family'] = ['Source Han Serif SC'] import numpy as np from numba import vectorize, jit from math import gamma diff --git a/lectures/jv.md b/lectures/jv.md index 2efcf36..a673dff 100644 --- a/lectures/jv.md +++ b/lectures/jv.md @@ -53,6 +53,10 @@ translation: from typing import NamedTuple import matplotlib.pyplot as plt +import matplotlib as mpl +FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" +mpl.font_manager.fontManager.addfont(FONTPATH) +plt.rcParams['font.family'] = ['Source Han Serif SC'] import scipy.stats as stats import jax import jax.numpy as jnp diff --git a/lectures/kesten_processes.md b/lectures/kesten_processes.md index 098b0b7..f22eb92 100644 --- a/lectures/kesten_processes.md +++ b/lectures/kesten_processes.md @@ -73,6 +73,10 @@ translation: ```{code-cell} ipython3 import matplotlib.pyplot as plt +import matplotlib as mpl +FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" +mpl.font_manager.fontManager.addfont(FONTPATH) +plt.rcParams['font.family'] = ['Source Han Serif SC'] import numpy as np import quantecon as qe import yfinance as yf From 4310d256dad7cf7d3a236383d49477d9234769bb Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Fri, 24 Jul 2026 12:18:51 +1000 Subject: [PATCH 2/2] Add a DejaVu fallback to font.family, and register the font in two more lectures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting font.family to a single entry removes matplotlib's fallback, so any character the CJK font lacks renders as a blank box. Source Han Serif SC follows Adobe-GB1, which omits subscript digits (U+2080-2083), the vertical ellipsis (U+22EE), and the lunate/symbol Greek forms (U+03F5 epsilon, U+03D5 phi) — all of which these lectures use in figure labels. Measured on matplotlib 3.11.1 with this repo's own font, rendering a label containing 密钥拆分树, key₀, ⋮, ϵ and ϕ: font.family = ['Source Han Serif SC'] -> 4 missing-glyph warnings font.family = ['Source Han Serif SC', 'DejaVu Sans'] -> 0 Two lectures already carried the block and were silently losing characters to it: career.md sets ylabel='ϵ' (and label='ϵ'), affine_risk_prices.md builds label=f"... (r₁ = ...)". Both are fixed by the fallback alone. This deviates from the single-entry dialect used elsewhere in the edition. That is deliberate: the dialect is missing a fallback, and adding one is strictly an improvement everywhere it appears. --- lectures/affine_risk_prices.md | 3 +-- lectures/career.md | 2 +- lectures/divergence_measures.md | 2 +- lectures/jv.md | 2 +- lectures/kesten_processes.md | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lectures/affine_risk_prices.md b/lectures/affine_risk_prices.md index a05b3e4..0e5e213 100644 --- a/lectures/affine_risk_prices.md +++ b/lectures/affine_risk_prices.md @@ -568,8 +568,7 @@ mystnb: import matplotlib as mpl # i18n FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" # i18n mpl.font_manager.fontManager.addfont(FONTPATH) # i18n -mpl.rcParams['font.family'] = ['Source Han Serif SC'] # i18n - +mpl.rcParams['font.family'] = ['Source Han Serif SC', 'DejaVu Sans'] # i18n n_max_1f = 60 maturities_1f = np.arange(1, n_max_1f + 1) diff --git a/lectures/career.md b/lectures/career.md index 3b4c507..1ecb1f8 100644 --- a/lectures/career.md +++ b/lectures/career.md @@ -64,7 +64,7 @@ import matplotlib.pyplot as plt import matplotlib as mpl FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" mpl.font_manager.fontManager.addfont(FONTPATH) -plt.rcParams['font.family'] = ['Source Han Serif SC'] +plt.rcParams['font.family'] = ['Source Han Serif SC', 'DejaVu Sans'] from matplotlib import cm from mpl_toolkits.mplot3d.axes3d import Axes3D diff --git a/lectures/divergence_measures.md b/lectures/divergence_measures.md index 2dfe7a3..659a0e9 100644 --- a/lectures/divergence_measures.md +++ b/lectures/divergence_measures.md @@ -66,7 +66,7 @@ import matplotlib.pyplot as plt import matplotlib as mpl FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" mpl.font_manager.fontManager.addfont(FONTPATH) -plt.rcParams['font.family'] = ['Source Han Serif SC'] +plt.rcParams['font.family'] = ['Source Han Serif SC', 'DejaVu Sans'] import numpy as np from numba import vectorize, jit from math import gamma diff --git a/lectures/jv.md b/lectures/jv.md index a673dff..9192923 100644 --- a/lectures/jv.md +++ b/lectures/jv.md @@ -56,7 +56,7 @@ import matplotlib.pyplot as plt import matplotlib as mpl FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" mpl.font_manager.fontManager.addfont(FONTPATH) -plt.rcParams['font.family'] = ['Source Han Serif SC'] +plt.rcParams['font.family'] = ['Source Han Serif SC', 'DejaVu Sans'] import scipy.stats as stats import jax import jax.numpy as jnp diff --git a/lectures/kesten_processes.md b/lectures/kesten_processes.md index f22eb92..4d3777e 100644 --- a/lectures/kesten_processes.md +++ b/lectures/kesten_processes.md @@ -76,7 +76,7 @@ import matplotlib.pyplot as plt import matplotlib as mpl FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf" mpl.font_manager.fontManager.addfont(FONTPATH) -plt.rcParams['font.family'] = ['Source Han Serif SC'] +plt.rcParams['font.family'] = ['Source Han Serif SC', 'DejaVu Sans'] import numpy as np import quantecon as qe import yfinance as yf