Matplotlib font common font with LaTeX - python

I can't seem to set the same font for both regular text and mathematical numbers
I am trying to set a font using Matplotlib for a draft article, and the font I need to use is Libertine. Ideally I would just let LaTeX do all the formatting, but it seems set on formatting the maths font with computer modern:
import matplotlib as mpl
rc_fonts = {
"font.family": "serif",
"font.size": 20,
'figure.figsize': (5, 3),
"text.usetex": True,
'text.latex.preview': True,
'text.latex.preamble': [
r"""
\usepackage[libertine]{newtxmath}
\usepackage{libertine}
"""],
}
mpl.rcParams.update(rc_fonts)
import matplotlib.pylab as plt
with the trivial plot
plt.ion()
plt.clf()
plt.plot(range(10))
plt.title("something 0,2,4,6,8 $e=mc^2$")
produces (compare the "2"s)
If instead I use
rc_fonts = {
"font.family": "serif",
'font.serif': 'Linux Libertine O',
"font.size": 20,
'figure.figsize': (5, 3),
}
then the numbers now match but the maths is not using LaTeX (unsurprisingly):
To get the libertine fonts I downloaded them from https://ctan.org/tex-archive/install/fonts and installed them using the description from https://dallascard.github.io/changing-the-font-in-matplotlib.html (http://andresabino.com/2015/08/18/fonts-and-matplotlib/ seems related). The following questions seem to touch upon the issue, but I can't get a solution to work from them yet:
Matplotlib, Consistent font using latex
how to set up a custom font with custom path to matplotlib global font?
Unable to use custom fonts in matplotlib

Based on the comment pointed out by #gboffi, it seems this is not an issue with Matplotlib at all, but can be replicated by LaTeX using the preamble. Switching the order of the packages, which is the order as seen in answers to this question: https://tex.stackexchange.com/questions/544474/libertine-and-math-numbers then the issue is resolved:
rc_fonts = {
"font.family": "serif",
"font.size": 20,
'figure.figsize': (5, 3),
"text.usetex": True,
'text.latex.preview': True,
'text.latex.preamble': [
r"""
\usepackage{libertine}
\usepackage[libertine]{newtxmath}
"""],
}
gives

Related

How can I get xticklabel and yticklabel bold when activating LaTeX text rendering with Times New Roman font in Python matplotlib?

I am trying to generate a figure with LaTeX text rendering activated. I want to use Time New Roman font for all the texts in the figure (including the mathematical texts) and I encounter some problems when trying to make the xticklabel and yticklable bold, here is what I have:
import numpy as np
from matplotlib import rc,rcParams
from pylab import *
tmpData = np.random.random( 100 )
rcParams.update({
"text.usetex": True,
"font.family": "serif",
"font.serif": ["Times"],
'font.weight': 'bold'})
rcParams['text.latex.preamble'] = [r'\usepackage{fontspec} \usepackage{newtxtext,newtxmath}']
#create figure
f = figure(figsize=(10,10))
ax = gca()
plot(np.arange(100), tmpData, label=r'\textbf{Line 1}', linewidth=2)
ylabel(r'\textbf{Y-AXIS}', fontsize=20)
xlabel(r'\textbf{X-AXIS}', fontsize=20)
ax.xaxis.set_tick_params(labelsize=20)
ax.yaxis.set_tick_params(labelsize=20)
legend()
I understand that the problem may due to the fact that the xticklabels on the x axis should really be interpreted as mathematical texts, but I am still struggling with this...
Can anyone help me with this? Thanks in advance!
Add this code above legend()
ylabs = [ f"{ilab:<.1f}" for ilab in ax.get_yticks()]
xlabs = [ f"{ilab:<.0f}" for ilab in ax.get_xticks()]
ax.set_yticklabels(ylabs, weight='bold', size=20)
ax.set_xticklabels(xlabs, weight='bold', size=20)
output is here.

How to change font in $$ which is in math form in python

When I tried to polt a figure with matplotlib, I wrote the x axis label with both text and "math text". Because I have to write a chemical formula in the label, it was written as '$CO_2$ concentration'. The question is that I hope the font should be times new roman, but I cannot change the font in the dollar sign somehow. Is there anyone who can help me fix it? Thank you very much!
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
xf1 = pd.read_excel('1812_GPT.xlsx',sheetname= 'PVD_CO2CH4_600',usecols=[1])
deltapx1 = pd.read_excel('1812_GPT.xlsx',sheetname= 'PVD_CO2CH4_600',usecols=[3])
Px1 = pd.read_excel('1812_GPT.xlsx',sheetname= 'PVD_CO2CH4_600',usecols=[5])
ax1 = plt.subplot(111)
l1, = ax1.plot(xf1,Px1,'s',markerfacecolor='black')
font1 = {'family' : 'Times New Roman',
'weight' : 'normal',
'size' : 14,
}
ax1.set_xlabel(r'$CO_2$ pressure', font1)
ax1.set_ylabel(r'$CO_2$ concentration', font1)
plt.show()
This is the picture link, you may see the pic and find that "CO2" is not in Times new roman.
https://flic.kr/p/2dmh8pj
I don't think it's easily possible to change any mathtext to an arbitrary font. However, in case of "CO_2" that consists only of regular symbols, you may use \mathdefault{} to make the mathtext use the symbols from the regular font.
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = "serif"
plt.rcParams["font.serif"] = ["Times New Roman"] + plt.rcParams["font.serif"]
fig, ax = plt.subplots()
ax.set_xlabel(r'$\mathdefault{CO_2}$ pressure')
ax.set_ylabel(r'$\mathdefault{CO_2}$ concentration')
plt.show()
Something like r"$\mathdefault{\sum_\alpha^\beta\frac{i}{9}}$ would still be rendered in the usual default math fontset (except the "i" and the 9, which are of course present in Times New Roman).
For the general case, you may also change the complete math fontset to any of the available, cm, stix, stixsans, dejavuserif, dejavusans. The closest to "Times New Roman" would be stix.
import matplotlib.pyplot as plt
rc = {"font.family" : "serif",
"mathtext.fontset" : "stix"}
plt.rcParams.update(rc)
plt.rcParams["font.serif"] = ["Times New Roman"] + plt.rcParams["font.serif"]
fig, ax = plt.subplots()
ax.set_xlabel(r'$CO_2$ pressure')
ax.set_ylabel(r'$CO_2$ concentration')
plt.show()
A general recommendation for reading would be the MathText tutorial.
I find it better to define the whole font family at once, rather than independently (assuming you want the same font). Give this a try
plt.rc('text', usetex=True )
plt.rc('font', family='Times New Roman', weight='normal', size=14)
plt.rcParams['mathtext.fontset'] = 'Times New Roman'
ax1.set_xlabel('$CO_2$ pressure')
ax1.set_ylabel('$CO_2$ concentration')

Failed to change matplotlib default font [duplicate]

I have been trying to use matplotlib's text or annotate modules with mandarin Chinese characters. Somehow it ends up showing boxes. Any idea on this ?
Here is a solution that works for me on Python 2.7 and Python 3.3, using both text and annotate methods with Chinese.
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
fig = plt.figure()
ax = fig.add_subplot(111)
ChineseFont1 = FontProperties(fname = 'C:\\Windows\\Fonts\\simsun.ttc')
ChineseFont2 = FontProperties('SimHei')
ax.text(3, 2, u'我中文是写得到的', fontproperties = ChineseFont1)
ax.text(5, 1, u'我中文是写得到的', fontproperties = ChineseFont2)
ax.annotate(u'我中文是写得到的', xy=(2, 1), xytext=(3, 4),
arrowprops=dict(facecolor='black', shrink=0.05),
fontproperties = ChineseFont1)
ax.axis([0, 10, 0, 10])
plt.show()
ChineseFont1 is hard coded to a font file, while ChineseFont2 grabs a font by family name (but for ChineseFont2 I had to try a couple to find one that would work). Both of those are particular to my system, in that they reference fonts I have, so you quite likely will need to change them to reference fonts/paths on your system.
The font loaded by default doesn't seem to support Chinese characters, so it was primarily a font choice issue.
Another solution is to use pgf backend which uses XeTeX. This allows one to use UTF-8 directly:
#!/usr/bin/env python2
# -*- coding:utf-8 -*-
import matplotlib
matplotlib.use("pgf")
pgf_with_custom_preamble = {
# "font.size": 18,
"pgf.rcfonts": False,
"text.usetex": True,
"pgf.preamble": [
# math setup:
r"\usepackage{unicode-math}",
# fonts setup:
r"\setmainfont{WenQuanYi Zen Hei}",
r"\setsansfont{WenQuanYi Zen Hei}",
r"\setmonofont{WenQuanYi Zen Hei Mono}",
],
}
matplotlib.rcParams.update(pgf_with_custom_preamble)
from matplotlib import pyplot as plt
x = range(5)
y = range(5)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, label=u"我")
ax.legend(u"中")
ax.set_xlabel(u"是")
ax.set_ylabel(u"写")
ax.set_title(u"得")
ax.text(3, 2, u'到')
ax.annotate(u'的', xy=(2, 1), xytext=(3, 1),
arrowprops=dict(arrowstyle="<|-", connectionstyle="arc3", color='k'))
fig.savefig("pgf-mwe.png")
Result:
This solution requires matplotlib 1.2+ and probably XeTeX installed on Your system. The easiest way to get a working XeTeX is to go for any modern LaTeX distribution: TeXLive (available for all platforms) or MiKTeX (windows only).
matplotlib.rc('font', family='Source Han Sans CN')
ax = quarterly_gdp.plot(title='国内生产总值')
example
You only have to setup font family of your matplotlib and after that you can plot with Chinese labels. I've set up font to be Source Han Sans CN, as it's the only available font on my computer for Chinese.
You can check the available font by command fc-list :lang=zh.

custom matplotlib font in ipython notebook

I use matplotlib in iPython notebooks and I'm hoping to change the font-family to Gotham-Book. I have Gotham-Book installed on my machine but unfortunately, matplotlib cannot seem to find the font and keeps defaulting to a serif font. Any thoughts on how to get gotham-book working?
Here is the code I'm using.
import matplotlib.pylab as plt
plt.rcParams['font.family']=['gothambook','gotham','gotham-book','serif']
mpl.pylab.plot(range(10), mpl.pylab.sin(range(10)))
mpl.pylab.xlabel("GOTHAM BOOK FONT", size=20)
I can see the font is on my machine here:
In [12]:
matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
Out[12]:
['/usr/share/fonts/dejavu/DejaVuLGCSansMono-Oblique.ttf',
'/usr/share/fonts/dejavu/DejaVuLGCSansMono.ttf',
'/usr/share/fonts/dejavu/DejaVuSansMono-BoldOblique.ttf',
'/usr/share/fonts/dejavu/DejaVuSans-ExtraLight.ttf',
'/usr/share/fonts/dejavu/DejaVuLGCSansMono-BoldOblique.ttf',
'/usr/share/fonts/dejavu/DejaVuSansCondensed-Oblique.ttf',
'/usr/share/fonts/dejavu/DejaVuSans.ttf',
'/usr/local/share/fonts/gothambook/Gotham-Book.ttf',
'/usr/share/fonts/dejavu/DejaVuSansCondensed.ttf',
'/usr/share/fonts/dejavu/DejaVuSansMono-Oblique.ttf',
'/usr/share/fonts/dejavu/DejaVuLGCSansMono-Bold.ttf',
'/usr/share/fonts/dejavu/DejaVuSans-BoldOblique.ttf',
'/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf',
'/usr/share/fonts/dejavu/DejaVuSansCondensed-BoldOblique.ttf',
'/usr/share/fonts/dejavu/DejaVuSansMono-Bold.ttf',
'/usr/share/fonts/dejavu/DejaVuSansCondensed-Bold.ttf',
'/usr/share/fonts/dejavu/DejaVuSans-Oblique.ttf',
'/usr/share/fonts/dejavu/DejaVuSansMono.ttf']
I believe because even you ADDED the font.family to the rcParams but you haven't USED it on the xlabel:
mpl.pylab.xlabel("GOTHAM BOOK FONT", size=20)
Change it to this, should work:
mpl.pylab.xlabel("GOTHAM BOOK FONT", family='gothambook', size=20)
You can use fontdict to change the font settings on the xlabel, something like this works on mine:
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['font.family']
Out[1]: [u'sans-serif']
plt.rcParams['font.family'].append(u'Comic Sans MS')
font = {
'family' : 'Comic Sans MS',
'color' : 'blue',
'weight' : 'normal',
'size' : 18,
}
plt.plot(range(10), matplotlib.pylab.sin(range(10)))
plt.xlabel('Comic Sans MS FONT', fontdict=font)
Results:
Alternatively you can set parameters on the fly with this:
plt.xlabel('Comic Sans MS FONT', family='Comic Sans MS', fontsize=18, color='blue')
which will have same results, you can read more about the parameters on Text Properties
Hope this helps.

How do I get 'matplotlib' to use my LaTeX sans font by default [duplicate]

The following script:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as mpl
mpl.rc('font', family='sans-serif')
mpl.rc('text', usetex=True)
fig = mpl.figure()
ax = fig.add_subplot(1,1,1)
ax.text(0.2,0.5,r"Math font: $451^\circ$")
ax.text(0.2,0.7,r"Normal font (except for degree symbol): 451$^\circ$")
fig.savefig('test.png')
is an attempt to use a sans-serif font in matplotlib with LaTeX. The issue is that the math font is still a serif font (as indicated by the axis numbers, and as demonstrated by the labels in the center). Is there a way to set the math font to also be sans-serif?
I always have text.usetex = True in my matplotlibrc file. In addition to that, I use this as well:
mpl.rcParams['text.latex.preamble'] = [
r'\usepackage{siunitx}', # i need upright \micro symbols, but you need...
r'\sisetup{detect-all}', # ...this to force siunitx to actually use your fonts
r'\usepackage{helvet}', # set the normal font here
r'\usepackage{sansmath}', # load up the sansmath so that math -> helvet
r'\sansmath' # <- tricky! -- gotta actually tell tex to use!
]
Hope that helps.
The easiest way is to use matplotlib's internal TeX, e.g.:
import pylab as plt
params = {'text.usetex': False, 'mathtext.fontset': 'stixsans'}
plt.rcParams.update(params)
If you use an external LaTeX, you can use, e.g., CM Bright fonts:
params = {'text.usetex': True,
'text.latex.preamble': [r'\usepackage{cmbright}', r'\usepackage{amsmath}']}
plt.rcParams.update(params)
Note, that the CM Bright font is non-scalable, and you'll not be able to save PDF/PS!
Same with other options with external LaTeX I've found so far.
This will enable you to use the Computer Modern Sans font if you, as I, prefer it over Helvetica:
mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.preamble'] = [r'\usepackage[cm]{sfmath}']
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = 'cm'

Categories