Matplotlib cannot find basic fonts
Question:
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!
Answers:
This work for me::
$ sudo apt-get install msttcorefonts -qq
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.
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]))
-
Delete the fonts located in matplotlib’s cache.
Cache’s location: import matplotlib as mpl; print(mpl.font_manager.get_cachedir())
-
Find matplotlib’s font directory. The path might be similar to
C:Miniconda3pkgsmatplotlib-2.2.2-py36_1Libsite-packagesmatplotlibmpl-datafontsttf
-
Copy necessary fonts like Computer Modern to this directory.
The warning may persist, but your plots’ font should change appropriately.
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
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.
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.
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.
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.
I actually solved by
import matplotlib.font_manager
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()
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']
For windows users
- Just go to the cache dir of matplotlib by using
import matplotlib as mpl
print(mpl.font_manager.get_cachedir())
-
Clear the entire cache file
-
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
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
:
- Find font directory =>
matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
- Put your font file (ttf. file) to that directory.
- Find font config file:
matplotlib.matplotlib_fname()
- Edit to set font type:
pdf.fonttype: 42 # Output Type 3 (Type3) or Type 42 (TrueType)
- Run PyCharm.
- After you start kernel, cache files will be generated. Clean
matplotlib__pycache__
folder.
- Set the font you want to use via:
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Lin Libertine']
- Run the code to generate plots.
If you restart your kernel, if will generate cache files, hence you need to remove them again.
My situation is that I have JupyterHub running in Docker and I need to use matplotlib
to plot and display some Chinese characters as titles.
Here’s how I install new fonts and get new fonts worked( No need to restart the Jupyter container ):
Docker Image version:
- Ubuntu 18.04.3 LTS
- Python 3.7.6
matplotlib.__version__
: 3.1.2
All operations are executed inside the container.
-
download the fonts to /.../python3.7/site-packages/matplotlib/mpl-data/fonts/ttf
-
rebuild the font cache in a notebook. ~/.cache/matplotlib/
(AttributeError: module 'matplotlib' has no attribute 'font_manager').
import matplotlib.font_manager
matplotlib.font_manager._rebuild()
the font cache is per-user base(/home/{username}/.cache/matplotlib/
), so other people might need to rebuild the cache too.
- use the new font. e.g.
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimSun']
You might need to restart the notebook/kernel in step 2 and 3.
Notes:
-
I tried sudo apt install msttcorefonts -qq
but I don’t think that works. Neither do I know what has been installed by that package. apt-file list msttcorefonts
returns nothing.
Why apt-file list msttcorefonts
returns nothing?
-
There is a configuration file /.../python3.7/site-packages/matplotlib/mpl-data/matplotlibrc
on which one can add font.sans-serif
fonts. But without modifying it, the new fonts also work.
For me, using Pycharm on Windows 10, none of the above completely solve my problem.
I have placed Roboto font at folder (replace with your Python package folder):
C:PythonPython310Libsite-packagesmatplotlibmpl-datafontsttf
The last thing I tried that made me successful is to remove the file fontlist-v330.json at folder (replace C:UsersUser with you own folder):
C:UsersUser.matplotlib
In fact, i tried the above because I can’t find a cache folder C:UsersUser.cache.matplotlib as mentioned in this thread.
Interestingly, if you find the following json within the file "fontlist-v330.json" that means you can start using the font (in my case Roboto). There is also tricky part here that I don’t know how to resolve yet. I tried to place both Arial and Arial Narrow font into the folder, but both of them appeared to use "Arial" as their name in this json file. So I have remove the font files for "Arial" and keep those "Arial Narrow" files, so I can use "Arial Narrow" font.
{
"fname": "fonts\ttf\Roboto-Regular.ttf",
"name": "Roboto",
"style": "normal",
"variant": "normal",
"weight": 400,
"stretch": "normal",
"size": "scalable",
"__class__": "FontEntry"
},
Then restart Pycharm which calls the function to set rc parameter:
pyplot.rcParams['font.family'] = 'serif'
pyplot.rcParams['font.serif']=['Roboto']
Then it will not complain being not able to get font file.
Just removing the matplotlib cache and restarting the jupyter instance solved the issue for me:
Removing cache using: rm ~/.cache/matplotlib -rf
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!
This work for me::
$ sudo apt-get install msttcorefonts -qq
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.
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]))
-
Delete the fonts located in matplotlib’s cache.
Cache’s location:import matplotlib as mpl; print(mpl.font_manager.get_cachedir())
-
Find matplotlib’s font directory. The path might be similar to
C:Miniconda3pkgsmatplotlib-2.2.2-py36_1Libsite-packagesmatplotlibmpl-datafontsttf
-
Copy necessary fonts like Computer Modern to this directory.
The warning may persist, but your plots’ font should change appropriately.
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
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.
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.
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.
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.
I actually solved by
import matplotlib.font_manager
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()
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']
For windows users
- Just go to the cache dir of matplotlib by using
import matplotlib as mpl
print(mpl.font_manager.get_cachedir())
-
Clear the entire cache file
-
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
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
:
- Find font directory =>
matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
- Put your font file (ttf. file) to that directory.
- Find font config file:
matplotlib.matplotlib_fname()
- Edit to set font type:
pdf.fonttype: 42 # Output Type 3 (Type3) or Type 42 (TrueType)
- Run PyCharm.
- After you start kernel, cache files will be generated. Clean
matplotlib__pycache__
folder. - Set the font you want to use via:
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Lin Libertine']
- Run the code to generate plots.
If you restart your kernel, if will generate cache files, hence you need to remove them again.
My situation is that I have JupyterHub running in Docker and I need to use matplotlib
to plot and display some Chinese characters as titles.
Here’s how I install new fonts and get new fonts worked( No need to restart the Jupyter container ):
Docker Image version:
- Ubuntu 18.04.3 LTS
- Python 3.7.6
matplotlib.__version__
: 3.1.2
All operations are executed inside the container.
-
download the fonts to
/.../python3.7/site-packages/matplotlib/mpl-data/fonts/ttf
-
rebuild the font cache in a notebook.
~/.cache/matplotlib/
(AttributeError: module 'matplotlib' has no attribute 'font_manager').
import matplotlib.font_manager
matplotlib.font_manager._rebuild()
the font cache is per-user base(/home/{username}/.cache/matplotlib/
), so other people might need to rebuild the cache too.
- use the new font. e.g.
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimSun']
You might need to restart the notebook/kernel in step 2 and 3.
Notes:
-
I tried
sudo apt install msttcorefonts -qq
but I don’t think that works.Neither do I know what has been installed by that package.apt-file list msttcorefonts
returns nothing.
Whyapt-file list msttcorefonts
returns nothing? -
There is a configuration file
/.../python3.7/site-packages/matplotlib/mpl-data/matplotlibrc
on which one can addfont.sans-serif
fonts. But without modifying it, the new fonts also work.
For me, using Pycharm on Windows 10, none of the above completely solve my problem.
I have placed Roboto font at folder (replace with your Python package folder):
C:PythonPython310Libsite-packagesmatplotlibmpl-datafontsttf
The last thing I tried that made me successful is to remove the file fontlist-v330.json at folder (replace C:UsersUser with you own folder):
C:UsersUser.matplotlib
In fact, i tried the above because I can’t find a cache folder C:UsersUser.cache.matplotlib as mentioned in this thread.
Interestingly, if you find the following json within the file "fontlist-v330.json" that means you can start using the font (in my case Roboto). There is also tricky part here that I don’t know how to resolve yet. I tried to place both Arial and Arial Narrow font into the folder, but both of them appeared to use "Arial" as their name in this json file. So I have remove the font files for "Arial" and keep those "Arial Narrow" files, so I can use "Arial Narrow" font.
{
"fname": "fonts\ttf\Roboto-Regular.ttf",
"name": "Roboto",
"style": "normal",
"variant": "normal",
"weight": 400,
"stretch": "normal",
"size": "scalable",
"__class__": "FontEntry"
},
Then restart Pycharm which calls the function to set rc parameter:
pyplot.rcParams['font.family'] = 'serif'
pyplot.rcParams['font.serif']=['Roboto']
Then it will not complain being not able to get font file.
Just removing the matplotlib cache and restarting the jupyter instance solved the issue for me:
Removing cache using: rm ~/.cache/matplotlib -rf