2

I'm using TikZ's data visualization feature to create a figure. This is working fine, up to the point where I add pins and/or labels to the figure; doing so creates a large amount of whitespace between the figure proper and its caption. The following is an MWE:

%!TEX TS-program = xelatex
\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{datavisualization}
\usetikzlibrary{datavisualization.formats.functions}

\begin{document}
    \begin{figure}[h!]
        \centering%
        \caption{Pareto frontier of risky investments}%
        \begin{tikzpicture}[scale=2.5]
            \datavisualization [
                scientific axes = clean
            ]
            [
                visualize as line/.list = { pareto, tangent },
                visualize as scatter/.list = { investments, portfolios },
                y axis = { 
                    label     = { $\mu$ [\%] },
                    attribute = M,
                    min value = 0,
                    max value = 25
                },
                x axis = { 
                    label     = { $\sigma$ [\%]}, 
                    attribute = S,
                    min value = 0,
                    max value = 70
                },
                pareto = {
                    label in data = {
                        when = S is 19,
                        text = Natasha Fund
                    },
                    label in data = {
                        when = S is 60,
                        text = Hannah Corporation
                    }
                },
                tangent = {
                    style = dashed,
                },
                investments  = {
                    pin in data = {
                        when = S is 0,
                        text = risk-free investment
                    }
                },
                portfolios = {
                    pin in data = {
                        when = S is 18.29379,
                        text' = $P^\star$
                    },
                }
            ]
            data [set = pareto, format = function] {
                var  t : interval [0:1] samples 1000;
                func M = 15 + 5*\value{t};
                func S = sqrt(3961*\value{t}^2 - 722*\value{t} + 361);
            }
            data [set = tangent, headline = {S, M}] {
                0, 3.2
                32.09828, 25
            }
            data [set = investments, headline = {S, M}] {
                0, 3.2
                19, 15
                60, 20
            }
            data [set = portfolios, headline = {S, M}] {
                18.29379, 15.62466
            }
            ;
        \end{tikzpicture}%
    \end{figure}
\end{document}

This produces:

MWE: extra whitespace in the presence of pins / labels in data

Commenting out the pins / labels gives the intended result:

MWE: no extra whitespace once pins / labels in data are removed

Looking for similar questions, I found Wide space between picture and caption, but no solution. I'm stuck, and would appreciate any help, tips, pointers, or suggestions. Thanks!

Addendum: in case it might be relevant, I'm using MiKTeX 2.9 on Windows. I've updated MiKTex to make sure the issue's not caused by outdated packages, to no avail.

  • Losing the [scale=2.5] fixes the white space, but then the lables are way too big. – John Kormylo Aug 25 '18 at 15:13
  • @JohnKormylo Thanks, that's an interesting observation. [scale=1.5] looks reasonable, both in terms of label placement and whitespace, so I might just run with that. Would still be nice to get to the bottom of this, however. – chsk Aug 25 '18 at 15:39
  • It is probably a bug. Most people use pgfplots. Also, \scalebox and \resizebox do not change the relative sizes of text and picture. – John Kormylo Aug 25 '18 at 15:44
  • Another problem: if you place the tikzpicture inside another box, it generates an odd error about trying to parse 3.2 32.09828 .as a floating point number (when they are actually two numbers on different lines). – John Kormylo Aug 25 '18 at 15:57
2

I think I'd suggest using the scaling features of the datavisualization library, rather than using scale directly. That is, add for example

x axis={length=12cm},
y axis={length=7cm}

to the \datavisualization options, to set the size of the axis. I did have to modify the pins a bit though, see comments in the code.

There are other methods as well:

  • scientific axes = {clean,width=12cm,height=7cm} (width and height are attributes of scientific axis).
  • x axis={unit length=1cm per 10 units} and similar for y axis. I.e. set the length that should be used by a given number of unit lengths.
  • Might be others. I don't really know the library that well, scrolling through the manual might lead to more options.

enter image description here

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{datavisualization}
\usetikzlibrary{datavisualization.formats.functions}

\begin{document}
    \begin{figure}[h!]
       \centering%
        \caption{Pareto frontier of risky investments}%
        \begin{tikzpicture}%[scale=2.5]
            \datavisualization [
                scientific axes = clean,
                x axis={length=12cm},
                y axis={length=7cm}
            ]
            [
                visualize as line/.list = { pareto, tangent },
                visualize as scatter/.list = { investments, portfolios },
                y axis = { 
                    label     = { $\mu$ [\%] },
                    attribute = M,
                    min value = 0,
                    max value = 25
                },
                x axis = { 
                    label     = { $\sigma$ [\%]}, 
                    attribute = S,
                    min value = 0,
                    max value = 70
                },
                pareto = {
                    label in data = {
                        when = S is 19,
                        text' = Natasha Fund % changed from text to text'
                    },
                    label in data = {
                        when = S is 60,
                        text = Hannah Corporation
                    }
                },
                tangent = {
                    style = dashed,
                },
                investments  = {
                    pin in data = {
                        when = S is 0,
                        text = risk-free investment,
                        node style={right} % added
                    }
                },
                portfolios = {
                    pin in data = {
                        when = S is 18.29379,
                        text' = $P^\star$,
                        pin length = 1cm, % added
                        pin angle = -30 % added
                    },
                }
            ]
            data [set = pareto, format = function] {
                var  t : interval [0:1] samples 1000;
                func M = 15 + 5*\value{t};
                func S = sqrt(3961*\value{t}^2 - 722*\value{t} + 361);
            }
            data [set = tangent, headline = {S, M}] {
                0, 3.2
                32.09828, 25
            }
            data [set = investments, headline = {S, M}] {
                0, 3.2
                19, 15
                60, 20
            }
            data [set = portfolios, headline = {S, M}] {
                18.29379, 15.62466
            }
            ;
        \end{tikzpicture}%
    \end{figure}
\end{document}
| improve this answer | |

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.