2

This question is related to the answer of tcolorbox: get height of actual box from inside box

Is it possible to get the newly defined option remember height working with \usetikzlibrary{external} \tikzexternalize and \usepackage{tikzscale}?

Without externalization I don't know how to handle many plots with lots of data :-(
Please help me again.

\documentclass{article}
\usepackage[breakable]{tcolorbox}
\usepackage{pgfplots}\pgfplotsset{compat=1.9}
\usetikzlibrary{external}
\tikzexternalize           %%%%%%% problem here %%%%%%%%
\usepackage{tikzscale}
\begin{filecontents}{tikzimage.tikz}
    \begin{tikzpicture}
    \begin{axis}[xlabel=time,ylabel=value]
    \addplot{x^2};
    \end{axis}
    \end{tikzpicture}
\end{filecontents}
\makeatletter
\tcbset{%
    remember height/.style={before upper={%
            \iftcb@fixedheight%
            \tcbdimto#1{\kvtcb@top@rule@stand+\kvtcb@bottom@rule@stand+\kvtcb@boxsep*2+\kvtcb@top+\kvtcb@bottom}%
            \iftcb@hasTitle%
            \tcbdimto#1{#1+\ht\tcb@titlebox+\dp\tcb@titlebox+\kvtcb@title@rule+\kvtcb@boxsep*2+\kvtcb@toptitle+\kvtcb@bottomtitle}%
            \fi%
            \tcbdimto#1{\kvtcb@height@fixed-#1}%
            \else%
            \tcbdimto#1{4cm}% fallback
            \fi%
    }},
}
\makeatother
\begin{document}
    \begin{tcolorbox}a\\a\\a\end{tcolorbox}
    \begin{tcolorbox}
        \includegraphics[width=\linewidth,height=8cm]{tikzimage.tikz}
    \end{tcolorbox}
    \begin{tcolorbox}[%
        height fill,
        remember height=\myheight,
        ]
        \includegraphics[width=\linewidth,height=\myheight]{tikzimage.tikz}
    \end{tcolorbox}
\end{document}

remeber height and tikz-external

Tobias
  • 928
  • I don't understand the relation between handle many plots and tikzexternalize because I can think another option. You can group all your plots inside a document with \documentclass[tikz]{standalone}. The result will be a pdf file with as many pages as plots, and each page cropped to plot dimensions. In your main file you can include plots with command \includegraphics[page=..., other options]{your-plots-file}, or into a tcolorbox-raster with \tcbincludepdf. http://tex.stackexchange.com/a/214787/1952, http://tex.stackexchange.com/a/99272/1952 – Ignasi Jan 27 '16 at 16:08
  • With standalone, it is not possible to scale the plots to the appropriate size which is given by the place where they are included. That means everythin has to be done by hand. I don't want to spend much time for that when latex can do it for me. \usepackage{tikzscale} can do that. – Tobias Jan 28 '16 at 15:04
  • No, you can not scale the plots, but you can make them all equal and scale the result with width and height \includegraphics options. Although in this case text is also scaled. – Ignasi Jan 28 '16 at 15:35
  • " ... text is also scaled." -- Yes, thats the thing that I don't have with tikzscale with externalize that automates most of the work. – Tobias Jan 28 '16 at 17:05

2 Answers2

3

I found the solution:

We have to use the mechanism of remember height for the first plot, too. This seems to help tikz-external.

Set the height of the first plot as option of \begin{tcolorbox} by height=10cm and remember it with remember height=\myheightONE, and use it to set the height of the plot with height=\myheightONE.

This seems to work without \tikzset{external/optimize=false}.

\documentclass{article}
\usepackage[breakable]{tcolorbox}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\usetikzlibrary{external}
%\tikzset{external/optimize=false}
\tikzexternalize           %%%%%%% problem here %%%%%%%%
\usepackage{tikzscale}
\begin{filecontents}{tikzimage.tikz}
  \begin{tikzpicture}
    \begin{axis}[xlabel=time,ylabel=value]
      \addplot{x^2};
    \end{axis}
  \end{tikzpicture}
\end{filecontents}
\makeatletter
\tcbset{%
  remember height/.style={%
    before upper={%
      \iftcb@fixedheight
        \tcbdimto#1{\kvtcb@top@rule@stand+\kvtcb@bottom@rule@stand+\kvtcb@boxsep*2+\kvtcb@top+\kvtcb@bottom}%
      \iftcb@hasTitle
        \tcbdimto#1{#1+\ht\tcb@titlebox+\dp\tcb@titlebox+\kvtcb@title@rule+\kvtcb@boxsep*2+\kvtcb@toptitle+\kvtcb@bottomtitle}%
      \fi
      \tcbdimto#1{\kvtcb@height@fixed-#1}%
      \else
        \tcbdimto#1{4cm}% fallback
      \fi
    },
  },
}
\makeatother
\begin{document}
\begin{tcolorbox}a\\a\\a\\a\\a\\a\\a\end{tcolorbox}
\begin{tcolorbox}[%
    height=10cm,                   %%%%%%%%%%%  NEW %%%%%%%%%%%%
    remember height=\myheightONE,  %%%%%%%%%%%  NEW %%%%%%%%%%%%
    ]
  \includegraphics[width=\linewidth,height=\myheightONE]{tikzimage.tikz} %% NEW %%
\end{tcolorbox}
\begin{tcolorbox}[%
  height fill,
  remember height=\myheightTWO,
  ]
  \includegraphics[width=\linewidth,height=\myheightTWO]{tikzimage.tikz}
\end{tcolorbox}
\end{document}

I hope my question did not exclude this solution that is nice for me?

Tobias
  • 928
0

The core problem is that tikzpicture environments are being optimized away, as can be seen by examining the log files.

From <jobname>-figure1.log:

(./tikzimage.tikz
A tikzpicture has been optimized away. Use '/tikz/external/optimize=false' to d
isable this.
) (./tikzimage.tikz) (./tikzimage.tikz) (./tikzimage.tikz) (./tikzimage.tikz
\openout6 = `<jobname>-figure1.dpth'.

This is essentially saying that it is throwing away the picture in an attempt to save compilation time and resources. Clearly not a good idea: we don't want it to be that flipping efficient. So, let's try taking the advice it offers about disabling the feature by adding

\tikzset{external/optimize=false}

to the preamble. The results are much improved although there is some remaining issue with the space required for the axis labels, it seems.

non-optimised

You could also disable optimisation more selectively e.g. only for particular pictures or only particular commands. Whether this is worth the additional effort will depend a great deal on your particular code. If you have a lot of tikzpicture environments, though, and most of them don't require this, it will save time to disable optimisation only for those pictures which require it. That said, the externalisation is still limiting the compilation time in total. Switching off optimisation is only, as far as I know, making compilation take longer when the picture must be compiled, which will not be the case on most runs if externalisation is enabled.

Complete code:

\documentclass{article}
\usepackage[breakable]{tcolorbox}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\usetikzlibrary{external}
\tikzexternalize           %%%%%%% problem here %%%%%%%%
\usepackage{tikzscale}
\begin{filecontents}{tikzimage.tikz}
  \begin{tikzpicture}
    \begin{axis}[xlabel=time,ylabel=value]
      \addplot{x^2};
    \end{axis}
  \end{tikzpicture}
\end{filecontents}
\makeatletter
\tcbset{%
  remember height/.style={%
    before upper={%
      \iftcb@fixedheight
        \tcbdimto#1{\kvtcb@top@rule@stand+\kvtcb@bottom@rule@stand+\kvtcb@boxsep*2+\kvtcb@top+\kvtcb@bottom}%
      \iftcb@hasTitle
        \tcbdimto#1{#1+\ht\tcb@titlebox+\dp\tcb@titlebox+\kvtcb@title@rule+\kvtcb@boxsep*2+\kvtcb@toptitle+\kvtcb@bottomtitle}%
      \fi
      \tcbdimto#1{\kvtcb@height@fixed-#1}%
      \else
        \tcbdimto#1{4cm}% fallback
      \fi
    },
  },
}
\makeatother
\tikzset{external/optimize=false}
\begin{document}
\begin{tcolorbox}a\\a\\a\end{tcolorbox}
\begin{tcolorbox}
  \includegraphics[width=\linewidth,height=8cm]{tikzimage.tikz}
\end{tcolorbox}
\begin{tcolorbox}[%
  height fill,
  remember height=\myheight,
  ]
  \includegraphics[width=\linewidth,height=\myheight]{tikzimage.tikz}
\end{tcolorbox}
\end{document}
cfr
  • 198,882
  • Feel free to take this code and create an answer which solves the remaining problem. If you do, ping me and I can delete this partial answer. – cfr Feb 01 '16 at 00:17
  • Thank you. This is already a good startingpoint. And since the error in height ist fixed in most cases, a work around can be generated. – Tobias Feb 02 '16 at 10:38
  • I was wrong. It does not work for me. Please test \includegraphics[width=\linewidth,height=4cm]{tikzimage.tikz} for the first plot. I do not understand the behaviour. – Tobias Feb 02 '16 at 10:57