Computer modern font in every element of plot (PyPlot)

I’m trying to achieve an homogeneous looking plot where every element of the plot has Computer Modern font using the PyPlot package.
Following some of the answers to existing questions in the forum, this is as close as I’ve gotten:

using PyPlot
using LaTeXStrings

PyPlot.matplotlib[:rc]("text", usetex=false) 
PyPlot.matplotlib[:rc]("mathtext",fontset="cm")
PyPlot.matplotlib[:rc]("font",family="serif",size=12)

x = range(0; stop=2*pi, length=1000); y = sin.(3 * x + 4 * cos.(2 * x))
plot(x, y, color="red", linewidth=2.0, linestyle="--")
title(L"\sin(3x + 4\cos(2x))")
xlabel(L"x")
ylabel(L"y");

With the following output

image

But the ticks’s numbers aren’t in Computer Modern font. Additionally, setting

PyPlot.matplotlib[:rc]("text", usetex=true) 

disables the inline display somehow.

Thanks in advance.

With the GR backend you can get that with:

julia> using Plots, LaTeXStrings

julia> default(fontfamily="Computer Modern",framestyle=:box)

julia> plot(x, y, color="red", linewidth=2.0, linestyle=:dash, label=L"y", title=L"\sin(3x + 4\cos(2x))", xlabel=L"x", ylabel="y")

see: Nice fonts with Plots, GR and LaTeXStrings

1 Like

Thanks for replying! I saw your post earlier today and I just wanted to know if what you did is doable using PyPlot.

2 Likes

Setting this line to true:

PyPlot.matplotlib[:rc]("text", usetex=true)

Seems to fix the issue on external plot window:
PyPlot_CM_ComputerModern_font

Not sure what you mean by inline plot but linking this thread, which is rich in related info.

By inline plots I refer to the plots generated in a Jupyter Notebook’s cell. Setting that line to true in a Jupyter Notebook session just results in the following message

Figure(PyObject <Figure size 640x480 with 1 Axes>)

In PyPlot, you can choose the serif font using the font.serif option. In particular, if you want Computer Modern, you can set this option to "cmr10":

PyPlot.matplotlib[:rc]("text", usetex=false) 
PyPlot.matplotlib[:rc]("mathtext", fontset="cm")
PyPlot.matplotlib[:rc]("font", family="serif", serif="cmr10", size=12)

If I understand correctly, this uses the cmr10.ttf font file bundled with matplotlib.

2 Likes

That does the trick, thanks! Unfortunately, there is a bug inside matplotlib when using cmr10:

RuntimeWarning: Glyph 8722 missing from current font

image

It has been reported here, but the fix doesn’t look easy to implement.

This is a possible workaround (which will fix the issue for tick labels):

PyPlot.matplotlib[:rc]("axes.formatter", use_mathtext = true)

Doing that gives the following warning

Font 'default' does not have a glyph for '\u2212' [U+2212], substituting with a dummy symbol.

According to the discussion in the GitHub issue, after doing that you’d need to tell matplotlib to get the minus sign from some other font file. That’s what I wouldn’t know how to do.