7

I'm trying to make some publication-quality plots, but I have encountered a small problem. It seems by default that matplotlib axis labels and legend entries are weighted heavier than the axis tick marks. Is there anyway to force the axis labels/legend entries to be the same weight as the tick marks?

import matplotlib.pyplot as plt
import numpy as np

plt.rc('text',usetex=True)
font = {'family':'serif','size':16}
plt.rc('font',**font)
plt.rc('legend',**{'fontsize':14})

x = np.linspace(0,2*np.pi,100)
y = np.sin(x)

fig = plt.figure(figsize=(5,5))
p1, = plt.plot(x,y)
p2, = plt.plot(x,x**2)
plt.xlabel('x-Axis')
plt.ylabel('y-Axis')
plt.legend([p1,p2],['Sin(x)','x$^2$'])
plt.gcf().subplots_adjust(left=0.2)
plt.gcf().subplots_adjust(bottom=0.15)
plt.savefig('Test.eps',bbox_inches='tight',format='eps')
plt.show()

I can use math-mode, but the problem (annoyance) is when I have a sentence for a label, i.e.,

plt.xlabel('$\mathrm{This is the x-axis}$') 

which squishes it all together. I can fix it by using

plt.xlabel('$\mathrm{This\: is\: the\: x-axis}$')

but that needs a lot of punctuation. I was hoping there was something that I could change that would allow me to bypass the \mathrm{} format, and use standard TeX format.

The other option I tried, was using \text instead of \mathrm, but it seems that Python's interpreter doesn't recognize this without loading the package amsmath. I have also tried:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

plt.rc('text',usetex=True)
font = {'family':'serif','size':16}
plt.rc('font',**font)
plt.rc('legend',**{'fontsize':14})
matplotlib.rcParams['text.latex.preamble']=[r'\usepackage{amsmath}']

x = np.linspace(0,2*np.pi,100)
y = np.sin(x)

fig = plt.figure(figsize=(5,5))
p1, = plt.plot(x,y)
p2, = plt.plot(x,x**2)
plt.xlabel(r'$\text{this is the x-Axis}$')
plt.ylabel('$y-Axis$')
plt.legend([p1,p2],['Sin(x)','x$^2$'])
plt.gcf().subplots_adjust(left=0.2)
plt.gcf().subplots_adjust(bottom=0.15)
plt.savefig('Test.eps',bbox_inches='tight',format='eps')
plt.show()

This doesn't return the desired result either.

0

2 Answers 2

6

The other answer provides a work-around to the problem... However, the problem is very specific to matplotlib and the implementation of the LateX backend.

First of all, the rc parameter controlling the font weight of the axis labels is 'axes.labelweight', which by default is set to u'normal'. This means that the labels should already be in regular weight.

The reason why the font appears to be bold can be found in matplotlib/texmanager.py:

  1. The font family is chosen by 'font.family', in the case of the OP, this is serif.

  2. Then, the array 'font.<font.family>' (here: font.serif) is evaluated, and the declaration of all fonts is added to the LateX preamble. Among those declarations is the line

    \renewcommand{\rmdefault}{pnc}
    

    which sets the default to New Century School Book which appears to be a bold version of Computer Modern Roman.

In conclusion, the shortest way to solve the problem is to set font.serif to contain only Computer Modern Roman:

font = {'family':'serif','size':16, 'serif': ['computer modern roman']}

This has the additional benefit that it works for all elements, even for labels and other captions - without dirty tricks using the math mode: enter image description here


Here is the complete code to generate the plot:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

plt.rc('text',usetex=True)
#font = {'family':'serif','size':16}
font = {'family':'serif','size':16, 'serif': ['computer modern roman']}
plt.rc('font',**font)
plt.rc('legend',**{'fontsize':14})
matplotlib.rcParams['text.latex.preamble']=[r'\usepackage{amsmath}']

x = np.linspace(0,2*np.pi,100)
y = np.sin(x)

fig = plt.figure(figsize=(5,5))
p1, = plt.plot(x,y)
p2, = plt.plot(x,x**2)
plt.xlabel(r'$\text{this is the x-Axis}$')
plt.ylabel('$y-Axis$')
plt.legend([p1,p2],['Sin(x)','x$^2$'])
plt.gcf().subplots_adjust(left=0.2)
plt.gcf().subplots_adjust(bottom=0.15)
plt.savefig('Test.eps',bbox_inches='tight',format='eps')
plt.show()
Sign up to request clarification or add additional context in comments.

3 Comments

Can you post the code you used for the plot? If I understand you correctly, all labels (axis and legend) were typed similarly to ('label entry') and the only math mode entry was the y-label ('$y-axis$'). If that's the case, then this is a great solution!
The plot was generated exactly from your code, only the highlighted line was changed!
I came across this answer while attempting to get LaTeX fonts in matplotlib. It turned out that I had to replace 'computer modern roman' with 'cmr10' which appears to have had the correct effect.
5

How about:

enter image description here

import matplotlib.pyplot as plt
import numpy as np

plt.rc('text',usetex=True)
font = {'family':'serif','size':16}
plt.rc('font',**font)
plt.rc('legend',**{'fontsize':14})

x = np.linspace(0,2*np.pi,100)
y = np.sin(x)

fig = plt.figure(figsize=(5,5))
p1, = plt.plot(x,y)
p2, = plt.plot(x,x**2)
plt.xlabel('$\mathrm{This is the }x\mathrm{-axis}$'.replace(' ','\: '))
plt.ylabel('$y\mathrm{-axis}$')
plt.legend([p1,p2],['$\sin(x)$','$x^2$'], loc='best')
fig.subplots_adjust(left=0.2, bottom=0.15)
plt.savefig('Test.eps',bbox_inches='tight',format='eps')
plt.show()

This uses

plt.xlabel('$\mathrm{This is the }x\mathrm{-axis}$'.replace(' ','\: '))

to replace spaces with '\: '. TeX gurus may object to this however. You may want to ask on TeX stackexchange if there is a better way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.