Matplotlib的内置文本对中文的支持,可以通过设置合适的字体来实现,相关内容通过网上搜索就有。但是,在使用Latex进行文本排版时如何支持中文,目前网上能够找到的信息并不多,并且按照他们的做法,并不能很好地实现中文文本。那么为什么要使用Latex排版文本呢?当时是为了利用Latex的灵活性,比如一行文字中可以对其中各别文字添加下划线或者设置不同字体,这通过内置的文本是无法实现的。当然,有一些第三方库支持这个功能,有兴趣的可以查看highlight-text,但是这个库不支持下划线。
通过一翻摸索,目前找到两条途径可以实现在使用Latex过程中支持中文,现在介绍如下:
-
前提条件
- 需要有相关的LaTex程序,例如Windows上的MikTex。我只使用Windows,至于其他系统,大家网上搜索一下应该也会有相关程序的安装教程。
- 需要有相关的LaTex宏包,例如实现中文的CJK宏包
-
第一种方法: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
所能使用的中文字体有限,但是只要有黑体和宋体基本上也够用了。绘制的图如下:
-
第二种方法: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
语法对文本的个别元素进行定制美化,然后保存输出图片。绘制的图形如下:
以上就是Matplotlib使用LaTex进行文本渲染时保证中文正常显示的两种方法。大家可以尝试一下,有任何问题或任何改进欢迎交流。
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付
