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

font family ['serif'] not found. Falling back to DejaVu Sans #13139

Closed
david-waterworth opened this issue Jan 9, 2019 · 58 comments
Closed

font family ['serif'] not found. Falling back to DejaVu Sans #13139

david-waterworth opened this issue Jan 9, 2019 · 58 comments
Milestone

Comments

@david-waterworth
Copy link

Bug report

Bug summary

I'm intermittently getting the warning font family ['serif'] not found. Falling back to DejaVu Sans when plotting with rc('text', usetex=True) enabled. If I delete ~\.cache\matplotlib the warning stops and the charts are rendered with the correct font. But a day or so later it starts again

Code for reproduction

Cannot reliably reproduce as intermittent, can reliably fix by deleting ~\.cache\matplotlib

Matplotlib version

  • Operating system: Ubuntu 18.04
  • Matplotlib version: 3.0.2
  • Matplotlib backend: module://ipykernel.pylab.backend_inline
  • Python version: 3.7.1 x64
  • Jupyter version (if applicable): 4.4.0
  • Other libraries:

installed from pip

@anntzer
Copy link
Contributor

anntzer commented Jan 9, 2019

Can you please provide your ~/.cache/matplotlib/fontlist-v300.json before and after deleting ~/.cache/matplotlib (and reimporting matplotlib to regenerate the json)? Thanks.

@david-waterworth
Copy link
Author

Quick update. Issue occurred again last night (running jupyter notebooks as batch jobs).

I deleted ~/.cache/matplotlib and the issue resolved. I also reimported matplotlib but it didn't regenerate the json?

I'll keep an eye on it.

@anntzer
Copy link
Contributor

anntzer commented Jan 10, 2019

"import matplotlib.font_manager" should regenerate it.

@david-waterworth
Copy link
Author

I had to do it outside jupyter - seems to be ignoring %load_ext autoreload

@david-waterworth
Copy link
Author

I've attached the fontlist-v300.json files before and after deleting ~/.cache/matplotlib

fontlist-v300-after.zip
fontlist-v300-before.zip

@anntzer
Copy link
Contributor

anntzer commented Jan 11, 2019

Thanks. The caches look fine and I don't see how these can trigger the warning for now :/
I guess you can try

fm = matplotlib.font_manager.json_load("/path/to/fontlist-v300.json")
fm.findfont("serif", rebuild_if_missing=False)
fm.findfont("serif", fontext="afm", rebuild_if_missing=False)

when the warning happens. Do these trigger the warning (in a fresh session)? Can you, say, debug-print the scoring in _findfont_cached()?

@david-waterworth
Copy link
Author

david-waterworth commented Jan 11, 2019

I've been playing with a minimal notebook - if I restart kernel and clear outputs, the first time I run the cells below I get the warnings, the 2nd time there's no warning and the 2nd font found is different.

i.e. first run through after restarting kernel:

import matplotlib.pyplot as plt
from matplotlib import rc
rc('font',**{'family':'serif','serif':['Computer Modern Roman']})
rc('text', usetex=True)

import matplotlib.font_manager
import os
fm = matplotlib.font_manager.json_load(os.path.expanduser("~/.cache/matplotlib/fontlist-v300.json"))

fm.findfont("serif", rebuild_if_missing=False)

/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/font_manager.py:1241: UserWarning: findfont: Font family ['serif'] not found. Falling back to DejaVu Sans.
(prop.get_family(), self.defaultFamily[fontext]))
'/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf'

fm.findfont("serif", fontext="afm", rebuild_if_missing=False)

/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/font_manager.py:1241: UserWarning: findfont: Font family ['serif'] not found. Falling back to Helvetica.
(prop.get_family(), self.defaultFamily[fontext]))
'/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm'

2nd (and subsequent) run:

import matplotlib.pyplot as plt
from matplotlib import rc
rc('font',**{'family':'serif','serif':['Computer Modern Roman']})
rc('text', usetex=True)

import matplotlib.font_manager
import os
fm = matplotlib.font_manager.json_load(os.path.expanduser("~/.cache/matplotlib/fontlist-v300.json"))

fm.findfont("serif", rebuild_if_missing=False)

'/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf'

fm.findfont("serif", fontext="afm", rebuild_if_missing=False)

'/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/afm/phvr8a.afm'

@david-waterworth
Copy link
Author

david-waterworth commented Jan 11, 2019

PS System python is 3.6, I'm running pyenv using python 3.7.1 and a virtualenv (called jupyter-3.7.1) if that's of any relevance. In particular it seems that the fonts are stored in a per virtualenv folder but the cache is shared across all python environments on the machine which could potentially cause issues - I'm only using the one pyenv though.

@anntzer
Copy link
Contributor

anntzer commented Jan 11, 2019

In theory the cache should be reusable across venvs (as long as they all have mpl>=3 (not sure of the exact lower bound)).

When you say no warning on the 2nd+ run, do you mean after restarting the kernel in between? Otherwise that's normal, that's due to the fact that Python keeps track of already emitted warnings and does not emit duplicate warnings (by default).

I still don't understand why deleting and regenerating the cache helps (can you provide your matplotlibrc? possibly relevant).
However I see at least one "bug" (say, inaccuracy) in the text layouting code now: even when usetex is True, we try to get the font extent using ismath=False, and that's apparently what triggers the warning (because then you need the font, e.g. Computer Modern Roman in your case, to actually be findable by non-tex machinery :/)

@david-waterworth
Copy link
Author

david-waterworth commented Jan 11, 2019 via email

@anntzer
Copy link
Contributor

anntzer commented Jan 11, 2019

The 2nd+ run has no restart of the kernel - note though it appears to have found the correct (non-fallback) font on the second run?

No? It's still falling back to dejavusans (the afm case is irrelevant I think).
I think it's just that the warning doesn't get printed out a second time (I think?).

@david-waterworth
Copy link
Author

OK, the afm case did change though? Presumably it should be deterministic

run 1:
'/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm'

run 2:
'/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/afm/phvr8a.afm'

@anntzer
Copy link
Contributor

anntzer commented Jan 12, 2019

Perhaps it should, but it's not clear it is... (both of these fonts are Helvetica)

@david-waterworth
Copy link
Author

I missed your request to provide my matplotlibrc.zip

matplotlib.matplotlib_fname()
'/home/david/.pyenv/versions/3.7.1/envs/jupyter-3.7.1/lib/python3.7/site-packages/matplotlib/mpl-da

I've not customised it, there's nothing in $HOME/.config/matplotlib

@tacaswell
Copy link
Member

possible related to #13137

@tacaswell tacaswell added this to the v3.0.3 milestone Jan 14, 2019
@anntzer
Copy link
Contributor

anntzer commented Jan 14, 2019

To the best of my guess this should be closed by #13170, @david-waterworth can you try matplotlib master?

@david-waterworth
Copy link
Author

david-waterworth commented Jan 14, 2019

@anntzer I'm still seeing the warning on master

i.e. (now I get the warning each time, and the reported font path is the same)

import matplotlib
import os
fm = matplotlib.font_manager.json_load(os.path.expanduser("~/.cache/matplotlib/fontlist-v310.json"))
fm.findfont("serif", rebuild_if_missing=False)

findfont: Font family ['serif'] not found. Falling back to DejaVu Sans.
'/home/david/matplotlib/lib/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf'

fm.findfont("serif", fontext="afm", rebuild_if_missing=False)

findfont: Font family ['serif'] not found. Falling back to Helvetica.
'/home/david/matplotlib/lib/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm'

@anntzer
Copy link
Contributor

anntzer commented Jan 14, 2019

That's expected; but what about the actual original use case?

@david-waterworth
Copy link
Author

Thanks @anntzer, master appears to have fixed the original issue (it does now throw an exception with the latex preamble I was using, but I understand that's not supported anyway and I don't need it at this stage)

@anntzer
Copy link
Contributor

anntzer commented Jan 14, 2019

This is good to close then?

@david-waterworth
Copy link
Author

I think so. Thanks!

@vishalmhjn
Copy link

findfont: Font family ['Times New Roman'] not found. Falling back to DejaVu Sans

Matplotlib version: 3.1.2

@jklymak
Copy link
Member

jklymak commented Aug 12, 2021

@thangckt please open a new issue with reproducible steps. Thanks...

@GoingMyWay
Copy link

@thangckt I think Matplotlib does not provide all fonts. You need to download the font file and install it so that Matplotlib can use it.

@charelF
Copy link

charelF commented Jan 15, 2022

I had the same problem on macOS with matplotlib 4.3.4, I could solve it by deleting

~/.matplotlib/fontlist-v330.json

and then restarting jupyter notebook

@hkayann
Copy link

hkayann commented Mar 3, 2022

findfont: Font family ['serif'] not found. Falling back to DejaVu Sans.

This issue still persists. Jupyter run from PyCharm. Lib version is 3.5.1.

@oscargus
Copy link
Contributor

oscargus commented Mar 3, 2022

Try matplotlib.font_manager._rebuild()

@hkayann
Copy link

hkayann commented Mar 4, 2022

@oscargus I get this AttributeError: module 'matplotlib.font_manager' has no attribute '_rebuild'

@DBerke
Copy link

DBerke commented Mar 19, 2022

I'm suddenly getting this error on macOS 10.12.6, first with matplotlib 3.4.2 and just now 3.5.1 after upgrading. Removing ~/.matplotlib/fontlist-v330.json had no effect. Running matplotlib.font_manager._rebuild() gave the same error as hkayann above. It was working fine a few months ago when making plots, and I can't think of any major system changes that might have changed anything.

In my case, the error says findfont: Generic family 'serif' not found because none of the following families were found: stix, cm10 (which are specified in my matplotlibrc file), but grepping for "stix" and "cm" in fontlist-v330.json turns up plenty of hits for both.

@anntzer
Copy link
Contributor

anntzer commented Mar 20, 2022

Please provide your fontlist-v330.json? (and also whether this is with usetex on or off)

@DBerke
Copy link

DBerke commented Mar 20, 2022

Here's my fontlist-v330.json file, and this is with usetex on (specifically, via matplotlibrc file).

@anntzer
Copy link
Contributor

anntzer commented Mar 20, 2022

I guess we'll need a complete repro example. There's no font named "stix" or "cm10" in your fontlist.json, and trying to use such fonts in font.serif with usetex results in

No LaTeX-compatible font found for the serif fontfamily in rcParams. Using default.

if one additionally has plt.set_loglevel("info").

@DBerke
Copy link

DBerke commented Mar 21, 2022

Thanks for taking a look. I was able to fix the problem by simply commenting out the line font.serif : stix, cm10 in my matplotlibrc file, which gave me serif fonts in my plot again (since font.family : serif is still uncommented, presumably). I'm not sure why that worked, but I'm content to leave it here now that it's working again, since it looks like a local configuration issue. Thanks for the help.

@anntzer
Copy link
Contributor

anntzer commented Mar 21, 2022

A full repro example would still be useful, if only so that this doesn't occur again (or perhaps we can make the configuration problem more obvious, etc.).

@DBerke
Copy link

DBerke commented Mar 21, 2022

Ok, I'll try to get one this weekend, I'm pressed for time this week.

@anntzer
Copy link
Contributor

anntzer commented Mar 21, 2022

No hurries.

@sakshamg94
Copy link

sakshamg94 commented Mar 23, 2022

Same issue. I tried both the solutions proposed here:

  • matplotlib.font_manager._rebuild()
  • removing everything in ~/.cache/matplotlib/ and then restarting Jupyter notebook.

Neither work for me

@hkayann
Copy link

hkayann commented Mar 24, 2022

@sakshamg94 can you try the steps I provided on SO.

@iDTer
Copy link

iDTer commented Apr 28, 2022

@sakshamg94 can you try the steps I provided on SO.

didn't help...

@iDTer
Copy link

iDTer commented Apr 28, 2022

Why this bug remains unsolved to this day....

@lancelot1969
Copy link

Having the same issue but in my case:
findfont: Font family ['Heiti TC'] not found. Falling back to DejaVu Sans.

@GorrepatiKaushik
Copy link

I have the same issue
findfont: Font family ['century-gothic'] not found. Falling back to DejaVu Sans.

@hoochanlon
Copy link

Maybe.

import platform
import os

system = platform.system()

if system == 'Darwin':  # macOS
  font_path = '/System/Library/Fonts/STHeiti Light.ttc'
elif system == 'Windows':
  font_path = 'C:/Windows/Fonts/simhei.ttf'
else:  #  unix
  font_path = 'simhei.ttf'

custom_font = fm.FontProperties(fname=font_path)

@jaweriaamjad
Copy link

I am having a similar issue. I have been trying to set fonts as follows:

matplotlib.rcParams['font.family'] = "sans-serif" matplotlib.rcParams['font.sans-serif'] = "Arial"

I have also tried with matplotli.pyplot but keep getting the following message:

findfont: Generic family 'sans-serif' not found because none of the following families were found: Arial

I have looked at the fonts cache and apparently there are not Arial fonts. I have tried removing the cache and regenerating it but the error persists.

fontlist-v300.zip

@oscargus
Copy link
Contributor

oscargus commented Nov 7, 2023

@jaweriaamjad it seems like you do not have Arial installed, so that seems like the most likely problem. (Arial is a Microsoft font and it looks from the paths like you are not using Windows? Helvetica is a good replacement, as in Arial is a "copy" of Helvetica.)

@ZPVIP
Copy link

ZPVIP commented Mar 9, 2024

I have problem to display chinese, I solved the problem by following these steps:

  • Download SimHei.ttf font file from internet and save it to python directory, for me, it's /Users/<username>/venv_3_9/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf
  • Delete ~/.cache/matplotlib and ~/.matplotlib/*.json
  • Find and delete all metadata of Font file, such as xattr -l SimHei.ttf, xattr -d com.apple.quarantine SimHei.ttf
  • Set font in python script: import matplotlib.pyplot as plt, plt.rcParams['font.sans-serif'] = ['SimHei']

If it doesn't work , try to reload python environment: cd /Users/<username>/venv_3_9/bin && deactivate && source ./activate

@QuLogic
Copy link
Member

QuLogic commented Mar 9, 2024

Download SimHei.ttf font file from internet and save it to python directory, for me, it's /Users/<username>/venv_3_9/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf

There is no need to put fonts in a system/package directory like this. Matplotlib will read fonts from standard system paths.

@locorico25
Copy link

Humble attempt here. I am using Ubuntu WSL on Windows and had the same issues anytime I tried to plot anything with matplotlib. I noticed that by doing the following imports the warnings finally disappear:
import matplotlib as mpl
import matplotlib.pyplot as plt

For me the solution was to add import matplotlib as mpl. Hope this can solve the issue!

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

No branches or pull requests