Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CJK Noto Fonts - Chinese and Korean don't work - Font 'default' does not have a glyph #84

Closed
downeykking opened this issue Jan 5, 2023 · 7 comments
Labels
bug Something isn't working help wanted Extra attention is needed upstream issue This issue is from a dependency

Comments

@downeykking
Copy link

downeykking commented Jan 5, 2023

os: ubuntu 22.04
python: 3.9
scienceplots: 2.0.1

After following the FAQ Installing CJK fonts, I have already installed fonts-noto-cjk.
But when i tried the examples like:

with plt.style.context(['science', 'no-latex', 'cjk-tc-font']):
    fig, ax = plt.subplots()
    for p in [5, 7, 10, 15, 20, 30, 38, 50, 100]:
        ax.plot(x, model(x, p), label=p)
    ax.legend(title='Order', fontsize=7)
    ax.set(xlabel=r'電壓 (mV)')
    ax.set(ylabel=r'電流 ($\mu$A)')
    ax.autoscale(tight=True)
    fig.savefig('figures/fig14a.jpg', dpi=300)

with plt.style.context(['science', 'no-latex', 'cjk-sc-font']):
    fig, ax = plt.subplots()
    for p in [5, 7, 10, 15, 20, 30, 38, 50, 100]:
        ax.plot(x, model(x, p), label=p)
    ax.legend(title='Order', fontsize=7)
    ax.set(xlabel=r'电压 (mV)')
    ax.set(ylabel=r'电流 ($\mu$A)')
    ax.autoscale(tight=True)
    fig.savefig('figures/fig14b.jpg', dpi=300)

with plt.style.context(['science', 'no-latex', 'cjk-jp-font']):
    fig, ax = plt.subplots()
    for p in [5, 7, 10, 15, 20, 30, 38, 50, 100]:
        ax.plot(x, model(x, p), label=p)
    ax.legend(title='Order', fontsize=7)
    ax.set(xlabel=r'電圧 (mV)')
    ax.set(ylabel=r'電気 ($\mu$A)')
    ax.autoscale(tight=True)
    fig.savefig('figures/fig14c.jpg', dpi=300)

Only cjk-jp-font made sense. Noto Serif CJK SC and Noto Serif CJK TC both failed.

findfont: Generic family 'serif' not found because none of the following families were found: Noto Serif CJK SC
findfont: Generic family 'serif' not found because none of the following families were found: Noto Serif CJK TC

How can I solve this problem? Thanks in advance.

@machel7
Copy link

machel7 commented Jan 14, 2023

I have same problem in using simplified chinese。

RuntimeWarning: Glyph 21387 missing from current font.
  font.set_text(s, 0, flags=flags)
Font 'default' does not have a glyph for '\u7535' [U+7535], substituting with a dummy symbol.
Font 'default' does not have a glyph for '\u6d41' [U+6d41], substituting with a dummy symbol.
Font 'default' does not have a glyph for '\u7535' [U+7535], substituting with a dummy symbol.
Font 'default' does not have a glyph for '\u6d41' [U+6d41], substituting with a dummy symbol.
Font 'default' does not have a glyph for '\u7535' [U+7535], substituting with a dummy symbol.
Font 'default' does not have a glyph for '\u6d41' [U+6d41], substituting with a dummy symbol.

@echedey-ls
Copy link
Collaborator

Hi @machel7 and @downeykking , I won't be able to troubleshoot it for some weeks due to personal constraints.
Can you two find which Latex distribution are you using (e.g. MikTex, TexLive...?
machel7, could you also please provide OS, Python version and SciencePlots version?

Till I return, you can have a look at this wiki entry, it may hint you in solving this issue. Have a look at the issue mentioned in the wiki, in some examples, it uses a "pgf" backend, that might solve it.

Whatever you find useful, please let us know.

@echedey-ls
Copy link
Collaborator

echedey-ls commented Jan 20, 2023

Well, I had a little time to look into it, enough I believe.
I come with bad news @downeykking and @machel7 . TLDR at the bottom.

Issue confirmed, SciencePlots docs are outdated

I've been doing the wiki step by step (on Ubuntu 22.04, python 3.9), and found I can't run this snippet:

>>> import matplotlib.font_manager as fm
>>> fm._rebuild()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'matplotlib.font_manager' has no attribute '_rebuild'

Went to matplotlib's repo and found this issue, which is addressed in this PR, still draft, has been some time since last update. They've got some problems with the font_manager module, can't really tell what happened to ._rebuild() as they claim it is internal API, so it is not even in the changelogs.

Some troubleshooting

I've been trying matplotlib versions prior to the ._rebuild() deprecation in v3.4.0 (found by trial and error), but with no luck rebuilding the fonts in any case, the fonts-noto-cjk of course installed and in some cases for older versions of matplotlib, even the JP font wasn't found in the font_manager cache (it was for v3.3.0):

{
	"fname": "/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc",
	"name": "Noto Serif CJK JP",
	"style": "normal",
	"variant": "normal",
	"weight": 400,
	"stretch": "normal",
	"size": "scalable",
	"__class__": "FontEntry"
},
{
	"fname": "/usr/share/fonts/opentype/noto/NotoSerifCJK-Bold.ttc",
	"name": "Noto Serif CJK JP",
	"style": "normal",
	"variant": "normal",
	"weight": 700,
	"stretch": "normal",
	"size": "scalable",
	"__class__": "FontEntry"
}

TLDR

The problem is that matplotlib is not reloading the fonts and it can't find the noto CJK (well, only the Japanese in v3.6.3).
I haven't been able to find a workaround to this issue. I encourage you to look for other sources like this stackoverflow post, although it looks a bit out-of-date. Also, here is a repo that claims to wrap matplotlib and allow Chinese fonts, hope it helps.

Whatever solution you find, please, let us know so the next person to have that problem has the reference.

@echedey-ls echedey-ls changed the title Some problems in CJK. CJK Noto Fonts - Chinese and Korean don't work - Font 'default' does not have a glyph Jan 20, 2023
@echedey-ls echedey-ls pinned this issue Jan 20, 2023
@echedey-ls echedey-ls added bug Something isn't working help wanted Extra attention is needed upstream issue This issue is from a dependency labels Jan 20, 2023
@FunClip
Copy link

FunClip commented Mar 17, 2023

I encountered the same problem when using Simplified Chinese.

Finally, I used mplfonts as a temporary solution.

mplfonts is a fonts manager for matplotlib.

This is a python package and command line tool to manage your matplotlib fonts. You can easily resolve the "tofu" problem when plotting with CJK(Chinese, Japanese, Korean) languages.

Hope it helps!

@echedey-ls
Copy link
Collaborator

Hi @FunClip!

Thank you very much for letting us know! I think I will deprecate our CJK styles, as I don't have both time & motivation to try to fix that. I will update the wiki in shortly.

Again, thank you.

@jeremy-feng
Copy link

jeremy-feng commented Nov 26, 2023

Finally it worked with CJK font! Be careful to set "pgf.preamble". I use the code from matplotlib documentation.

import matplotlib as mpl
import matplotlib.pyplot as plt
import scienceplots

plt.style.use(["science"])
mpl.use("pgf")

params = {
    "font.family": "serif",
    "text.usetex": True,
    "pgf.rcfonts": False,
    "pgf.texsystem": "xelatex",
    "pgf.preamble": "\n".join(
        [
            r"\usepackage{fontspec, xeCJK}",
            # r"\setmainfont{Times New Roman}",
            r"\setCJKmainfont{SimSong}",
            r"\setCJKsansfont{Hei}",
        ]
    ),
}
mpl.rcParams.update(params)

x = [1, 2, 3, 4, 5, 6]
y = [1, 4, 9, 16, 25, 36]
plt.figure()
plt.plot(x, y)
plt.title("中文标题 xyz 123")
plt.savefig("test.pdf")
image with Chinese font

It seems that the pgf backend can only save the figure to pdf format. I'm wondering how to save the figure as png, svg, or other formats.

@machel7
Copy link

machel7 commented Dec 15, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed upstream issue This issue is from a dependency
Projects
None yet
Development

No branches or pull requests

5 participants