The problem is that the external
library will automatically assign names for each encountered tikzpicture
- but in your case, you effectively have one name and two pictures.
One could think about a solution which assigns individual file names for each of the two involved pictures - but that is a waste of time because you are never interested in the first one.
So, I propose the following solution: we check if we are currently generating an external picture. If so, we will always typeset the first (which is necessary to determine the picture's size) and we will externalize the second one. If we are currently NOT exporting the (current) picture, we can safely assume that there is an external picture ready at hand - and use it.
Here is the modification. It requires that \usetikzlibrary{external}
has been loaded (although it does not necessarily need to be active).
% Automagically scale a Tikz picture, so it has the desired (given) width.
% Does NOT scale line width/text width! Needs the package "environ"!
%
% Usage:
%
% \begin{myscaletikzwidth}{\textwidth}
% \begin{tikzpicture}[scale=\tikzscale]
% ..
% \end{tikzpicture}
% \end{myscaletikzwidth}
%
\makeatletter
\newsavebox{\measure@tikzpicture}
\NewEnviron{myscaletikzwidth}[1]{%
\tikzifexternalizingnext{%
\def\tikz@width{#1}%
\def\tikzscale{1}\begin{lrbox}{\measure@tikzpicture}%
\tikzset{external/export next=false,external/optimize=false}% force translation of this BODY (and do not optimize it away as it would usually do):
\BODY
\end{lrbox}%
\pgfmathparse{#1/\wd\measure@tikzpicture}%
\edef\tikzscale{\pgfmathresult}%
\BODY
}{% this will re-use an existing external graphics:
\BODY
}%
}
\makeatother
EDIT:
You are right, there are problems with the todonotes
package. It is (unfortunately) incompatible with the tikz external
image. Apparently,
\usepackage{todonotes}
\makeatletter
\renewcommand{\todo}[2][]{%
\tikzexternaldisable\@todo[#1]{#2}\tikzexternalenable%
}
\makeatother
helps here.
The main difficulty is that the scale
and transform shape
keys belong to /tikz/
family and does not penetrate down to PGF level. Instead they are mapped with rather tedious mechanisms. Hence, we need to somewhat fake it with low level transformation commands. If for some reasons we still need to use [x=0.1in,y=0.1in]
we have to add the corresponding \pgfsetxvec
and \pgfsetyvec
commands appropriately to mimic the TikZ effect.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}[scale=.75]
\pgfgettransform{\somemacro}
\draw[top color= black!50] (-2cm,-2cm) rectangle (5cm,4cm);
\draw[style=help lines] (-2cm,-2cm) grid[step=1cm] (5cm,4cm);
\node (o) at (0,0) {0};
\begin{scope}
\pgfset{minimum width=1.5cm,minimum height=1.5cm}
\pgftransformshift{\pgfpoint{3cm}{0cm}}
\pgfnode{star}{center}{}{}{\pgfusepath{clip}}
\pgfsettransform{\somemacro}
\fill[yellow] (3cm,0cm) circle (0.65cm);
\end{scope}
\node[draw,circle,transform shape] (dum) at (2,2) {(2,2)};
\begin{scope}
\pgfset{minimum width=2cm,minimum height=2cm}
\pgftransformshift{\pgfpoint{0cm}{2.5cm}}
\pgfnode{star}{center}{}{}{\pgfusepath{clip}}
\pgfsettransform{\somemacro}
\fill[red] (0cm,2.5cm) circle (0.8cm);
\end{scope}
\end{tikzpicture}
\end{document}
Best Answer
Every
tikzpicture
uses the styleevery picture
. So if you put\tikzset{every picture/.append style={scale=0.9}}
near the start of your document, alltikzpicture
s will be scaled by that amount (in addition to anyscale
s you might already be applying to individualtikzpicture
s).