5

I'm using TikZ to generate line after line of graphics based on certain sets of data supplied by an external program I'm working on. When there is more than one set of data I want all of their graphical representations to also start printing at the beginning of the document just like the first one.

The thing is, my LaTeX file is generated entirely by that external program of mine and cannot be modified by hand afterwords (well, it can, but this is for end users who will not know how to do this).

Here's an mwe that might make it clearer:

\documentclass[11pt]{memoir}  
\usepackage{tikz}  
\begin{document}  

\begin{tikzpicture} % 1st line  
  \draw[fill=black] (8pt,1) circle [radius = 8pt];  
  \draw[fill=black] (40pt,1) circle [radius = 4pt];  
\end{tikzpicture}\\  
\begin{tikzpicture} % 2nd line  
  \draw[fill=blue] (18pt,1) circle [radius = 11pt];  
  \draw[fill=blue] (30pt,1) circle [radius = 3pt];  
\end{tikzpicture}\\  

%%%% This data is all generated on a separate run and 
%%%% must be appended to the above -- I cannot merge them!  
\begin{tikzpicture} % This should start printing on the "1st line" above with the black circles   
  \draw[fill=green] (4pt,1) circle [radius = 4pt];  
  \draw[fill=green] (50pt,1) circle [radius = 2pt];  
\end{tikzpicture}\\  
\begin{tikzpicture} % This should start printing on the "2nd line" above with the blue circles  
  \draw[fill=red] (12pt,1) circle [radius = 5pt];  
  \draw[fill=red] (72pt,1) circle [radius = 1pt];  
\end{tikzpicture}\\  

\end{document}`  

I'm hoping there's a magic command I can insert before the %%%% line above that tells LaTeX to reset, what I'm going to call, the "printing cursor" to the beginning of the document. Ideally to the same point as the first printed line as I do have a large title section I don't have in my mwe but if I have to print over the title I'm fine with that.

All subsequent runs of data and TikZ representations have no relation to the original set of TikZ commands and if they print over previous runs that's perfectly ok -- this is for art, not legibility. Notice my use of paragraph breaks, this works really well and LaTeX handles page breaks perfectly when doing this. It's a very simple method I'm using and I'm using it in three graphical styles and plan on more, so I need to keep it simple and any solution that requires changing this underlying method probably won't be worth the effort.

I'm a poor programmer. My program that generates all this data can only append any new set of TikZ commands at the end of the file. There is no easy way for me to merge the new commands within the existing lines (like I would do if I were typesetting this by hand). So I need to be able to reset where the next printed line will be to the top of the document. It's worth noting that the beginning of the document might be even a few pages away after one run through the data!

If there's not a magic command, I can enclose the existing chunks of code in a larger scope and even nested scopes but it all needs to work the same way for each chunk. Though I can do something different for just the first run if I have to like setting nodes and then the rest of the chunks can use those nodes to start printing from.

I've added an image that shows the results of the mwe but below that shows what I want it to look like but keeping the same overall form as the mwe.

enter image description here

  • it isn't clear what output you want (but you should not have \\ before the blank lines) do you want all the tikzpicture to overprint? – David Carlisle Oct 26 '16 at 21:08
  • If you look at the code the black circles will be on one line and the blue on the next. And then I want the green circles to begin printing on the line with the black circles which means the red ones will begin printing on the line with the blue circles. They might print over each other or they may not depending on the data, but either result is fine -- the data is music and sometimes musical notes sound at the same time. – bfootdav Oct 26 '16 at 21:15
  • @DavidCarlisle, I've added an image that hopefully makes it clearer what I'm trying to do while keeping the overall structure of my LaTeX file. – bfootdav Oct 26 '16 at 21:36
2

You can use remember picture and overlay, but you should compile twice in this case.

\documentclass{article}
\usepackage{tikz}
\begin{document}

\noindent
\begin{tikzpicture}[remember picture] % 1st line
  \coordinate (first origin) at (0,0);
  \draw[fill=black] (8pt,1) circle [radius = 8pt];
  \draw[fill=black] (40pt,1) circle [radius = 4pt];
  \path (0,0) ++(80pt,0); % to reserve place for the next overprint
\end{tikzpicture}\\
\begin{tikzpicture}[remember picture] % 2nd line
  \coordinate (second origin) at (0,0);
  \draw[fill=blue] (18pt,1) circle [radius = 11pt];
  \draw[fill=blue] (30pt,1) circle [radius = 3pt];
\end{tikzpicture}
%%%% This data is all generated on a separate run and
%%%% must be appended to the above -- I cannot merge them!
\begin{tikzpicture}[remember picture, overlay, shift={(first origin)}] % This should start printing on the "1st line" above with the black circles
  \draw[fill=green] (4pt,1) circle [radius = 4pt];
  \draw[fill=yellow] (50pt,1) circle [radius = 2pt];
\end{tikzpicture}\\
\begin{tikzpicture}[remember picture, overlay, shift={(second origin)}]
% This should start printing on the "2nd line" above with the blue circles
  \draw[fill=red] (12pt,1) circle [radius = 5pt];
  \draw[fill=red] (72pt,1) circle [radius = 1pt];
\end{tikzpicture}

\end{document}

enter image description here

Note: It is probably better to save all your generated data in macros, and only after that to generate the entire image and not to superpose images.

  • Hey Kpym this looks good. And while it involves more changes to my underlying program than I was hoping for it should be doable and it looks like it should be able to preserve the automatic page breaks. I have to admit that I'm a little surprised that there's not something built-in to TeX/LaTeX to just start printing again at the top of the document. I'm going to wait a bit before marking this answered in case there is some such magic TeX command lurking about somewhere ... – bfootdav Oct 26 '16 at 22:19
2

You should be able to do this using overlays. The idea is that all \draw statements are relative to a fixed origins "line1" and "line2", which is done using coordinates of the form (line1)+(x,y), where the origin is a remembered coordinate and (x,y) gives the distance from the origin.

With this modification your MWE produces: enter image description here

As proof-of-concept I think this approach does what you want, although you will probably need to tweak the offsets . Of course, I am assuming that you are able to change the output of your "external program"!

Here is the code.

\documentclass[11pt]{memoir}
\usepackage{tikz}
\begin{document}
\tikzstyle{every picture}+=[remember picture,overlay]

\begin{tikzpicture} % 1st line
  \coordinate (line1) at (0,0);
  \draw[fill=black] (line1)+(8pt,1) circle [radius = 8pt];
  \draw[fill=black] (line1)+(40pt,1) circle [radius = 4pt];
\end{tikzpicture}

\begin{tikzpicture} % 2nd line
  \coordinate (line2) at (0,0);
  \draw[fill=blue] (line2)+(18pt,1) circle [radius = 11pt];
  \draw[fill=blue] (line2)+(30pt,1) circle [radius = 3pt];
\end{tikzpicture}

%%%% This data is all generated on a separate run and
%%%% must be appended to the above -- I cannot merge them!
\begin{tikzpicture} 
% This should start printing on the "1st line" above with the black circles
  \draw[fill=green] (line1)+(4pt,1) circle [radius = 4pt];
  \draw[fill=green] (line1)+(50pt,1) circle [radius = 2pt];
\end{tikzpicture}

\begin{tikzpicture} 
% This should start printing on the "2nd line" above with the blue circles
  \draw[fill=red] (line2)+(12pt,1) circle [radius = 5pt];
  \draw[fill=red] (line2)+(72pt,1) circle [radius = 1pt];
\end{tikzpicture}

\end{document}

As David suggests, I have also removed the \\ at the ends of lines.

EDIT

Here is an easier syntax that combines the ideas in my post with the shift syntax used in @Kpym's. This way is it only necessary to mark the subsequent "lines" with lineone or linetwo as the start of the tikzpicture environment:

\documentclass[11pt]{memoir}
\usepackage{tikz}
\begin{document}
\tikzset{% styling for lineone and linetwo: set the shift and overlays
  lineone/.style={remember picture,overlay, shift={(lineone)}},
  linetwo/.style={remember picture,overlay, shift={(linetwo)}},
}

\begin{tikzpicture}[remember picture] % 1st line
  \coordinate (lineone) at (0,0);
  \draw[fill=black] (8pt,1) circle [radius = 8pt];
  \draw[fill=black] (40pt,1) circle [radius = 4pt];
\end{tikzpicture}

\begin{tikzpicture}[remember picture] % 2nd line
  \coordinate (linetwo) at (0,0);
  \draw[fill=blue] (18pt,1) circle [radius = 11pt];
  \draw[fill=blue] (30pt,1) circle [radius = 3pt];
\end{tikzpicture}

%%%% This data is all generated on a separate run and
%%%% must be appended to the above -- I cannot merge them!
\begin{tikzpicture}[lineone]
  \draw[fill=green] (4pt,1) circle [radius = 4pt];
  \draw[fill=green] (50pt,1) circle [radius = 2pt];
\end{tikzpicture}
\begin{tikzpicture}[linetwo]
  \draw[fill=red] (12pt,1) circle [radius = 5pt];
  \draw[fill=red] (72pt,1) circle [radius = 1pt];
\end{tikzpicture}

\end{document}
  • Thank you Andrew, but I do need some of the circles to be on the next lines like in my example image. Would using this method require me to set up an "origin" for each line like: (origin1) at (0,0) (origin2) at (0,2) etc? – bfootdav Oct 26 '16 at 22:02
  • Yes. I'll edit the solution. I didn't do this initially because I was not sure of the appropriate offsets. You'll probably still nee to tweak these. – Andrew Oct 26 '16 at 22:41
  • Thanks Andrew. I should be able to adapt that to my program as I can iterate over the names of the line numbers (line1, line2, etc) easy enough. I'm still a little surprised that there's not a command to just jump to the beginning of the document to begin printing again. Oh well. – bfootdav Oct 27 '16 at 20:48

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.