8

I have a two-dimensional image plotted by Matplotlib using the PGF backend. It is stored in the figures subdirectory (since I have a lot of images and don't want to clutter up the main folder). As an example of the generation process:

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')

The figures subdirectory now contains test.pgf and the raster image test-img0.png. The PGF file includes the command \pgfimage[interpolate=true,width=4.810000in,height=4.810000in]{test-img0.png}} to include the PNG. Since it (by design) does not contain the figures/ prefix, I need to find a workaround. According to a comment at a top of the PGF file (and backed up by this comment on the Matplotlib issue tracker) I can use the import package to make things work:

\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}

When I compile this (xelatex test), I get the message

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.

The PGF file is found, so the resulting PDF has the axes, title etc, but just a placeholder instead of the PNG.

I also tried defining \graphicspath{{figures/}} but PGF doesn't seem to use that either.

Adding the figures directory to the TEXINPUTS environment variable prior to compiling works, but it isn't the cleanest workaround. I could also edit the PGF file to include the path, but I'd have to do that every time I regenerate the image. Can anybody suggest why import isn't working, or an alternative method?

8

Quick answer

Since the command that imports the png files inside the pgf image is pgfimage, I redefined it like this:

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

The first line copies the original pgfimage command to a temporary pgfimageWithoutPath. The second line redefines pgfimage to be the same as pgfimage, but prefixing the path with figures/.

Read below for more details

I actually use the chapterfolder package, which allows me to split the document into subfolders, one per chapter. It's very cool for long documents but needs a workaround for importing the figures, exactly the same problem that you had. So in the end my importing for pgfs works like this:

  1. This is the same as above, but using chapterfolders' directives.

    \let\pgfimageWithoutCF\pgfimage
    \renewcommand{\pgfimage}[2][]{\pgfimageWithoutCF[#1]{\cfcurrentfolder\subfigurepath#2}}
    
  2. This is a wrapper to \input{figure.pgf}, which includes the chapter path:

    \newcommand{\includepgf}[1]{\input{\cfcurrentfolder\subfigurepath#1.pgf}}
    
  3. And finally this is a shortcut to make the figure fit exactly the width of the text (to be used like

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

Thanks to jevopi's little blog for the how-to.

  • Great, thanks. The chapterfolder example is also really useful -- finding something like this to break up my thesis is on my list of things to do :). – Blair Sep 2 '13 at 3:29
6

For a more general workaround, in the case where you have multiple figure subfolders, you can define a new command which includes a localized redefinition:

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

You then simply use it like so:

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

The first argument specifies the local folder from which all image files for that figure will be included, and the second argument is just the filename of the PGF file.

Like the previous answer, this redefines the \pgfimage command, but only for the execution of the input command.

  • 1
    this works beautifully for me! – Nolan Conaway Jan 6 '17 at 21:43
0

The solution is written in the output .pgf file.

From other directories you can use the import package

\usepackage{import}

and then include the figures with:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.