Python Matplotlib 画图示例
前言
在写论文的时候,画图有如下一些要求:
字体一致、字体大小一致、数据点与拟合曲线的颜色、保存图片的分辨率……
这里初步总结出一个常用的模板
初始设定
首先导入库,设定图框大小和字体格式:
import matplotlib.pyplot as plt
import numpy as np
rc_fonts_common = {
'figure.figsize': (7, 5),
'font.family': 'Times New Roman',
'font.size': 20,
'text.latex.preamble': r'''
\usepackage{libertine}
\usepackage[libertine]{newtxmath}
'''
}
plt.rcParams.update(rc_fonts_common)
其中,text.latex.preamble
一项,是 Latex 相关的字体设定。需要安装 Latex 之后才能起作用
其他三个分别是:图框大小,字体格式,字体大小。
plt.rcParams
相当于一个 dict,里面是画图的各种参数设定。
在这里设定好就不需要再在后面一个一个的设定了。
数据
以平方反比数据为例:
x = np.arange(1, 10, 0.5)
y = 10/x**2 + np.random.random((len(x)))*0.2 - 0.1
z = (x**2*y).mean()
x_fit = np.arange(0.9, 11, 0.1)
y_fit = z/x_fit**2
画图
# 单个图表
# plt.scatter(x, y, color='black', label='Data')
plt.errorbar(x, y, yerr=np.ones(shape=len(x))*0.2, fmt="o", label='460nm data', color='black', ecolor='blue', elinewidth=2, capsize=4)
plt.plot(x_fit, y_fit, color='red', label=r'$1/r^2$ fitting')
plt.xlabel('Time [ms]')
plt.ylabel('Radius [cm]')
plt.text(3, 7, r'Use nothing: $ABC+\frac{\pi}{r^2}+\alpha_1^2$')
plt.text(3, 5, r'Use mathregular: $\mathregular{ABC+\frac{\pi}{r^2}+\alpha_1^2}$')
plt.text(3, 3, r'Use tex: $ABC+\frac{\pi}{r^2}+\alpha_1^2$', usetex=True)
plt.rcParams.update({'text.usetex':True})
plt.legend()
plt.rcParams.update({'text.usetex':False})
# plt.savefig('sample_simplest.png', dpi=1000, bbox_inches='tight')
plt.show()
图片效果展示:
值得注意的是:
- 一般不使用中文,所以这里不介绍中文乱码的处理
- 一般不使用标题,如有需要可以使用
plt.title('Some title')
- 坐标轴的单位用中括号括起来;首个字母大写
- 图片中的文字,字体格式和大小要尽量与正文的字体一致
- 使用 Latex 公式的方式是用
$
括起来,如:r'$x_1^2$'
-> x 1 2 x_1^2 x12。但是 Latex 公式的默认字体很丑 - 改进 Latex 公式的第一种方式是用
\mathregular
,具体用法如:r'$\mathregular{x_1^2}$'
。
大多数情况下都可以这样做,很方便,而且这样不需要安装 Latex。 - 另外一种改善 Latex 的字体显示的方式就是
usetex=True
,需要安装 Latex 才能用,不然会报错。
安装 Latex,如 Windows 上推荐 TeX Live
之后最直接的使用方式是:plt.rcParams.update({'text.usetex':True})
,让全局的字体都使用 Latex。但是这个不太推荐,这一项建议一般设置为 False 。
下面具体介绍两种不同情况下的 Latex 使用:- 坐标轴、直接添加文字的时候,直接在函数里面加上
usetex=True
即可。如:plt.title(r'test: $x_1^2$', usetex=True)
- 给曲线添加 label 的时候,传入
usetex=True
会报错。我研究很久之后意识到,label 的添加实际上发生在 legend 的时候,也就是说,需要在 legend 里面添加。但是那样还是会报错,于是最后就有了终极的解决办法:在 legend 函数前后套上 uestex 的设定:
精准打击(虽然也没那么精准plt.rcParams.update({'text.usetex':True}) plt.legend() plt.rcParams.update({'text.usetex':False})
- 坐标轴、直接添加文字的时候,直接在函数里面加上
- 保存图片,一方面是使用
dpi=1000
来提高分辨率,一般情况下 500 就已经很清晰了,但是论文要求 dpi 不低于 800;
另一方面,使用bbox_inches='tight'
来消除白边。
另外,推荐在 jupyter notebook 里面画图,尤其是 VS Code ~
附
最后按惯例,附上整体代码:
import matplotlib.pyplot as plt
import numpy as np
rc_fonts_common = {
'figure.figsize': (7, 5),
'font.family': 'Times New Roman',
'font.size': 20,
'text.latex.preamble': r'''
\usepackage{libertine}
\usepackage[libertine]{newtxmath}
'''
}
plt.rcParams.update(rc_fonts_common)
# 数据准备
x = np.arange(1, 10, 0.5)
y = 10/x**2 + np.random.random((len(x)))*0.2 - 0.1
z = (x**2*y).mean()
x_fit = np.arange(0.9, 11, 0.1)
y_fit = z/x_fit**2
# 单个图表
# plt.scatter(x, y, color='black', label='Data')
plt.errorbar(x, y, yerr=np.ones(shape=len(x))*0.2, fmt="o", label='Data', color='black', ecolor='blue', elinewidth=2, capsize=4)
plt.plot(x_fit, y_fit, color='red', label=r'$1/r^2$ fitting')
plt.xlabel('Time [ms]')
plt.ylabel('Radius [cm]')
plt.text(3, 7, r'Use nothing: $ABC+\frac{\pi}{r^2}+\alpha_1^2$')
plt.text(3, 5, r'Use mathregular: $\mathregular{ABC+\frac{\pi}{r^2}+\alpha_1^2}$')
plt.text(3, 3, r'Use tex: $ABC+\frac{\pi}{r^2}+\alpha_1^2$', usetex=True)
plt.rcParams.update({'text.usetex':True})
plt.legend()
plt.rcParams.update({'text.usetex':False})
plt.savefig('sample_simplest.png', dpi=1000, bbox_inches='tight')
plt.show()
之后或许可以更新一些别的画图
有问题欢迎提出 ~