在科研论文写作中,经常会遇到画色温图,3D图。此时一般输入的数据量比较大,导致在Latex中使用Tikz画图时出现内存不足的情况。常常报错如下:
! TeX capacity exceeded, sorry [main memory size=5000000].
参考pgfplots手册中的第六章,我们有以下解决方案:
- 使用LuaTex进行编译
有些版本不含LuaTex - 对输入数据采样降低数据量
不是从本质上解决问题,降低了精度 - 使用其它软件画图,e.g., MATLAB
- 增大LaTex的编译内存
本文主要介绍如何在MacOS系统中Texlive平台下,克服内LaTex内存限制。关于在Linux和MiKTEX环境下,pgfplots手册已给了说明,这里不再赘述。
解决办法:在Texlive安装目录中找到texmf.cnf文件并编辑:
其安装目录在:
/usr/local/texlive/2018/texmf-dist/web2c/texmf.cnf
注意:/usr/local/texlive/2018/texmf.cnf也有相同的文件,编辑这个文件无法解决问题
其内容修改如下:
注意:修改的内存大小不能超过实际内存大小,我的是8G.
最后,打开终端进入安装目录下,执行
sudo texhash
若发生文件不可写的情况,可以使用chmod 777 来更改文件读写权限。
下面,我们通过实例来验证:
-
数据产生
我们使用Matlab的peaks函数来产生peaks.dat文件用于tikz画图的输入数据。其代码如下:clear all clc close all lambda_total=2;% the sum of Z [X,Y,Z] = peaks(100); Z(Z<0)=0; Z=Z/sum(sum(Z))*lambda_total; x_temp=repmat(1:100,100,1);% X-axis x_temp=x_temp(:); y_temp=repmat(1:100,1,100);%Y-axis xyz=['x y z']; dlmwrite('peaks.dat',xyz,'delimiter',' '); for x_ind=1:size(Z,1) for y_ind=1:size(Z,2) % for one point (x,y,z), we use 4 coordinates (x,y,z) (x,y+1,z) (x+1,y+1,z) (x+1,y,z) to form a patch xyz=[x_ind y_ind Z(x_ind, y_ind);x_ind y_ind+1 Z(x_ind, y_ind);x_ind+1 y_ind+1 Z(x_ind, y_ind);x_ind+1 y_ind Z(x_ind, y_ind)]; if(x_ind==1&&y_ind==1) dlmwrite('peaks.dat',xyz,'delimiter',' ','-append','roffset',0); else dlmwrite('peaks.dat',xyz,'delimiter',' ','-append','roffset',1); end end end
-
在Tikz中画图
本文使用了patch来画图,也可以改用surf, mesh等。完整latex源代码如下:\documentclass{standalone} \def\pgfsysdriver{pgfsys-dvipdfmx.def} \usepackage{tikz} \usepackage{pgfplots} \pgfplotsset{width=7cm,compat=1.14} \begin{document} \begin{tikzpicture} \begin{axis}[ colorbar, xmin=1,xmax=101, ymin=1,ymax=101, xlabel={X-axis (m)}, ylabel={Y-axis (m)}, ] \addplot [patch,patch type=rectangle] table [point meta=\thisrow{z}] {peaks.dat }; \end{axis} \end{tikzpicture} \end{document}
画图效果如下: