Skip to content

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

Description

@downeykking
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.

Activity

  1. machel7 commented on Jan 14, 2023

    @machel7

    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.
    
  2. echedey-ls commented on Jan 14, 2023

    @echedey-ls
    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.

  3. echedey-ls commented on Jan 20, 2023

    @echedey-ls
    Collaborator

    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.

  4. changed the title [-]Some problems in CJK.[/-] [+]CJK Noto Fonts - Chinese and Korean don't work - Font 'default' does not have a glyph[/+] on Jan 20, 2023
  5. pinned this issue on Jan 20, 2023
  6. added
    bugSomething isn't working
    help wantedExtra attention is needed
    upstream issueThis issue is from a dependency
    on Jan 20, 2023
  7. FunClip commented on Mar 17, 2023

    @FunClip

    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!

  8. echedey-ls commented on Mar 17, 2023

    @echedey-ls
    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.

  9. jeremy-feng commented on Nov 26, 2023

    @jeremy-feng

    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.

  10. machel7 commented on Dec 15, 2023

    @machel7
  11. Mingzefei commented on Jun 21, 2024

    @Mingzefei

    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!

    I've practically exhausted all methods, and only this approach has proven successful for me. (WSL2, ubuntu2004)
    Those encountering the same problem should consider trying this first. Many thanks once again!

  12. shiquda commented on Sep 1, 2024

    @shiquda

    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!

    I tried this, but unfortunately it didn't work for me. I'm on Windows 11, and I use the following code to solve the problem temporarily:

    plt.style.use(['science', 'grid', 'cjk-sc-font', 'no-latex'])
    
    plt.rcParams.update({
        'font.family': 'Noto Serif CJK SC',
        'axes.unicode_minus': False,
    })

    sin_curve

  13. jiang131072 commented on Sep 18, 2024

    @jiang131072

    OK, it seems matplotlib treat a .ttc font collection as one font. Just use Noto Serif CJK JP or Noto Sans CJK JP is enough to draw SC/TC/KR Glyph.
    image

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

    bugSomething isn't workinghelp wantedExtra attention is neededupstream issueThis issue is from a dependency

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions