子目录中的 Matplotlib PGF 图像

子目录中的 Matplotlib PGF 图像

我有一个使用 PGF 后端由 Matplotlib 绘制的二维图像。它存储在figures子目录中(因为我有很多图像,不想让主文件夹变得杂乱)。作为生成过程的示例:

from matplotlib import pyplot as plt
import numpy as np

plt.imshow(np.random.randn(200, 200))
plt.title('Some random data')
plt.savefig('figures/test.pgf')

图形子目录现在包含test.pgf和光栅图像test-img0.png。 PGF 文件包含包含 PNG 的命令\pgfimage[interpolate=true,width=4.810000in,height=4.810000in]{test-img0.png}}。由于它(根据设计)不包含figures/。由于它(根据设计)不包含前缀,我需要找到一种解决方法。根据 PGF 文件顶部的评论(并由Matplotlib 问题跟踪器上的这条评论)我可以使用导入包来使事情正常运作:

\documentclass{article}

\usepackage[margin=2cm]{geometry}
\usepackage{import}
\usepackage{pgf}

\begin{document}

\begin{figure}
\begin{center}
\import{figures/}{test.pgf}
\end{center}
\end{figure}

\end{document}

当我编译这个(xelatex test)时,我收到消息

Package pgf Warning: File "test-img0.png" not found when defining image "pgflastimage".
(pgf) Tried all extensions in ".pdf:.jpg:.jpeg:.png:" on input line 62.

找到了 PGF 文件,因此生成的 PDF 具有轴、标题等,但只是一个占位符而不是 PNG。

我也尝试过定义,\graphicspath{{figures/}}但 PGF 似乎也不使用它。

在编译之前将目录添加figuresTEXINPUTS环境变量中是可行的,但这不是最干净的解决方法。我也可以编辑 PGF 文件以包含路径,但每次重新生成图像时我都必须这样做。有人能建议为什么导入不起作用,或者有其他方法吗?

答案1

快速回答

png由于导入图像里面的文件的命令pgfpgfimage,我把它重新定义如下:

\let\pgfimageWithoutPath\pgfimage 
\renewcommand{\pgfimage}[2][]{\pgfimageWithoutPath[#1]{figures/#2}}

第一行将原始pgfimage命令复制到临时的pgfimageWithoutPath。第二行重新定义pgfimage为与 相同pgfimage,但在路径前加上 前缀figures/

阅读下文了解更多详情

我实际上使用章节文件夹包,它允许我将文档拆分为子文件夹,每个章节一个。这对于长文档来说非常棒,但需要一种导入图表的变通方法,这与你遇到的问题完全相同。所以最后我对pgfs 的导入工作如下:

  1. 这与上面的相同,但使用 chapterfolders 的指令。

    \let\pgfimageWithoutCF\pgfimage
    \renewcommand{\pgfimage}[2][]{\pgfimageWithoutCF[#1]{\cfcurrentfolder\subfigurepath#2}}
    
  2. 这是的包装器\input{figure.pgf},其中包括章节路径:

    \newcommand{\includepgf}[1]{\input{\cfcurrentfolder\subfigurepath#1.pgf}}
    
  3. 最后,这是一个使图形完全适合文本宽度的快捷方式(用法如下

    % usage: \resizepgf[<optional size (defaults to textwidth)>]{<filename>}
    \newcommand{\resizepgf}[2][\textwidth]{
        \resizebox{#1}{!}{\includepgf{#2}}
    }
    

谢谢jevopi 的小博客了解操作方法。

答案2

对于更通用的解决方法,如果您有多个图形子文件夹,您可以定义一个包含本地化重新定义的新命令:

\newcommand\inputpgf[2]{{
\let\pgfimageWithoutPath\pgfimage
\renewcommand{\pgfimage}[2][]{\pgfimageWithoutPath[##1]{#1/##2}}
\input{#1/#2}
}}

然后你只需像这样使用它:

\inputpgf{path/to/figures}{figure.pgf}

第一个参数指定包含该图形的所有图像文件的本地文件夹,第二个参数只是 PGF 文件的文件名。

与上一个答案类似,这重新定义了\pgfimage命令,但仅用于执行输入的命令。

答案3

解决方案写在输出的.pgf 文件中。

从其他目录,您可以使用import包裹

\usepackage{import}

然后将数字包括:

\import{<path to file>}{<filename>.pgf}

答案4

虽然几个月前 glopes 的答案对我来说很好用,但在尝试使用新生成的图形时它就坏了,可能是由于 matplotlib 更新,它现在\includegraphics在我的 PGF 文件中内部使用而不是\pgfimage。要将修复程序也应用于此命令,我们需要扩展定义\inputpgf如下:

\newcommand\inputpgf[2]{{
\let\pgfimageWithoutPath\pgfimage
\renewcommand{\pgfimage}[2][]{\pgfimageWithoutPath[##1]{#1/##2}}
\let\includegraphicsWithoutPath\includegraphics
\renewcommand{\includegraphics}[2][]{\includegraphicsWithoutPath[##1]{#1/##2}}
\input{#1/#2}
}}

它对我在使用新旧 PGF 文件的文档中很有用。

相关内容