garrettj403 / SciencePlots

Matplotlib styles for scientific plotting
MIT License
6.96k stars 700 forks source link

Matplotlib warning about no LaTeX-compatible font. #30

Closed arnauqb closed 9 months ago

arnauqb commented 3 years ago

Hi,

Whenever I use this package setting

plt.style.use(["science"])
plt.style.reload_library()

I get the following warning sign multiple times when I plot anything:

matplotlib.texmanager - INFO - No LaTeX-compatible font found for the serif font family in rcParams. Using default.

Now, I have investigated a little, this warning is issued here:

https://github.com/matplotlib/matplotlib/blob/02af61b3000b93efad98f415b4a7eb330c9e46c1/lib/matplotlib/texmanager.py#L124

so it looks like it cannot found the specified font in the attribute TexManager.font_info. I have printed the font that is trying to look at, and it is "Times New Roman", as you would expect, but indeed that font is not found in the font_info dictionary:

https://github.com/matplotlib/matplotlib/blob/02af61b3000b93efad98f415b4a7eb330c9e46c1/lib/matplotlib/texmanager.py#L62

What am I missing here? I am using:

SciencePlots: latest commite release Matplotlib: 3.3.0 OS: Manjaro 20.2 Tex: Texlive installation with these packages:

texlive-bibtexextra
texlive-core
texlive-fontsextra
texlive-formatsextra
texlive-games
texlive-humanities
texlive-latexextra
texlive-music
texlive-pictures
texlive-pstricks
texlive-publishers
texlive-science

Thank you very much for your help!

Hsins commented 3 years ago

Hi @arnauqb

You got that warning because the given font Times New Roman in science style can't be found in your matplotlib cache. The Times New Roman is a font licensed to Microsoft from Monotype so you can't find that font in your machine which runs with Linux operating system.


There are two steps to solve your problem:

  1. Install the Times New Roman fonts on your system.

    There are two packages ttf-times-new-roman and ttf-ms-fonts in AUR (Arch User Repository) and you can install one of them by the package manager yay or yaourt in your Manjaro system.

    # Install Times New Roman Fonts with Package Manager
    $ yay -S ttf-times-new-roman     # Option 1
    $ yay -S ttf-ms-fonts            # Option 2
    
    # Clear and Regenerate Your Font Cache (System Fonts Cache)
    $ sudo fc-cache -f -v
  2. Then clear the font cache of matplotlib.

    After installing those fonts and regenerate the cache, you can directly use them in software like PyCharm or LibreOffice but still get that warning in matplotlib. You should find out the path of the font cache of matplotlib and clear it.

    If you don't know the path of the font cache of matplotlib. Just type python in your terminal and run the commands below in the interactive Python REPL environment.

    >>> import matplotlib as plt
    >>> plt.get_cachedir()
    '/home/hsins/.cache/matplotlib'

    Then clear the font cache of matplotlib by deleting that folder. (The cache would be regenerated when you run matplotlib next time)

    # Clear the Font Cache of Matplotlib (MUST REPLACE THE PATH TO WHAT YOU GOT IN PREVIOUS STEP)
    $ rm -rf /home/hsins/.cache/matplotlib
Hsins commented 3 years ago

Hi @garrettj403

The Times New Roman fonts are not installed in the Linux systems by default because the digital data of Monotype and Linotype releases of Times New Roman are copyrighted.

I think that it would be nice to add the free alternatives fonts of Times New Roman like Linux Libertine or Nimbus Roman No. 9 L to the candidate fonts list. Or just adding the solution above to the FAQ section in the README.md file.

The commands to install Times New Roman with different Linux systems are shown below.

# Debian / Ubuntu
$ sudo add-apt-repository multiverse && sudo apt update
$ sudo apt install ttf-mscorefonts-installer

# Fedora / CentOS
$ sudo dnf install curl cabextract xorg-x11-font-utils fontconfig
$ sudo rpm -i https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm

# Arch Linux
$ yay -S ttf-times-new-roman     # Option 1
$ yay -S ttf-ms-fonts            # Option 2

Moreover, users can just copy the Times New Roman fonts from the Microsoft Windows system and run fc-cache command in Linux systems instead.

garrettj403 commented 3 years ago

Hi @Hsins @arnauqb

Sorry for the delay, and thank you for your answers.

I think that the Times font should be available on all machines and isn't copyrighted by Microsoft. You can use this font by:

import matplotlib.pyplot as plt 
plt.style.use('science')
plt.rcParams.update({
    "font.family": "serif",
    "font.serif": ["Times"]})

However, when I switch to Times on my machine, the math characters fail to render in my PDFs. For example, ax.set_ylabel='Current ($\mu$A)' results in:

fig2-error

I can get around this by using ax.set_ylabel='Current (\textmu A)' instead, but this isn't ideal.

garrettj403 commented 3 years ago

Note: I changed the default font in ieee to Times in commit b0de4cafe5bd5e2d2764b8eb7febd4141b095923 (since IEEE papers use Times New Roman).

garrettj403 commented 3 years ago

Thank you @Hsins for your detailed answer on how to install Times New Roman. I've added a link to this discussion in the README.

garrettj403 commented 3 years ago

In commit 86e369fc1e3dc5df15b7409a3286f64ec8785775, I deleted font.serif : Times New Roman from the Science style. SciencePlots should now use the default serif font on your machine, which should resolve this issue. Please let me know if you still have any problems.

Hsins commented 3 years ago

How about using the code below to let matplotlib find fonts in order instead of given a certain font? (Because I prefer Times New Roman rather than Times and don't want to set it again with the hardcoded plt.rcParams.update(). lol)

font.serif: Nimbus Roman No9 L, Times New Roman, Times, serif
garrettj403 commented 3 years ago

The problem is that the Times font causes rendering errors when used in conjunction with Latex math characters. (See my comment above.)

I'll see if there is a way around this.

arnauqb commented 3 years ago

Thank you very much @Hsins for such detailed responses.

However, I'm still facing the same problem, even though Times New Roman is installed (I tested it works in Gedit for instance). It is weird because it seems that the plot is using Times New Roman:

image

and the font name does appear in my ~/.cache/matplotlib/fontlist-v330.json file, but I still get multiple warnings like the one in my original post.

Edit: The font is indeed detected by the matplotlib font manager:

image

and fc-list: image

Hsins commented 3 years ago

Hi @arnauqb

In commit 86e369f, @garrettj403 have changed the font from Times New Roman to Times. If you use the newest version of SciencePlot in your machine, then it would give warnings if there is no Times font.

Would you show that warning message?

arnauqb commented 3 years ago

Thanks, I have updated to the last commit and it works fine now. I was just stubborn to make the Times New Roman one to work.

marcoBmota8 commented 9 months ago

This is happening with the latests versions of matplotlib (3.8.1) and SciencePlots (2.1.0).

import matplotlib.pyplot as plt
import scienceplots
import numpy as np

x = np.linspace(-10,10)
plt.plot(x,x**2)

gives this annoying message multiple times

INFO:matplotlib.texmanager:No LaTeX-compatible font found for the serif fontfamily in rcParams. Using default.

ednaruiz commented 9 months ago

Hi, im encountering the same problem as @marcoBmota8

echedey-ls commented 9 months ago

I will have a look at whenever I got time.

echedey-ls commented 9 months ago

I can't reproduce on Windows neither on Ubuntu.

from pathlib import Path

science_fonts = ["cmr10", "Computer Modern Serif", "DejaVu Serif"]

cache_dir = get_cachedir() print(cache_dir) font_list_file = Path(cache_dir, "fontlist-v330.json") assert font_list_file.exists()

for style_font in science_fonts: regex = re.compile(style_font, re.IGNORECASE) matched_lines = [line for line in open(font_list_file) if regex.findall(line)] pprint(matched_lines)

ednaruiz commented 9 months ago

Hi @echedey-ls I am on MacOs. In my case I am using the science style.

This would be the output of the code above

['      "fname": "fonts/afm/cmr10.afm",\n',
 '      "fname": "fonts/ttf/cmr10.ttf",\n',
 '      "name": "cmr10",\n']
[]
['      "name": "DejaVu Serif",\n',
 '      "name": "DejaVu Serif Display",\n',
 '      "name": "DejaVu Serif",\n',
 '      "name": "DejaVu Serif",\n',
 '      "name": "DejaVu Serif",\n']

running which latex on the terminal prints a reasonable path, as I set it accordingly after installing MatTex which latex /Library/TeX/texbin/latex

echedey-ls commented 9 months ago

Should be solved now in latest release.

Upgrade with python -m pip install -U SciencePlots

marcoBmota8 commented 8 months ago

This is still an issue. The plots render correclty but I get a numerous amount of "INFO:matplotlib.texmanager:No LaTeX-compatible font found for the serif font family in rcParams. Using default."

output from @echedey-ls 's code

['      "fname": "fonts/afm/cmr10.afm",\n',
 '      "fname": "fonts/ttf/cmr10.ttf",\n',
 '      "name": "cmr10",\n']
[]
['      "name": "DejaVu Serif Display",\n',
 '      "name": "DejaVu Serif",\n',
 '      "name": "DejaVu Serif",\n',
 '      "name": "DejaVu Serif",\n',
 '      "name": "DejaVu Serif",\n']
echedey-ls commented 8 months ago

@marcoBmota8 could you open a new issue and fill all details? Link to this issue if you can.

I'll be unable to have a deep look at this for a few months.

P.D.: specify the style(s) you are using too.