Reputation: 1492
I want to have bold labels on my axis, so I can use the plot for publication. I also need to have the label of the lines in the legend plotted in bold. So far I can set the axis labels and the legend to the size and weight I want. I can also set the size of the axis labels to the size I want, however I am failing with the weight.
Here is an example code:
# plotting libs
from pylab import *
from matplotlib import rc
if __name__=='__main__':
tmpData = np.random.random( 100 )
# activate latex text rendering
rc('text', usetex=True)
rc('axes', linewidth=2)
rc('font', weight='bold')
#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)
fontsize = 20
fontweight = 'bold'
fontproperties = {'family':'sans-serif','sans-serif':['Helvetica'],'weight' : fontweight, 'size' : fontsize}
ax.set_xticklabels(ax.get_xticks(), fontproperties)
ax.set_yticklabels(ax.get_yticks(), fontproperties)
for tick in ax.xaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
for tick in ax.yaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
legend()
show()
sys.exit()
And this is what I get:
Any idea what I am missing or doing wrong in order to get the axis ticks label in bold?
EDIT
I have updated my code using toms response. However I now have another problem, as I need to use datetime
on the x-axis, this has not the same effect as on the normal y-axis (sorry for not putting this in in the original question, but I did not think it would change things):
# plotting libs
from pylab import *
from matplotlib import rc, rcParams
import matplotlib.dates as dates
# datetime
import datetime
if __name__=='__main__':
tmpData = np.random.random( 100 )
base = datetime.datetime(2000, 1, 1)
arr = np.array([base + datetime.timedelta(days=i) for i in xrange(100)])
# activate latex text rendering
rc('text', usetex=True)
rc('axes', linewidth=2)
rc('font', weight='bold')
rcParams['text.latex.preamble'] = [r'\usepackage{sfmath} \boldmath']
#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)
ax.xaxis.set_major_formatter(dates.DateFormatter('%m/%Y'))
ax.xaxis.set_major_locator(dates.MonthLocator(interval=1))
legend()
Now my result looks like this:
It seems to be that the changes doe not affect the display or rather the weight of the x-axis ticks labels.
Upvotes: 30
Views: 117429
Reputation: 69136
I think the problem is because the ticks are made in LaTeX math-mode, so the font properties don't apply.
You can get around this by adding the correct commands to the LaTeX preamble, using rcParams
. Specifcally, you need to use \boldmath
to get the correct weight, and \usepackage{sfmath}
to get sans-serif font.
Also, you can use set_tick_params
to set the font size of the tick labels.
Tested in python 3.12.0
, matplotlib 3.8.0
xticklabels
import matplotlib.pyplot as plt
import numpy as np
tmpData = np.random.random( 100 )
# activate latex text rendering
plt.rc('text', usetex=True)
plt.rc('axes', linewidth=2)
plt.rc('font', weight='bold')
plt.rcParams['text.latex.preamble'] = r'\usepackage{sfmath} \boldmath'
#create figure
f = plt.figure(figsize=(10,10))
ax = plt.gca()
plt.plot(np.arange(100), tmpData, label=r'\textbf{Line 1}', linewidth=2)
plt.ylabel(r'\textbf{Y-AXIS}', fontsize=20)
plt.xlabel(r'\textbf{X-AXIS}', fontsize=20)
ax.xaxis.set_tick_params(labelsize=20)
ax.yaxis.set_tick_params(labelsize=20)
plt.legend()
xticklabels
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime, timedelta
tmpData = np.random.random(100)
base = datetime(2000, 1, 1)
arr = np.array([base + timedelta(days=i) for i in range(100)])
# activate latex text rendering
plt.rc('text', usetex=True)
plt.rc('axes', linewidth=2)
plt.rc('font', weight='bold')
plt.rcParams['text.latex.preamble'] = r'\usepackage{sfmath} \boldmath'
# create figure
f = plt.figure(figsize=(10, 10))
ax = plt.gca()
plt.plot(arr, tmpData, label=r'\textbf{Line 1}', linewidth=2)
plt.ylabel(r'\textbf{Y-AXIS}', fontsize=20)
plt.xlabel(r'\textbf{X-AXIS}', fontsize=20)
ax.xaxis.set_tick_params(labelsize=20)
ax.yaxis.set_tick_params(labelsize=20)
# Set x-axis major formatter and locator
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%Y'))
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
plt.legend()
Upvotes: 23
Reputation: 62413
[fr'\textbf{{{v}}}' for v in ax.get_xticks()]
uses 3 sets of {}
because an f-string is also being used.
{}
is used, fr'\textbf{v}'
, only the first character will be bold.Axes
interface. If the implicit pyplot
interface is used, then get the Axes
with ax = plt.gca()
after the plot call.python 3.12.0
,matplotlib 3.8.0
import matplotlib.pyplot as plt
import numpy as np
data = np.random.random(100)
# activate latex text rendering
plt.rc('text', usetex=True)
plt.rc('axes', linewidth=2)
plt.rc('font', weight='bold')
# create figure and Axes
fig, ax = plt.subplots(figsize=(10, 10))
ax.plot(np.arange(100), data, label=r'\textbf{Line 1}', linewidth=2)
# Set the axis labels to bold and increase the fontsize
ax.set_ylabel(r'\textbf{Y-AXIS}', fontsize=20)
ax.set_xlabel(r'\textbf{X-AXIS}', fontsize=20)
# change the tick labels to bold
ax.set_xticks(ax.get_xticks(), [fr'\textbf{{{v}}}' for v in ax.get_xticks()], fontsize=20)
_ = ax.set_yticks(ax.get_yticks(), [fr'\textbf{{{round(v, 1)}}}' for v in ax.get_yticks()], fontsize=20)
Upvotes: 0
Reputation: 85
this is another example for you
import matplotlib.pyplot as plt
places = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
literacy_rate = [100, 98, 90, 85, 75, 50, 30, 45, 65, 70]
female_literacy = [95, 100, 50, 60, 85, 80, 75, 99, 70, 30]
plt.xlabel("Places")
plt.ylabel("Percentage")
plt.plot(places, literacy_rate, color='blue',
linewidth=6, label="Literacy rate")
plt.plot(places, female_literacy, color='fuchsia',
linewidth=4, label="Female Literacy rate")
plt.legend(loc='lower left', ncol=1)
and the youtput will be like this:
Upvotes: -1
Reputation: 1
If you want to make the axis labels bold automatically (i.e. without having to add \textbf every time), you could do the following
from matplotlib.axes import Axes
from matplotlib import pyplot as plt
plt.rcParams['text.usetex'] = True
def get_new_func(axis_name): # returns a modified version of the Axes.set_xlabel (or y) methods
orig_func = getattr(Axes, f'set_{axis_name}label')
def add_bold(self, *args, **kwargs):
new_args = list(args)
new_args[0] = fr"\textbf{{{new_args[0]}}}" # modify the argument
return orig_func(self, *new_args, **kwargs)
return add_bold
for x in ['x', 'y']:
setattr(Axes, f'set_{x}label', get_new_func(x)) # modify the methods of the Axis class
x = np.linspace(0, 2 * 3.14, 20)
y = np.sin(x)
ax = plt.gca()
ax.plot(x, y)
ax.set_xlabel("Theta")
ax.set_ylabel("Amp")
plt.show()
This makes use of the fact that the Axis.set_xlabel
and Axis.set_ylabel
methods are attributes (in this case function objects) that can be modified by the user. The modification is done in add_bold
, which simply calls the original function object but with a modified argument. orig_func
and add_bold
are defined inside of get_new_func
in order to correctly preserve the reference to the original method (i.e. i'm forming a closure).
Upvotes: -1
Reputation: 89
labels = axes.get_xticklabels() + axes.get_yticklabels()
[label.set_fontweight('bold') for label in labels]
Upvotes: 8