custom matplotlib font in ipython notebook - python

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.

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.

Matplotlib xlabel in Arial with one word italicised

I want to create a matplotlib figure with an x-axis label that is in Arial font, and has one word italicised.
I can create figures with x-axis labels in latex-font with one word italicised; I can also create figures with x-axis labels in Arial, as long as I have either the entire label italicised or the entire label normal; but I can't get part of the xlabel in Arial italicised and the other part in arial normal.
I'm mostly trying permutations of the following code:
from matplotlib import pyplot as plt
import numpy as n
import matplotlib
from matplotlib.font_manager import FontProperties
font = {'family' : 'Arial',
'weight' : 'medium',
'size' : 20,
'style' : 'normal'}
font0 = {'family' : 'Arial',
'weight' : 'medium',
'size' : 20,
'style' : 'italic'}
matplotlib.rcParams['mathtext.fontset'] = 'custom'
matplotlib.rcParams['mathtext.rm'] = 'Arial'
matplotlib.rcParams['mathtext.it'] = 'Arial'
matplotlib.rc('font', **font)
#matplotlib.rc('font', **font0)
matplotlib.rc('text', usetex=False)
plt.figure(); plt.plot(n.linspace(0,3,10), n.linspace(0,3,10))
plt.xlabel(r'$\mathit{italics}$ - rest normal')
from matplotlib.pyplot import *
# Need to use precise font names in rcParams; I found my fonts with
#>>> import matplotlib.font_manager
#>>> [f.name for f in matplotlib.font_manager.fontManager.ttflist]
rcParams['mathtext.fontset'] = 'custom'
rcParams['mathtext.it'] = 'Arial:italic'
rcParams['mathtext.rm'] = 'Arial'
fig, ay = subplots()
# Using the specialized math font elsewhere, plus a different font
xlabel(r"$\mathit{Italic}$ $\mathrm{and\ just\ Arial}$ and not-math-font",fontsize=18)
# No math formatting, for comparison
ylabel(r'Italic and just Arial and not-math-font', fontsize=18)
grid()
show()

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