将matplotlib输出为PGF格式 郝伟 2021/01/23 [TOC]

1. 简介

matplotlib库是一个非常强大的图像绘制库,能够输出各种漂亮的函数图像,同时matplotlib可以输入为多种格式的图片。但是作为一般的图片输出时,放大后图片会失真,同时图片中的文字也不支持搜索。所以,本文介绍了一种可以用将matplotlib中绘制的内容输出为矢量的PGF格式,从而实现矢量输出的目的。

先看下实际引用文件的效果,以下引入了这个文件:pdf_demo.pdf

【HTML 嵌入PDF文件】

This browser does not support PDFs. Please download the PDF to view it: Download PDF.

PS,以上的嵌入代码如下:

<object data="pgf_demo.pdf" type="application/pdf" width="800px" height="1000px">
    <embed src="pgf_demo.pdf">
        <p>This browser does not support PDFs. Please download the PDF to view it: <a href="pgf_demo.pdf">Download PDF</a>.</p >
    </embed>
</object>

2. 第1步:使用plot绘制

以下的关键代码已经高亮。几点注意事项:

  1. 必需引入matplotlib
  2. 要先定义24-30行,其后的代码才有效
  3. plot.show() 失效
  4. 暂时不支持中文

```python{.line-numbers, highlight=[5,24-30, 97]} import math import matplotlib.pyplot as plt import numpy as np import scipy.stats import matplotlib

def normal_dis(x, mu=50, sigma=5): ''' x: 输入待计算的值 μ: (mu, 读作:谬) 为数学期望, σ (sigma, 读作:西格玛)为标准差 '''

# k = 0.3989422804014327 / mu # 1.0 / math.sqrt(2 * math.pi)
return 0.3989422804014327 / sigma * math.exp(- (x - mu) * (x - mu) / (2 * sigma * sigma))

3. pyplot methods reference

4. https://matplotlib.org/api/_as_gen/matplotlib.pyplot.html?highlight=plot#module-matplotlib.pyplot

5. 支持中文

plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号

matplotlib.use("pgf") matplotlib.rcParams.update({ "pgf.texsystem": "pdflatex", 'font.family': 'serif', 'text.usetex': True, 'pgf.rcfonts': False, })

6. mu 和 sigma

mu, sigma = 50, 12 n1 = scipy.stats.norm(mu, sigma)

7. 生成符合 N(mu, sigma)的正态分布曲线的数据

8. PS: scipy中提供了生成方法,如 ys = scipy.stats.norm.pdf(xs, mu, sigma)

xs = list(range(101)) ys = [normal_dis(x, mu, sigma) for x in xs] plt.plot(xs, ys, color='darkblue', label='Normal Distribution')

9. 填充函数区域

for i in range(1, 4): xs = np.linspace(mu - sigma i, mu + sigma i, 100) ys = scipy.stats.norm.pdf(xs, mu, sigma) plt.fill_between(xs, ys, 0, alpha=0.35, color='darkblue')

10. 绘制线条和文字

for i in range(1, 4):

# 计算中间三个区间连线的两端坐标
x1 = mu - sigma * i
x2 = mu + sigma * i
y1 = normal_dis(x1, mu, sigma)
y2 = normal_dis(x2, mu, sigma)
# 绘制三条线段,分别为左右1条和上下2条
plt.plot([x1, x2], [y1, y2], color='r')
plt.plot([x1, x1], [y1, 0], color='black')
plt.plot([x2, x2], [y1, 0], color='black')
# 绘制相应的文本
plt.text((x1+x2)/2-3, y1, '{:.2%}'.format(n1.cdf(x2) - n1.cdf(x1)), fontsize=14, color='w')
plt.text(x1 - 12, y1, f"$\mu - {i}\sigma$", fontsize=14)
plt.text(x2 + 3, y1, f"$\mu + {i}\sigma$", fontsize=14)

11. 绘制顶部横线

y_top = 1/math.sqrt(2*math.pi)/sigma plt.plot([0, mu], [y_top, y_top], color='black')

12. 绘制最上方的单个的 \mu

plt.text(mu, normal_dis(mu, mu, sigma) + 0.0003, f'$\mu$', fontsize=14, color='black')

13. 用plot函数绘制折线图,线条颜色设置为绿色

plt.title(f'N($\mu=50, \sigma=12$)',fontsize=24)

14. 设置图表标题和标题字号

plt.tick_params(axis='both',which='major',labelsize=14)

15. 设置刻度的字号

plt.xlabel('Range',fontsize=14)

16. 设置x轴标签及其字号

plt.ylabel('Probility',fontsize=14)

17. 设置X轴和Y轴的显示范围

plt.xlim(0, 100) plt.ylim(0, 0.035)

18. 设置X轴的显示的内容为 [0, 10, 20, ..., 100]

plt.xticks(range(0, 110, 10))

19. 显示每条曲线的文本

plt.legend()

20. 显示网格,黑色透明度为 0.2

plt.grid(color='black', alpha=0.2)

21. plt.show()

plt.savefig('histogram.pgf')


需要注意一下,在以上代码中使用了导出为pgf格式,导出功能如以下代码所示:
```python
# Exporting Matplotlib Plots
# Adjust your matplotlib script by adding the following lines after import matplotlib:

matplotlib.use("pgf")
matplotlib.rcParams.update({
    "pgf.texsystem": "pdflatex",
    'font.family': 'serif',
    'text.usetex': True,
    'pgf.rcfonts': False,
})
Update the save command to write to .pgf

plt.savefig('histogram.pgf')
# make sure LaTeX is installed on the system. The command pdflatex is needed. On Mac brew cask install mactex does the job.

22. 第2步:编写LaTeX代码

内容如下:

\documentclass{article} 
\usepackage{pgfplots}  % for processing pgf 
\usepackage{layouts}   % for actural size

% to adjust size of pgf figures
% \printinunitsof{in}\prntlen{\textwidth}

\begin{document} 
    \begin{figure}
        \begin{center}
            \input{histogram.pgf}
        \end{center}
        \caption{A PGF histogram from \texttt{matplotlib}.}
    \end{figure}
\end{document}

编译后即可将PGF文件嵌入至PDF中。

23. 参考文献

[1] matplotlib 官网, matplotlib.pyplot API文档, https://matplotlib.org/api/_as_gen/matplotlib.pyplot.html?highlight=plot#module-matplotlib.pyplot [2] matplotlib官方, plot函数API文档, https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html [3] 欧德飞, 标准正态分布概率密度函数的定积分计算方法及Python实现代码, https://zhuanlan.zhihu.com/p/59495652 [4] Timo Denk, Exporting Matplotlib Plots to LaTeX, https://timodenk.com/blog/exporting-matplotlib-plots-to-latex/, August 12, 2019. [5] matplotlib输出LaTex https://timodenk.com/blog/exporting-matplotlib-plots-to-latex/

results matching ""

    No results matching ""