I set the font style in the matplotlibrc param file to Helvetica (sans serif) and I set text.usetex to 'True' but the axes fonts use serif fonts. How do I get the axes fonts to use sans serif?
Sometimes changing your .matplolibrc won't be enough. For example in OS X Helvetica is installed per default but stored as a .dfont file which is inaccessible to Matplotlib. If this is the case you need to convert it to .ttf and place it in the right folder so that matplotlib can see it. Please see here for more details.
Something like this will help you troubleshoot the issue:
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
path = '/home/username/Helvetica.ttf'
prop = font_manager.FontProperties(fname=path)
mpl.rcParams['font.family'] = prop.get_name()
fig, ax = plt.subplots()
ax.set_title('Test text', fontproperties=prop, size=40)
To see all fonts available to you:
import matplotlib.font_manager
print matplotlib.font_manager.findSystemFonts(fontpaths=None)
I ran into this problem as well, and it was resolved by setting an additional rcparam for the font itself. I.e. using this code gives me the problem you describe:
import matplotlib.pyplot as plt
params = {
'text.usetex': True,
'font.family': 'sans'
}
plt.rcParams.update(params)
Modifying by setting the 'font.sans' option resolved the problem for me:
import matplotlib.pyplot as plt
params = {
'text.usetex': True,
'font.family': 'sans',
'font.sans': 'cm'
}
plt.rcParams.update(params)
Related
I have a piece of code for producing a plot that suddenly stopped working. The issue comes when I try to define the font for the yticks on a plot with a logscale.
Example:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
fig, ax = plt.subplots(figsize=(9,6))
ax.plot(np.arange(10),np.arange(10),color='green',linestyle='-',marker='.')
plt.xticks(font='Nimbus Roman',size=22)
plt.yticks(font='Nimbus Roman',size=22)
ax.set_yscale('log')
this produces an error:
ValueError: None is not a valid value for fontset; supported values are 'cm', 'dejavuserif', 'dejavusans', 'stix', 'stixsans', 'custom'
However, if I remove "font='Nimbus Roman'" fom the yticks part, or remove the logscale, the plot is plotted as expected. I also tried different fonts to no avail. The same error appears for the x-axis if I instead set that one to logscale.
I am using python3.9. This error does not occur in python3.8.6
I am trying to change the font type (from deja-vu to lets' say comic sans or calibri) for the text that appears along with matplotlib's annotate function. However, though I can change the font for all the other elements in the plot, it won't change it for the annotated text. Any help? Below is what I'm working with and how I globally set the font. You'll notice the difference in fonts when comparing the style of "1" on the plots.
import numpy as np
import os, glob
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.font_manager
from matplotlib import rcParams
import pdb
matplotlib.font_manager._rebuild()
# THIS SETS ALL THE RELEVANT FONT STYLE FOR PLOTS
rcParams['font.family'] = 'sans-serif'
rcParams['font.weight'] = 'regular' #can omit this, it's the default
rcParams['font.sans-serif'] = ['calibri']
# test code
ax = plt.figure().add_subplot()
x,y = np.arange(10),np.arange(10)
ax.plot(x,y)
ax.annotate(r'$100^\circ$',
xy=(1.1, 0.1), xycoords='axes fraction',
xytext=(1.1, 0.8), textcoords='axes fraction',
arrowprops=dict(facecolor='black', shrink=0.01),
horizontalalignment='center', verticalalignment='top',
fontsize=15)
The problem is, it's a mathematical text... if you change regular text's font characteristics, you're not going to affect the fonts that Matplotlib uses for mathematical text.
Of course you can modify the font used in mathematical text (is there anything in Matplotlib that you cannot modify?)
Writing mathematical expressions
[...] Mathtext can use DejaVu Sans (default), DejaVu Serif, the Computer Modern fonts (from (La)TeX), STIX fonts (with are designed to blend well with Times), or a Unicode font that you provide. The mathtext font can be selected with the customization variable mathtext.fontset (see Customizing Matplotlib with style sheets and rcParams).
So I am using the pgf backendin matplotlib to include some automatically compiled references to some other parts of my Tex documents (figures, bibliography) in my TeX document.
import matplotlib
matplotlib.use('pgf')
import matplotlib.pyplot as plt
plt.figure()
plt.txt(0.0,0.5,r'Some text compiled in latex \cite{my_bib_tag}')
plt.savefig("myfig.pgf", bbox_inches="tight", pad_inches=0)
Then in my tex document I have the lines:
\usepackage[dvipsnames]{xcolor}
%yada yada yada
\begin{figure}
\input{myfig.pgf}
\end{figure}
It is working great but when I try to add some transparency to the text it doesn't work. For instance when setting:
plt.txt(0.0,0.5,r'Some text compiled in latex \cite{my_bib_tag}', alpha=0.5)
The text appears unchanged, and if I try to do it in the compilation by using \textcolorfrom the xcolor package (or any other commands in LateX, like the transparent package) I get parsing errors when compiling the Python.
I tried escaping characters but somehow I cannot make it work.
plt.txt(0.0,0.5,r'\textcolor{gray}{Some text compiled in latex \cite{my_bib_tag}}', alpha=0.5)
#raise ValueError !Undefined Control Sequence
EDIT 1: I tried adding the required package in the preamble, but it does not work when saving to pgf (with the pgf backend), it works using the Agg backend (I think it is expected behavior). But I need to save it in pgf to have the dynamic parsing of references.
import matplotlib
import matplotlib.pyplot as plt
matplotlib.rcParams["text.usetex"] = True
matplotlib.rcParams["text.latex.preamble"].append(r'\usepackage[dvipsnames]{xcolor}')
matplotlib.verbose.level = 'debug-annoying'
plt.figure()
plt.text(0.0,0.5,r'\textcolor{gray}{Some text compiled in latex \cite{my_bib_tag}}', alpha=0.5)
#works in .png, does not work in .pgf
#plt.savefig("myfig.png", bbox_inches="tight", pad_inches=0)
EDIT 2: A work around is to use the color param in plt.text but what if I would like to use more complicated LateX styling...
Thanks to #ImportanceOfBeingErnest I finally made it work with the pgf backend:
import matplotlib
matplotlib.use('pgf')
import matplotlib.pyplot as plt
pgf_with_custom_preamble = {
"text.usetex": True, # use inline math for ticks
"pgf.rcfonts": False, # don't setup fonts from rc parameters
"pgf.preamble": [
"\\usepackage[dvipsnames]{xcolor}", # load additional packages
]
}
matplotlib.rcParams.update(pgf_with_custom_preamble)
plt.figure()
plt.text(0.0,0.5,r'\textcolor{gray}{Some text compiled in latex \cite{my_biblio_tag}}')
plt.savefig("myfig.pgf", bbox_inches="tight", pad_inches=0)
Tex's \textcolor seems to be ignored in my plottling script
import matplotlib as matplotlib
from matplotlib import pyplot as plt
matplotlib.rcParams.update({'text.usetex': True})
matplotlib.rc(
'text.latex', preamble=r"\usepackage{xcolor}")
fig, ax = plt.subplots()
ax.set_ylabel(r'\textcolor{red}{aaaaaaa}')
plt.show()
does not give me a red text, it produces:
Am I missing something?
It's explained in more detail here : https://matplotlib.org/users/usetex.html but seems like it only works when you export it to a ps file. For me, it works in color if you're saving it as a ps file while the same file inline doesn't work.
Slight workaround here.
import matplotlib as matplotlib
from matplotlib import pyplot as plt
matplotlib.rcParams.update({'text.usetex': True})
matplotlib.rc('text.latex', preamble=r"\usepackage{xcolor}")
fig, ax = plt.subplots()
ax.set_ylabel(r"aaaaaaa", color='r')
#plt.savefig(r"foo.ps")
# you can include the above line if you're using your old code.
plt.show()
I am using the pgf backend in matplotlib 1.5.3 to produce publication-quality figures. Here is how I set up the plotting script.
import matplotlib as mpl
mpl.use('pgf')
pgf_with_latex = { # setup matplotlib to use latex for output
"pgf.texsystem": "pdflatex", # change this if using xetex or lautex
"text.usetex": True, # use LaTeX to write all text
"font.family": "sans-serif",
"font.sans-serif": "Bitstream Vera Sans, Helvetica, Computer Modern Sans Serif",
"pgf.preamble": [
r"\usepackage[utf8x]{inputenc}", # use utf8 fonts because your computer can handle it :)
r"\usepackage[T1]{fontenc}", # plots will be generated using this preamble
r"\usepackage{textcomp}",
r"\usepackage{sfmath}", # sets math in sans-serif
]
}
mpl.rcParams.update(pgf_with_latex)
import matplotlib.pyplot as plt
def newfig():
plt.clf()
fig = plt.figure(figsize=(4, 2))
ax = fig.add_subplot(111)
return fig, ax
fig, ax = newfig()
ax.set_xlabel("Some x-label text")
plt.gcf().tight_layout()
plt.savefig(os.getcwd() + "/test.pdf")
plt.savefig(os.getcwd() + "/test.eps")
I am using the package sfmath to set all math environments in sans-serif. At the end I save in .pdf and .eps format. Here's the problem: While the pdfclearly uses sans-serif font everywhere, the eps file uses serif for all tick labels (not axis labels)! When I modify my LaTeX template to use sfmath it does not change the tick labels.
How can I prevent the epsfrom using serif font in the tick labels?
Edit: After a good day of experimenting, the only (barely) satisfying solution I found was to use .tiff as format, since this is also allowed by the journal. eps just seems to have problems and always turns out different than the pdf or other image formats.