73

I am using matplotlib version 2.0.0 on Python 3 in a miniconda virtual environment. I am working on a unix scientific computing cluster where I don't have root privileges. I am generally executing python code through an ipython notebook. If I do a basic command such as:

import matplotlib.pyplot as plt
plt.scatter([1,5], [1,5])

I get an error message:

path_to_miniconda/miniconda3/envs/conda34/lib/python3.4/site-
packages/matplotlib/font_manager.py:1297: UserWarning: findfont: Font family
['sans-serif'] not found. Falling back to DejaVu Sans
(prop.get_family(), self.defaultFamily[fontext]))

I would like to be able to use a Times New Roman font but even after deleting the Font cache file (fontList.py3k.cache) which I find from here:

import matplotlib as mpl
fm = mpl.font_manager
fm.get_cachedir()

The commands:

mpl.rcParams['font.family'] = ['serif']
mpl.rcParams['font.serif'] = ['Times New Roman']

have no effect, I get the same error as above. The true type fonts directory:

path_to_miniconda/miniconda3/envs/conda34/lib/python3.4/site-packages/matplotlib/mpl-data/fonts/ttf/

only has 40 fonts in it of the type: DejaVuSerif,DejaVuSans,STIX,cmb, cmt, cmy

Any idea what could be going on and how I can add additional fonts? Thanks!

pcu
  • 1,123
  • 10
  • 27
dylkot
  • 1,975
  • 2
  • 18
  • 23

13 Answers13

57

To get it to work, I had to combine the two current top answers. Here's what worked for me:

$ sudo apt install msttcorefonts -qq
$ rm ~/.cache/matplotlib -rf
felleg
  • 703
  • 6
  • 8
32

I had this exact same problem on a Vagrant VM running Ubuntu Xenial 64-bit. No matter how many fonts I had already installed, matplotlib was having a problem with the "system" font name "sans-serif". I fixed it by:

  • Stopping Jupyter
  • Installing font-manager: sudo apt install font-manager
  • Cleaning the matplotlib cache directory: rm ~/.cache/matplotlib -fr
  • Restarting Jupyter.

No more error messages about sans-serif.

Craig Kelly
  • 2,536
  • 1
  • 17
  • 15
  • 5
    Note that you can get the cache directory (which varies by OS) with: `matplotlib.font_manager.get_cachedir()` – DilithiumMatrix Jul 23 '18 at 16:10
  • 1
    `fontmanager.get_cachedir()` didn't exist for me (on OSX), but `fontmanager._fmcache` did, and deleting the json file it points to, solved the issue. – Thomas Ahle May 21 '20 at 09:42
25

This work for me::

$ sudo apt-get install msttcorefonts -qq
user3313834
  • 6,579
  • 7
  • 50
  • 91
  • 8
    Docker users will need to accept the license agreement automatically: `RUN echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections` `RUN apt-get install -y ttf-mscorefonts-installer` – Matt Kleinsmith Nov 09 '17 at 12:56
  • 2
    This worked after I deleted the matplotlib font cache file described in the question. – user2699 Mar 05 '19 at 17:27
  • 5
    You need to clear the cache: ```rm ~/.cache/matplotlib -fr``` – jubueche Oct 29 '19 at 16:28
16

A solution for Windows users, when confronted with the warning:

UserWarning: findfont: Font family ['serif'] not found. Falling back to DejaVu Sans
(prop.get_family(), self.defaultFamily[fontext]))
  1. Delete the fonts located in matplotlib's cache.
    Cache's location: import matplotlib as mpl; print(mpl.font_manager.get_cachedir())

  2. Find matplotlib's font directory. The path might be similar to
    C:\Miniconda3\pkgs\matplotlib-2.2.2-py36_1\Lib\site-packages\matplotlib\mpl-data\fonts\ttf

  3. Copy necessary fonts like Computer Modern to this directory.

The warning may persist, but your plots' font should change appropriately.

mab
  • 2,418
  • 25
  • 36
  • 3
    Worked exactly as you described for me on windows (inc. persisting warning) – Christian Apr 30 '18 at 08:42
  • 3
    The solution did not work for me (`module 'matplotlib' has no attribute 'font_manager'`), but instead I found that `print(matplotlib.font_manager.findfont('the font i want'))` shows me where the font (or the default font if the font I want is not found) is located. – Mariuslp Jun 04 '21 at 19:49
  • 1
    Just in case someone gets this error: ```'module' object has no attribute 'font_manager'```. I solved it by first importing the font_manager like this: ```import matplotlib.font_manager as fm``` and then: ```print(fm.get_cachedir())``` – Javier TG Jul 13 '21 at 22:18
8

There is a conda package for it[1]. So, you don't really need sudo to fix this!

conda install -c conda-forge -y mscorefonts

UPDATE: the below functionality is broken in recent matplotlib (no longer works on v3.4.3)

Also, if you dont want to restart jupyter, you can force rebuild matplotlib font cache

import matplotlib
matplotlib.font_manager._rebuild()

[1] - https://anaconda.org/conda-forge/mscorefonts

Thamme Gowda
  • 10,359
  • 3
  • 46
  • 54
  • 2
    This is clean and worked first time for my Windows installation. Thanks :-) – Paddy3118 Mar 24 '21 at 07:20
  • 1
    Also did not have to restart jupyter with `rm ~/.cache/matplotlib -rf` :) – Vira Jun 29 '21 at 00:23
  • 1
    +1. Thanks a lot! I did not remove any cache or anything else. Just `import matplotlib matplotlib.font_manager._rebuild()` solved my problem. – Md. Sabbir Ahmed Sep 21 '21 at 20:26
  • 2
    Not sure what version this is for, but for Python 3.8.10 with matplotlib 3.5.0, `AttributeError: module 'matplotlib.font_manager' has no attribute '_rebuild'` – sdbbs Nov 19 '21 at 14:35
7

I actually solved by

import matplotlib.font_manager

GRquanti
  • 445
  • 4
  • 18
6

I had this problem with anaconda env (it could be useful in other related situations as well). For example, for base env, I have checked the following directory: /home/***/anaconda3/pkgs/matplotlib-base-3.1.3-py37hef1b27d_0/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf/

and noticed that I have DejaVuSerif.ttf intalled there, so instead of using plt.rcParams['font.family'] = 'Serif' I used plt.rcParams['font.family'] = 'DeJavu Serif' ( there is a space between "DeJavu and serif" ). i worked for me.

import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'DeJavu Serif'
plt.rcParams['font.serif'] = ['Times New Roman']
Mohammad
  • 129
  • 1
  • 4
3

It took me many hours to finally figure out that I needed to update matplotlib.

My original version of 3.0.3 (which came with my jupyter-datascience docker image) would give me this error, but updating to 3.1.1 fixed it.

In the end, my docker script:

RUN pip install matplotlib==3.1.1
COPY fonts /usr/share/fonts/truetype/
RUN fc-cache -fv
RUN rm /home/jovyan/.cache/matplotlib -rf

is what did it for me.

Sylhare
  • 4,330
  • 7
  • 50
  • 67
celine
  • 31
  • 2
  • 1
    It works! You save me an hour! My original version is 3.0.2, after update to 3.1.1, it no longer pop `Font family ... not found` error message. – allenyllee May 27 '20 at 06:22
1

I was facing a similar issue in a Cloud Datalab docker image running on a gcloud VM. Executing the following fixed the issue for me:

$ sudo apt install msttcorefonts -qq
$ rm ~/.cache/matplotlib -rf

Here is instructions on how to get to the docker image running on the gcloud VM containing the Datalab instance just in case.

Soroush Sotoudeh
  • 178
  • 1
  • 14
1

try all the methods above, not work for me.

my way to solve this is a little dirrent cause I'm using conda on ubuntu server running jupyter

locate -b '\mpl-data'

find a folder

/usr/share/matplotlib/mpl-data

then I add the simhei fonts into the font folder in mpl-data . then remove matplotlib fonts cache

rm -rf ~/.cache/matplotlib

restart jupyter notebook, and it works.

0

I am in macOS with jupyter notebook, I solved with the following, first close your jupyter notebook. Then find out the font path by doing the following in Python

import matplotlib
print(matplotlib.matplotlib_fname())

it prints /Users/zyy/anaconda2/lib/python2.7/site-packages/matplotlib/mpl-data/matplotlibrc for me, notice matplotlibrc is a file, not a directory.

Then download font SimHei, and copy it to the directory fonts/ttf under the mpl-data/ directory above.

Delete directory ~/.cache/matplotlib and restart your jupyter notebook, everything should be good.

zyy
  • 953
  • 11
  • 22
0

For windows users

  1. Just go to the cache dir of matplotlib by using

import matplotlib as mpl

print(mpl.font_manager.get_cachedir())

  1. Clear the entire cache file

  2. Lastly again import matplotlib

Hopefully u will also find it helpful as it worked for me

P:S - If you wish you can restart your jupyter/ide (optional) after this

  • Hi, First I found out the location using .getcachedir() function,after that I deleted everything from that file including the empty cache file and the fonts generated.After that I started my Jupiter notebook again and importer matplotlib and seaborn,you will find that once you import again the fonts are automatically regenerated. That would hopefully solve your problem as it solved mine – anuroop nag Apr 07 '21 at 12:20
0

None of the above worked for me. I had to combine the provided solutions.

I run Jupyter from PyCharm in Windows 10. Here is my workaround. Before doing these steps, import the font manager via import matplotlib.font_manager:

  1. Find font directory => matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
  2. Put your font file (ttf. file) to that directory.
  3. Find font config file: matplotlib.matplotlib_fname()
  4. Edit to set font type: pdf.fonttype: 42 # Output Type 3 (Type3) or Type 42 (TrueType)
  5. Run PyCharm.
  6. After you start kernel, cache files will be generated. Clean \matplotlib\__pycache__ folder.
  7. Set the font you want to use via:
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Lin Libertine']
  1. Run the code to generate plots.

If you restart your kernel, if will generate cache files, hence you need to remove them again.

Mr. Panda
  • 393
  • 1
  • 13