Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

For each figure in my main document, I import the corresponding page of a multipage .pdf containing all pictures (one picture per page).

Is there a way to give a label to each picture, in order to import a picture by giving its label instead of its page number ? This means that I would like to do something like

\includegraphics[pagelabel={Figure name}]{pictures.pdf}

instead of

\includegraphics[page=1]{pictures.pdf}

Here is a code producing my file with (some) figures :

\documentclass[multi=true,tikz,border={0pt  0pt 1cm 0pt}]{standalone}

\usepackage{amsmath,amssymb,amsrefs}
\usepackage{t1enc}%\usepackage[svgnames]{xcolor}
%\usepackage{tikz}
\usepackage{tcolorbox}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}

\newcommand{\x}{14cm}\newcommand{\y}{\x/2.5}
\newcommand{\all}{thick,width=\x,height=\y}
\newcommand{\size}{\small}
\begin{document}

\begin{tikzpicture}         %%% I would like to give a label \label{Figure name}
\begin{axis}[\all,ybar=-10pt,enlargelimits=0.05,ylabel={Volume},ymin=1,xlabel={Price},ymax=20,nodes near coords,nodes near coords align={vertical},xtick={2,3,4,5,6,7,8,9,10,11,12}]\size
\addplot[black,fill=blue] coordinates {(2,7) (3,8) (4, 15) (5, 10) (6,12)};
\addplot[black,fill=red] coordinates { (8, 18) (9, 12) (10,15) (11,5) (12,3)};
\legend{Buy orders, Sell orders}
\end{axis}
\end{tikzpicture}

\newpage

\begin{tikzpicture}
\begin{axis}[\all,ybar=-10pt,enlargelimits=0.05,ylabel={Volume},ymin=1,xlabel={Price},ymax=20,nodes near coords,nodes near coords align={vertical},xtick={2,3,4,5,6,7,8,9,10,11,12}]\size
\addplot[black,fill=blue] coordinates  {(2,7) (3,8) (4, 15) (5, 10) (6,12)};
\addplot[black,fill=red] coordinates  { (8, 8) (9, 12) (10,15) (11,5) (12,3)};
\addplot[black,fill=red, opacity=0.2] coordinates { (8, 18)};
\legend{Buy orders, Sell orders}
\end{axis}
\end{tikzpicture} \end{document}
share|improve this question
add comment

3 Answers

up vote 10 down vote accepted

Put in the file figs.tex with the pictures labels, e.g. \label{fig:nameA} and \label{fig:nameB} on the pages. And then do this in your main document:

\documentclass{article}
\usepackage{graphicx,xr,refcount}
\externaldocument[A-]{figs}
\begin{document}
\includegraphics[page=\getpagerefnumber{A-fig:nameA}]{figs}
\includegraphics[page=\getpagerefnumber{A-fig:nameB}]{figs}
\end{document}
share|improve this answer
    
I see your answer is a little bit simpler than mine, and you beat me by 53 seconds. :^) –  Steven B. Segletes Jun 26 '13 at 18:09
2  
@StevenB.Segletes: I can't handle complicated code so I always find the simple solutions ;-). –  Ulrike Fischer Jun 26 '13 at 18:10
add comment

EDITED to fully allow printing figures by reference label. (RE-EDITED to correct \label which had been pointing to the key, rather than figure number)

If you are willing to do things a little differently (i.e., using your figure source file directly, rather than by way of PDF import), here is an idea employing the figure (and table) deferral mechanism of the boxhandler package. I am assuming that you wish to use your graphics as figure floats.

Before getting into the specifics of this solution, I should just say in generality that boxhandler can save figures (graphics and captions) without printing them (using \holdFigures). When it finally does print them, it wants to do so in the order they were created (via \nextFigure). So the challenge to this solution is in fooling boxhandler's FigureClearedIndex count into printing out the stored images in the order eventually requested by the user, rather than in the order they were generated.

Now, to the solution. First, you put your figures in a separate file, like this (figs.tex) that can be \input. Note that I have created there, at the top of figs.tex, the commands \storethisfigure and \showreffigure which will be used to create and later recall-by-reference the figures (I had to use Heiko's refcount package to accomplish this task):

\usepackage{boxhandler}
\usepackage{refcount}
\newcounter{FigOutputCount}
\newcommand\showreffig[1]{%
  \setcounter{FigureClearedIndex}{\getrefnumber{KEY#1}}%
  \refstepcounter{FigOutputCount}\label{#1}%
  \addtocounter{FigureClearedIndex}{-1}%
  \nextFigure%
}
\newcounter{reffigcounter}
\newcommand\storethisfigure[3]{%
  \refstepcounter{reffigcounter}\label{KEY#1}%
  \bxfigure{#2}{#3}%
}
\holdFigures

\storethisfigure{fg:large}{large figure caption}{%
\scalebox{.9}{%
\begin{tikzpicture}         %%% I would like to give a label \label{Figure name}
\begin{axis}[\all,ybar=-10pt,enlargelimits=0.05,ylabel={Volume},ymin=1,xlabel={%
Price},ymax=20,nodes near coords,nodes near coords align={vertical},xtick={%
2,3,4,5,6,7,8,9,10,11,12}]\size
\addplot[black,fill=blue] coordinates {(2,7) (3,8) (4, 15) (5, 10) (6,12)};
\addplot[black,fill=red] coordinates { (8, 18) (9, 12) (10,15) (11,5) (12,3)};
\legend{Buy orders, Sell orders}
\end{axis}
\end{tikzpicture}
}
}

\storethisfigure{fg:small}{small figure caption}{%
\scalebox{.6}{%
\begin{tikzpicture}
\begin{axis}[\all,ybar=-10pt,enlargelimits=0.05,ylabel={Volume},ymin=1,xlabel={%
Price},ymax=20,nodes near coords,nodes near coords align={vertical},xtick={%
2,3,4,5,6,7,8,9,10,11,12}]\size
\addplot[black,fill=blue] coordinates  {(2,7) (3,8) (4, 15) (5, 10) (6,12)};
\addplot[black,fill=red] coordinates  { (8, 8) (9, 12) (10,15) (11,5) (12,3)};
\addplot[black,fill=red, opacity=0.2] coordinates { (8, 18)};
\legend{Buy orders, Sell orders}
\end{axis}
\end{tikzpicture}
}
}

The figs.tex file is \input in the preamble of your main document. Then, to recall the figures in whatever order you want, use \showreffig{label}. Note in this example, I first recall the image that was second in the file and later the first image.

\documentclass{article}
\usepackage{amsmath,amssymb,amsrefs}
\usepackage{t1enc}%\usepackage[svgnames]{xcolor}
%\usepackage{tikz}
\usepackage{tcolorbox}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepackage{lipsum}
\newcommand{\x}{14cm}\newcommand{\y}{\x/2.5}
\newcommand{\all}{thick,width=\x,height=\y}
\newcommand{\size}{\small}
\input{figs}
\begin{document}
\lipsum[4]
\showreffig{fg:small}
\lipsum[4]
\showreffig{fg:large}
In figure~\ref{fg:large}, we see the following.  But in 
figure~\ref{fg:small}...
\end{document}

The result looks like this:

enter image description here

As a side benefit, the boxhandler package gives great control over caption appearance.

share|improve this answer
    
This is a good solution ! In my case, I would prefer to compile the pictures and the main file separately to increase the speed. –  Laurent Jun 26 '13 at 14:43
    
@user81566 Understood. In that case, Im guessing the figs file will have to output a special file that contains reference information, later read by the main tex file. –  Steven B. Segletes Jun 26 '13 at 15:08
    
Exactly, I thought for example to add a hidden text, corresponding to the label of the picture. This hidden text could then be read as the pdf files are imported. This may be complicated to implement, but it could be useful when it works :) –  Laurent Jun 26 '13 at 15:19
add comment

I am adding a second answer, because in the other answer, I showed how to solve this problem (create figures via \ref labels) if you were willing to recompile the figures with the main document. Here, I produce what the user actually wanted, which is to load the figures in from an external PDF file, also via the \ref label mechanism.

In this solution (called FBR for figure-by-ref), I also have a file that contains just the actual figure data. Here it is, called FBRfigs.tex and looks like this:

\storethisfigure{fg:eighteen}{18 peak sells}{%
\begin{tikzpicture}         %%% I would like to give a label \label{Figure name}
\begin{axis}[\all,ybar=-10pt,enlargelimits=0.05,ylabel={Volume},ymin=1,xlabel={Price},ymax=20,nodes near coords,nodes near coords align={vertical},xtick={2,3,4,5,6,7,8,9,10,11,12}]\size
\addplot[black,fill=blue] coordinates {(2,7) (3,8) (4, 15) (5, 10) (6,12)};
\addplot[black,fill=red] coordinates { (8, 18) (9, 12) (10,15) (11,5) (12,3)};
\legend{Buy orders, Sell orders}
\end{axis}
\end{tikzpicture}
}

\conditionalnewpage

\storethisfigure{fg:eight}{8 peak sells}{%
\begin{tikzpicture}
\begin{axis}[\all,ybar=-10pt,enlargelimits=0.05,ylabel={Volume},ymin=1,xlabel={Price},ymax=20,nodes near coords,nodes near coords align={vertical},xtick={2,3,4,5,6,7,8,9,10,11,12}]\size
\addplot[black,fill=blue] coordinates  {(2,7) (3,8) (4, 15) (5, 10) (6,12)};
\addplot[black,fill=red] coordinates  { (8, 8) (9, 12) (10,15) (11,5) (12,3)};
\addplot[black,fill=red, opacity=0.2] coordinates { (8, 18)};
\legend{Buy orders, Sell orders}
\end{axis}
\end{tikzpicture}
}

Now, to create the desired PDF file with just the images in it, I must place a wrapper around this data file. I call the wrapper FBRpdfs.tex, and it looks like this. Note the wrapper uses information supplied by the user in his question.

\documentclass[multi=true,tikz,border={0pt  0pt 1cm 0pt}]{standalone}

\usepackage{amsmath,amssymb,amsrefs}
\usepackage{t1enc}%\usepackage[svgnames]{xcolor}
%\usepackage{tikz}
\usepackage{tcolorbox}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\newcommand{\x}{12cm}\newcommand{\y}{\x/2.5}
\newcommand{\all}{thick,width=\x,height=\y}
\newcommand{\size}{\small}

\newcommand\storethisfigure[3]{#3}

\newcommand\conditionalnewpage{\newpage}

\begin{document}
\input{FBRfigs}
\end{document}

Thus, pdflatex'ing FBRpdfs.tex produces FBRpdfs.pdf, containing the two images on two pages (Note that I now identify the images as "18" and "8" because I can no longer use \scalebox to shrink them, for some reason, with the standalone class, as I did in my other solution).

Now, for the solution on how to access these images by reference, I use a very similar logic to my earlier posted solution. Rather than using a different external file to store the reference information, however, I actually re-read the FBRfigs.tex file to get the reference label information, WHILE THROWING AWAY THE ACTUAL GRAPHICS CONTENT of that file! This means, I don't need all the tikz stuff, etc. and don't need to recompile the graphics. I am only using the file to get the label information, and I actually save the captions, too. Then, with the \includefig command that I define, I extract the graphic from the file, and place the re-read caption under it, as follows:

\documentclass{article}
\usepackage{lipsum}
\usepackage{boxhandler}
\usepackage{graphicx}
\usepackage{refcount}

\newcounter{FigureFileIndex}
\newcounter{FigOutputCount}
\newcounter{reffigcounter}

\newcommand\includefig[2][htbp]{%
  \setcounter{FigureFileIndex}{\getrefnumber{KEY#2}}%
  \refstepcounter{FigOutputCount}\label{#2}%
  \bxfigure[#1]{\csname figurecaption\roman{FigureFileIndex}\endcsname}%
    {\includegraphics[page=\value{FigureFileIndex}]{FBRpdfs.pdf}}%
}

%NOTE: NOTHING IS DONE BELOW WITH [EXPENSIVE] ARGUMENT #3
\newcommand\storethisfigure[3]{%
  \refstepcounter{reffigcounter}\label{KEY#1}%
  \expandafter\def\csname figurecaption\roman{reffigcounter}\endcsname{#2}%
}

\newcommand\conditionalnewpage{}

\input{FBRfigs}
\begin{document}
This is my introductory paragraph.

\includefig[ht]{fg:eight}
\lipsum[4]
\includefig[ht]{fg:eighteen}
In figure~\ref{fg:eighteen}, we see the following.  But in 
figure~\ref{fg:eight}...
\end{document}

Doing a pdflatex on FBR.tex (since the page= qualifier is only understood by pdflatex) produces the following:

enter image description here

There is only one strange thing that I note. I believe it arises from the refcount package and maybe someone knows the issue already. It is this: if a compile fails (due to typographical error, etc.) then all recompiles fail, even when the error is corrected and the .aux file is deleted. The only way, then, to make it work is to comment out all calls to \includefig (which is where the refcount stuff is accessed), recompile, then uncomment the \includefig calls, and recompile again. That is a major nuisance, but it is out of my control. I'm guessing refcount keeps some .aux-like file (not in my working directory) that needs to be reset, somehow. I just don't know.

share|improve this answer
    
I am willing to delete this solution, in light of Ulrike's (cough) "more streamlined" approach. unless @user81566 wishes to leave it as an exercise in excess. –  Steven B. Segletes Jun 26 '13 at 18:13
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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