1

From my previous question/answer Tikz image within a defined box (& the textpos package), @frougon provided a great solution. And now, I'm seeking to have a standard scaling for all of my Tikz-pictures (see the edit/addition).

I want all of my Tikz-pictures to be 3.5cm x 3.5cm, and I can do this by using scale = 3.5/k, where k is the "coordinate-length" of the Tikz-picture.

I'm wondering if there is a way to get the outermost (or length of) coordinates in a Tikz-picture? For example,

\begin{tikzpicture}
    \draw (1,4)--(10,7);
\end{tikzpicture}

would have k=9, as the x-axis ranges from 1 to 10 (a difference of 9), while the y=axis ranges from 4 to 7 (a difference of 3).

I would envision some sort of "maximum" function coming into play here. Something like k = max(<largest x coordinate> - <smallest x coordinate >, <largest y coordinate > - <smallest y coordinate >) = max(10-1,7-4) = max(9,3) = 9.

For a more detailed example, consider the following:

\begin{tikzpicture}
    \draw[thick] (0,0)--(10,5);
    \draw[thick] (0,0)--(5,-10);
    \draw[thick] (0,0)--(-10,5);
    \draw[thick] (0,0)--(-5,-10);
    \draw[thick] (0,0)--(10,-5);
    \draw[thick] (0,0)--(-5,10);
    \draw (.5,2) node {1};
    \draw (-2.5,2.5) node {2};
    \draw (-2,-.5) node {3};
    \draw (0,-2.5) node {4};
    \draw (2.5,-2.5) node {5};
    \draw (2.5,0) node {6};
\end{tikzpicture}

In this case, I would want k = 20, as the "length" of the x-axis (and y-axis, in fact), is 20 coordinate units.

Thanks in advance!

4

UPDATE: This computes the dimensions of the bounding box and the corresponding scale factor, which it applies in the next run. (Replaced max by min, big thanks to frougon!)

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc}
\makeatletter
\newcommand\ExportBB[1]{\path let 
 \p1=($(current bounding box.north east)-(current bounding box.south west)$),
 \n1={#1/\x1},\n2={#1/\y1}
 in \pgfextra{\pgfmathsetmacro{\figscale}{min(\n1,\n2)}\xdef\figscale{\figscale}};
 \immediate\write\@mainaux{\xdef\string\figscale{\figscale}\relax}}
\makeatother
\tikzset{scale to max size/.style={execute at end picture={\ExportBB{#1}},
/utils/exec=\ifdefined\figscale
\else
\message{Recompile the figure.}
\xdef\figscale{1}
\fi,scale=\figscale}}
\begin{document}
\begin{tikzpicture}[scale to max size=3.5cm]
    \draw[thick] (0,0)--(10,5);
    \draw[thick] (0,0)--(5,-10);
    \draw[thick] (0,0)--(-10,5);
    \draw[thick] (0,0)--(-5,-10);
    \draw[thick] (0,0)--(10,-5);
    \draw[thick] (0,0)--(-5,10);
    \draw (.5,2) node {1};
    \draw (-2.5,2.5) node {2};
    \draw (-2,-.5) node {3};
    \draw (0,-2.5) node {4};
    \draw (2.5,-2.5) node {5};
    \draw (2.5,0) node {6};
\end{tikzpicture}
\end{document}

enter image description here

Of course, the texts are not transformed. You could transform them, too, but then it might be more straightforward to use \maxsizebox{3.5cm}{3.5cm}{....} that comes with adjustbox.

This stores the dimensions in \n1 and \n2 in the first example and prints the dimensions in a node in the second example.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
    \draw (1,4)--(10,7);
    \path let \p1=($(current bounding box.north east)-(current bounding
    box.south west)$),\n1={\x1/1cm},\n2={\y1/1cm}
    in \pgfextra{\typeout{x=\n1 cm,y=\n2 cm}};
\end{tikzpicture}

\begin{tikzpicture}[store dimensions of current picture in/.style 2 args={
  insert path={let \p1=($(current bounding box.north east)-(current bounding
    box.south west)$),\n1={\x1/1cm},\n2={\y1/1cm}
    in \pgfextra{\edef#1{\n1}\edef#2{\n2}}}}]
    \draw[thick] (0,0)--(10,5);
    \draw[thick] (0,0)--(5,-10);
    \draw[thick] (0,0)--(-10,5);
    \draw[thick] (0,0)--(-5,-10);
    \draw[thick] (0,0)--(10,-5);
    \draw[thick] (0,0)--(-5,10);
    \draw (.5,2) node {1};
    \draw (-2.5,2.5) node {2};
    \draw (-2,-.5) node {3};
    \draw (0,-2.5) node {4};
    \draw (2.5,-2.5) node {5};
    \draw (2.5,0) node {6};
    \path[store dimensions of current picture in={\myx}{\myy}]
    node[fill=white] at (current bounding box.center) {%
    $x=\pgfmathparse{\myx}\pgfmathprintnumber{\pgfmathresult}$cm,
    $y=\pgfmathparse{\myy}\pgfmathprintnumber{\pgfmathresult}$cm};
\end{tikzpicture}
\end{document}

enter image description here

  • I would like to take the maximum of these lengths and scale the tikzpicture by 3.5/maximum. Also, I'm confused how \n1 and \n2 are actually stored and how I would scale the picture (something like \begin{tikzpicture}[scale = 3.5/max{\n1, \n2}) – ryanj1823 Jun 28 at 6:21
  • @ryanj1823 You cannot know at the beginning of the tikzpicture how large it will be. However, adustbox allows you to do precisely that, it has some maximum functions of that type. – user121799 Jun 28 at 6:24
  • ...and of course you did my "difficult solution" in almost no time. marmots rocks! – Rmano Jun 28 at 6:54
  • 1
    @frougon Yes, that's a nice answer (+1). However, let me mention that there is a second difference: if you use scalebox, adjustbox etc., you can no longer access coordinates with remember picture. In many situations this won't matter, but in some it does. – user121799 Jun 28 at 19:18
  • 1
    @frougon I think that this is just a numerical inaccuracy because the symbolic coordinates are stored internally in pt units, so TikZ converts back and forth and loses the edges. Try e.g. \documentclass[tikz, border=3.14mm]{standalone} \usetikzlibrary{calc} \begin{document} \path let \p1=($(A)-(1,5)$) in \pgfextra{\typeout{\x1,\y1}}; \end{tikzpicture} \end{document}. We probably need to live with these limitations. – user121799 Jun 28 at 22:38
1

This seems to me a kind of XY question... I am not sure about the exact semantic you want, but for example:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{adjustbox}
\begin{document}
\adjustboxset{min width=3.5cm, min height=3.5cm, max width=3.5cm, max height=3.5cm}

\adjustbox{}{\tikz \draw (0,0) rectangle (4,6) (2,2) rectangle (3,3);}
\adjustbox{}{\tikz \draw (0,0) rectangle (6,4) (2,2) rectangle (3,3);}
\adjustbox{}{\tikz \draw (0,0) rectangle (6,6) (2,2) rectangle (3,3);}
\adjustbox{}{\tikz \draw (0,0) rectangle (1,1) (.2,.2) rectangle (.3,.3);}
\end{document}

will produce: enter image description here

which can or cannot be what you want (notice the effect of scaling on the smaller picture).

Otherwise, the only other way I see is using @marmot answer, and doing a bit of magic to store the scale factor in the .aux file to be used at the second pass. (Too complex now to think about it, no time...)

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.