0%

【漫漫科研路\pgfplots】克服绘制色温图时,数据量大出现的内存限制

在科研论文写作中,经常会遇到画色温图,3D图。此时一般输入的数据量比较大,导致在Latex中使用Tikz画图时出现内存不足的情况。常常报错如下:

1
! 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也有相同的文件,编辑这个文件无法解决问题

其内容修改如下:
图1
注意:修改的内存大小不能超过实际内存大小,我的是8G.

最后,打开终端进入安装目录下,执行

1
sudo texhash

若发生文件不可写的情况,可以使用chmod 777 来更改文件读写权限。


下面,我们通过实例来验证:

  • 数据产生
    我们使用Matlab的peaks函数来产生peaks.dat文件用于tikz画图的输入数据。其代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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源代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     \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}

    画图效果如下:
    图2

坚持原创技术分享,您的支持将鼓励我继续创作!