Solution to Garbled Double-Byte Fonts in Mac Matplotlib-Generated PDFs

A matplotlib chart and garbled two-byte characters on a blackboard

I' ve been bothered by garbled double-byte fonts in matplotlib-generated PDFs, probably since I upgraded my Mac's OS to Ventura 13. What makes matters more complicated, characters are garbled when viewed in Adobe Acrobat Pro & Reader but look totally OK in Preview.app. This issue doesn't seem limited to Japanese fonts but common among double-byte fonts such as Chinese and Korean ones. I wrote about a makeshift solution before, but this time I came up with a better one.

Double-byte Fonts Garbled in Mac matplotlib-Generated PDFs

In Mac matplotlib-generated PDFs, double-byte characters are unreadable in Adobe Acrobat Reader while they look fine in Preview.app.

Environment: macOS Ventura 13.1, miniconda 22.11.1, Python 3.11.0, numpy 1.24.1, matplotlib 3.6.3

Problem

These figures represent the issue. When I used a double-byte Japanese font, Hiragino Sans, to generate a figure, (1) it was OK in Preview, but (2) all characters, including alphabets and numerals, were garbled in Acrobat. This was also the case with a traditional Chinese font (繁體字), PingFang HK (3,4). Then I assigned a single-byte font, Helvetica, for ASCII characters and found that (5) the PDF was again fine in Preview. In Acrobat, however, double-byte-font characters were missing, while alphabets and numerals appeared normal (6).

This is the Python code for the above plots.

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import rcParams

rcParams['pdf.fonttype']  =  42 
rcParams['font.family']  =  'Hiragino Sans' 
# To assign a single-byte font for alphabets and numerals: rcParams['font.family']  =  ['Helvetica', 'Hiragino Sans']

x = np.linspace(-np.pi,np.pi)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(2,1.5))
ax.plot(x,y)
ax.set_xlabel('これがX軸')
ax.set_ylabel('これがY軸')
ax.set_title('正弦曲線')
plt.tight_layout()
fig.savefig(f"{'-'.join(rcParams['font.family'] )}.pdf")

My research has revealed that all Japanese fonts that come with macOS are incompatible with Acrobat when used in matplotlib-generated PDFs. Furthermore, this problem is not limited to Japanese fonts and is shared by at least one Chinese font, PingFang.

  • Hiragino Maru Gothic Pro
  • Hiragino Mincho ProN
  • Hiragino Sans CNS
  • Hiragino Sans GB
  • Toppan Bunkyu Gothic
  • Toppan Bunkyu Midashi Gothic
  • Toppan Bunkyu Midashi Mincho
  • Toppan Bunkyu Mincho
  • Tsukushi A Round Gothic
  • Tsukushi B Round Gothic
  • YuGothic
  • YuMincho
  • PingFang HK

The issue was reproducible when I clean-installed the latest macOS to another machine and created a new user account and a minimal virtual environment of miniconda with just Python, numpy, and matplotlib. So, something in macOS Ventura, matplotlib, or their default settings should be responsible, not the particular settings of my Mac.

Solution

Acrobat displayed a figure with correct characters when I installed a Japanese font IPAex and set it for double-byte characters in a Python code. Try a font of your tongue if you speak another language.

Steps I took

  1. Download the font
  2. Unzip the archive and copy the .ttf file to /Library/Fonts or ~/Library/Fonts
  3. Delete matplotlib's old font list by typing in your terminal rm -f ~/.matplotlib/fontlist-v330.json.
  4. In a Python code, set the IPAex font for double-byte characters. In the above example, Line 6 should be something like rcParams['font.family'] = ['Helvetica', 'IPAexGothic'].

One thought on “Solution to Garbled Double-Byte Fonts in Mac Matplotlib-Generated PDFs

Comments are closed.