I'm producing a big report with lot's of figures with some LateX content, and to maintain layout coherence I use a predefined mplstyle file with the following related definitions:
# FONT
font.family: serif
font.size: 9.0
font.serif: Palatino
font.sans-serif: DejaVu Sans
font.weight: normal
#font.stretch: normal
# LATEX
text.usetex: True
However, I ran into a specific figure where I need to use LateX siunitx
. Here is a stripped down version of my code, that includes the solution for this tex.stackexchange question:
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib as mpl
import seaborn as sns
def get_binarized_categories(categories=['None', 'Low', 'Medium', 'Med +', 'High', 'Very High'],
bins=[-0.01, 0.000001, 0.10, 0.20, 0.30, 0.666, 1]):
criteria_str = 'C'
label_cats = []
special_cats = ['None', 'Low', 'Very High']
for i, cat in enumerate(categories):
if cat not in special_cats:
bin_low, bin_high = bins[i], bins[i+1]
label = f'${bin_low:9.3f}\\leqslant\\Delta {criteria_str}<{bin_high:9.3f}$'
elif cat == 'None':
label = f'$\\Delta {criteria_str}=0$'
elif cat == 'Low':
bin_low, bin_high = bins[i], bins[i+1]
sc_notation = f'{bin_low:.2e}'
sc_notation = f'$\\num{{{bin_low}}}$'
label = f'${sc_notation}\\leqslant\\Delta {criteria_str}<{bin_high:9.3f}$'
elif cat == 'Very High':
label = f'$\\Delta {criteria_str}\\geqslant{{{bins[-2]:9.3f}}}$'
label_cats.append(label)
return categories, bins, label_cats
# These are the defaults that I use with every figure to maintain layout coherence
sns.set_theme(style="whitegrid")
plt.style.use('./python.mplstyle')
palette = sns.color_palette("deep", n_colors=11)
sns.set_palette(palette, n_colors=11)
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": "serif",
"font.size": 9.0,
"font.serif": "Palatino",
"font.sans-serif": "DejaVu Sans",
"font.weight": "normal",
"pgf.preamble": "\n".join([ # plots will use this preamble
r"\usepackage[utf8]{inputenc}",
r"\usepackage[T1]{fontenc}",
r"\usepackage[detect-all,locale=UK]{siunitx}",
])
}
mpl.rcParams.update(pgf_with_latex)
fig, ax = plt.subplots(2, 3, constrained_layout=True)
df = pd.DataFrame({'diff': [0, 0.00001, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]})
categories, bins, label_cats = get_binarized_categories()
df = df.assign(slope=pd.cut(df['diff'], bins=bins, precision=6, labels=categories))
for id, (ax, category) in enumerate(zip(fig.axes, categories)):
up_str = f'{label_cats[id]}'
ax.text(.5, 1.01, up_str, horizontalalignment='center', transform=ax.transAxes, fontsize='small')
fig.savefig('test_latex.pdf', bbox_inches='tight')
However, upon running this code, I get the following errors:
This exact code runs perfectly fine when I do not try to use siunitx
(and consequently 'pgf'
). Any idea on how I might fix this?
The problem is unrelated to siunitx. The latex error messages reports the control sequence \leqslant
to be undefined, so you either need to replace it with something else or load a package which defines it, e.g.
\usepackage{MnSymbol}