Times new roman font is always bold

I want to use Times New Roman font as default in a couple of figures to blend well with the (required) article text font.
This used to work fine in matplotlib 1.5.3 (which I used when I last had that requirement). By now, the following

import matplotlib.pyplot as plt
plt.rcParams["font.family"] = "serif"
plt.rcParams["font.serif"] = "Times New Roman"

plt.plot([1,2,3])
plt.xlabel('title')
plt.savefig("test.png")
plt.show()

gives

image

As you can see, the font is Times New Roman, but the font weight is bold.
In matplotlib 1.5.3 it gave

as expected.
It seems there are some similar issues like https://github.com/matplotlib/matplotlib/issues/4822 or https://github.com/matplotlib/matplotlib/issues/8550
In my case I have four times new roman fonts

times.ttf
timesbd.ttf
timesbi.ttf
timesi.ttf

and matplotlib always selects timesbd.ttf. I.e.
DEBUG:matplotlib.font_manager:findfont: Matching :family=serif:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0 to Times New Roman ('C:\\Windows\\Fonts\\timesbd.ttf') with score of 0.145000.

Hence manually selecting the font weight via plt.rcParams["font.weight"] = 100 (also trying other weights), does not help.

So the solution would need to be to explicitely select a particular font (instead of its name).

Trying plt.rcParams["font.serif"] = "C:\\Windows\\Fonts\\times.ttf" does not work. Neither does
plt.rcParams["font.serif"] = FontProperties(fname="C:\\Windows\\Fonts\\times.ttf")

So the question is: How do I use a particular font (file) for the whole document?

There are basically two issues here:

I would guess that whether times.ttf or timesb.ttf gets selected comes down to the order in which they appear in fontList.json, which is basically random, you may be able to just delete timesb.ttf from fontList.json as a stopgap…

Because I needed a quick solution I now used this workaround:

  1. Install a font editor (http://fontforge.org)
  2. Open the times.ttf from the windows font folder
  3. Rename the font to Times New Roman NN
  4. Save it under timesnewromannn.ttf (or any other name)
  5. Install the new font.
  6. Regenerate matplotlib’s font cache (matplotlib.font_manager._rebuild() - is this the recommended way to do so?)
  7. Use the new font as plt.rcParams["font.serif"] = "Times New Roman NN"

The drawback is that this is not portable and there is no way to get that font bold - both of which are not requirements for my specific case.

I think the current “public” API to regen the font cache is to just delete it and let it be regen’d :slight_smile:

Concerning the second point, I want to note that

plt.xlabel('title', fontproperties=FontProperties(fname="C:\\Windows\\Fonts\\times.ttf"))

actually works fine. But it’s not feasable to supply this to each and every text in all figures at hand.

I know this is an old post, but in case someone still didn’t get it right then I suggest another solution that worked for me. The font selection algorithm picks the first font in the Time New Roman family, which has four different files (bold, bold italic, italic and regular). So the steps would be:

  1. Go to C:\Windows\Fonts\Times New Roman
  2. Right-click -> Sort by -> Descending (the order will change so the Times New Roman Regular will end up as the first font, and that will be the font the algorithm will choose).

By the way, does https://github.com/matplotlib/matplotlib/pull/16203 help?