当使用usetex=True时,使坐标轴刻度标签加粗。

25
我想在我的坐标轴上使用粗体标签,这样我就可以将图表用于出版物。我还需要将图例中的线条标签绘制为粗体。 到目前为止,我可以设置坐标轴标签和图例的大小和粗细。我还可以将坐标轴标签的大小设置为我想要的大小,但是我在粗细方面遇到了问题。
以下是一个示例代码:
# 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()

这就是我得到的东西:

plot example

有没有任何想法,我在哪里出错了或者做错了什么,以至于无法将轴刻度标签加粗?
编辑:
我已经根据Tom的回答更新了我的代码。然而,我现在又遇到了另一个问题,因为我需要在x轴上使用datetime,这与普通的y轴不同(抱歉我在原问题中没有提到这一点,但我没有想到这会改变事情)。
# 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()

现在我的结果看起来是这样的:

updated figure

似乎这些变化并不影响x轴刻度标签的显示或者说权重。
6个回答

22

使用

plt.xticks(x, weight = 'bold')

8
请勿仅以代码作为回答,还需解释您的代码是如何解决问题的并且它的工作原理。带有解释的答案通常更有帮助、质量更高,也更有可能获得赞同。 - Mark Rotteveel
2
这是不言自明的。你想要什么样的解释? - Mr. Panda
问题是如何在使用plt.rc('text', usetex=True)时使xticklabels和yticklabels加粗,而这种方法并不能实现。 - undefined

19

我认为问题出在刻度是在LaTeX数学模式下制作的,因此字体属性不适用。

您可以通过在LaTeX导言区添加正确的命令来解决此问题,使用rcParams。具体而言,您需要使用 \boldmath 来获取正确的粗细,以及 \usepackage{sfmath} 来获取无衬线字体。

另外,您可以使用set_tick_params设置刻度标签的字体大小。enter image description here

这里是一些实现您想要的功能的代码:

import numpy as np
from matplotlib import rc,rcParams
from pylab import *

tmpData = np.random.random( 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)

legend()

谢谢Tom,这有所帮助,至少一点点。然而,由于我需要在X轴上使用日期,它们的显示方式与Y轴不同。请参见我的更新/编辑问题。 - red_tiger
1
我已经找到了解决方案。我需要做的是将传入DateFormatter的字符串格式化为以下形式:ax.xaxis.set_major_formatter(dates.DateFormatter(r'\textbf{%m/%Y}')) - red_tiger
1
@red_tiger:我认为你应该接受答案。日期格式是你一开始并没有询问的内容。 - George
@George 你是对的。答案很棒,而且我无论如何都找到了其余部分。 - red_tiger

9
labels = axes.get_xticklabels() + axes.get_yticklabels()
    [label.set_fontweight('bold') for label in labels]

8
仅使用列表解析来循环会使代码变得混乱。使用for label in labels: label.set_fontweight('bold')可以使代码更清晰明了。 - joanis
问题是如何在使用plt.rc('text', usetex=True)时使xticklabelsyticklabels加粗,而这种方法并不能实现。 - undefined

0
给定原始问题在OP中,其中x和y轴刻度和标签是数字。 [fr'\textbf{{{v}}}' for v in ax.get_xticks()] 使用3组{},因为还使用了f-string。
  • 如果只使用{}fr'\textbf{v}',只有第一个字符会加粗。
以下代码使用显式的Axes接口。如果使用隐式的pyplot接口,则在绘图调用之后使用ax = plt.gca()获取Axespython 3.12.0matplotlib 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)

enter image description here


-1
如果您想要自动将轴标签加粗(即无需每次添加\textbf),可以执行以下操作:
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()

这是利用了Axis.set_xlabelAxis.set_ylabel方法是属性(在这种情况下是函数对象),可以被用户修改的事实。修改是在add_bold中完成的,它只是调用原始函数对象,但使用修改后的参数。 orig_funcadd_boldget_new_func内部定义,以正确保留对原始方法的引用(即我正在形成闭包)。


问题是如何在使用plt.rc('text', usetex=True)时使xticklabels和yticklabels加粗,但这并不能实现。 - undefined

-1

这是另一个例子给你

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)

输出结果将会是这样的:

example plot


1
你误解了问题。问题是在使用plt.rc('text', usetex=True)时如何使xticklabels加粗,而不是如何画粗的图线。这并没有回答问题。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接