Matplotlib在使用Latex时如何支持中文

Posted by Zhenyu Lu on Tuesday, May 17, 2022

Matplotlib的内置文本对中文的支持,可以通过设置合适的字体来实现,相关内容通过网上搜索就有。但是,在使用Latex进行文本排版时如何支持中文,目前网上能够找到的信息并不多,并且按照他们的做法,并不能很好地实现中文文本。那么为什么要使用Latex排版文本呢?当时是为了利用Latex的灵活性,比如一行文字中可以对其中各别文字添加下划线或者设置不同字体,这通过内置的文本是无法实现的。当然,有一些第三方库支持这个功能,有兴趣的可以查看highlight-text,但是这个库不支持下划线。

通过一翻摸索,目前找到两条途径可以实现在使用Latex过程中支持中文,现在介绍如下:

  1. 前提条件

    1. 需要有相关的LaTex程序,例如Windows上的MikTex。我只使用Windows,至于其他系统,大家网上搜索一下应该也会有相关程序的安装教程。
    2. 需要有相关的LaTex宏包,例如实现中文的CJK宏包
  2. 第一种方法:CJK + PDFLaTex

    import matplotlib.pyplot as plt
    config = {
       ...: 'text.usetex': True,
       ...: 'text.latex.preamble': r'\usepackage{CJK}',  # 预先导入CJK宏包处理中文
    }
    plt.rcParams.update(config)
    
    fig, ax = plt.subplots()
    
    ax.text(0.2, 0.2, r'\begin{CJK}{UTF8}{song}\underline{你}好\end{CJK}')	# 宋体
    ax.annotate(r'\begin{CJK}{UTF8}{kai}你\underline{好}!\end{CJK}', 	# 楷体
                xy=(0.4, 0.4), xytext=(20, 40), 
                arrowprops=dict(arrowstyle='->'), textcoords='offset points')
    ax.text(0.5, 0.5, r'\begin{CJK}{UTF8}{hei}太阳\end{CJK}')	# 黑体
    
    plt.show()
    

    在上面的代码中,首先需要预先加载LaTex宏包CJK,这一步是关键之一。在具体使用过程中,中文文本必须包含在\begin{CJK}{UTF8}{song}\end{CJK}之间,这是使用的关键之二。当然,使用CJK所能使用的中文字体有限,但是只要有黑体宋体基本上也够用了。

    绘制的图如下:

    图1

  3. 第二种方法:PGF + XeLaTex

    在第一种方法中,使用的是默认的PDFLatex,其好处就是支持交互式绘图。但是PDFLaTex对于中文的支持实在有限,这也是为什么第一种方法用起来比较复杂。根据Matplotlib官网介绍,使用XeLaTex能够更好地支持中文,但是要想调用XeLaTex,那么绘图后端得改成pgf。具体实现如下:

    import matplotlib as mpl
    mpl.use('pgf')	# 修改绘图后端
    
    import matplotlib.pyplot as plt
    fig, ax = plt.subplots()
    
    ax.text(0.2, 0.2, r'\underline{你}好', fontfamily='SimHei')
    ax.annotate(r'你\underline{好}!', xy=(0.4, 0.4), xytext=(20, 40),
                arrowprops=dict(arrowstyle='->'), textcoords='offset points',
               fontfamily='SimHei')
    ax.set_ylabel(r'y\underline{轴}', fontfamily='SimHei')
    
    fig.savefig('text.png', dpi=300)
    

    可以看到,这种方法使用起来相对比较简单,而且字体可以选择任何支持中文的支持。但是有一个缺点就是pgf不支持交互式绘图,也即你无法通过GUI界面或者Jupyter Notebook来交互式画图,只能通过保存的方式绘制。

    当然,在实际操作中,你可以先用内置文本交互式绘制,当图形元素、文字排版都满足要求时,你再可以切换成pgf后端,并使用LaTex语法对文本的个别元素进行定制美化,然后保存输出图片。

    绘制的图形如下:

    图2

以上就是Matplotlib使用LaTex进行文本渲染时保证中文正常显示的两种方法。大家可以尝试一下,有任何问题或任何改进欢迎交流。

「真诚赞赏,手留余香」

水鸿的博客

真诚赞赏,手留余香

使用微信扫描二维码完成支付