6

Follow-up to pgfplots: multiple loops for ticks, positioning, etc (and Passing a macro to an environment option (TikZ/pgfplots)), but there may be a LateX-only solution. I suppose there is a trivial solution with a loop in Lua, but I would prefer something that compiles with PdfLateX.

See the first linked question for working code, but the relevant snippet I would like to make work is:

\newcommand{\myxlist}{1,2,3,5} % The list of values should be hardcoded only once
\newcommand{\myylist}{\dosomethingon\myxlist} % <--- how to do this?
\begin{axis}
[xtick/.expanded=\myxlist,
ytick/.expanded=\myylist, % desired result: ytick={f(x1),f(x2)..f(xn)}
...]
\addplot[...]{sqrt(x)}; % not the actual f, but almost
\end{axis}

In English:

I want to plot a (simple) function f(x) and have ticks for a few given points on the function, based on the x-positions x1,x2...xn, and I want pgf to calculate the corresponding values of f on those points to make the y-ticks.

I can retype the function multiple times in the source code, it will not change and there is little risk of error. However I want to try different x1,x2,...xn lists, and I wish not to have to pre-compute them each time I change my mind about which one will be used.

EDIT: full document per request:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots} 

\begin{document}

    \begin{tikzpicture}
    \newcommand{\myxlist}{1,2,3,5}
    \begin{axis}[
    xmin=0,xmax=10,
    ymin=0,ymax=4,
    xtick/.expanded=\myxlist,
    ytick={1,1.4142136,1.7320508,2.236068} % how to compute this?
    ]

    \addplot+[domain=0:10,samples=100,no markers]{sqrt(x)};

    \end{axis}

    \end{tikzpicture}

\end{document}
  • Would you mind to provide a complete document? – gernot says Reinstate Monica Oct 14 '16 at 16:59
  • Perhaps a \foreach command before the axis environment iterating trough the \myxList, calculating the results and appending to a pgfkey (I'm on the phone, therefore cannot go further than a comment) – Guilherme Zanotelli Oct 14 '16 at 17:05
3

Besides the solution suggested by Guilherme Z. Santos you could also add an invisible plot together with xtick=data and ytick=data.

Of course it only has to be invisible when you want to plot another function/stuff that isn't related to the ticks. Here I plot another function to demonstrate that the invisible plot really is invisible and not hidden behind the second \addplot.

\documentclass[border=2pt]{standalone}
\usepackage{pgfplots}
    \pgfplotsset{
        % declare the function you want to plot so you can reuse it easily later
        /pgf/declare function={
            f(\x)=sqrt(\x));
        },
        % define style to use for the plot to draw only ticks at `\myxlist'
        % (the plot should be invisible)
        my ticks/.style={
            samples at={\myxlist},
            mark=none,
            draw=none,
%            only marks,     % <-- uncomment me to show the data points
        },
    }
\begin{document}
    \begin{tikzpicture}
            \newcommand{\myxlist}{1,2,3,5}
        \begin{axis}[
            xmin=0,xmax=10,
            ymin=0,ymax=4,
            % use `data' as value for `xtick' and `ytick' to draw ticks
            % at the data points of the *first* plot,
            % which is our invisible plot
            xtick=data,
            ytick=data,
            %
            domain=0:10,
            samples=100,
            no markers,
        ]
            % as mentioned above place first the invisible plot by applying
            % the above defined style
            \addplot  [my ticks]    {f(x)};
            % then you can plot whatever you want
            \addplot                {2*f(x)};

            \legend{
                ,           % use empty entry to hide the invisible plot
                $2f(x)$,
            }
        \end{axis}
    \end{tikzpicture}
\end{document}

image showing the result of above code

  • OK, I accepted that and copied happily, but my main document failed to compile. Half an hour of package trimming later, I see \usepackage[french]{babel} (!) in the preambule makes the code above fail with a Runaway argument error. If I manage to solve that, I will post the solution, otherwise I will post the link to the next post. – JM114516 Oct 17 '16 at 14:23
  • I know from the bug tracker that sometimes French causes problems. Please try, if adding \usetikzlibrary{babel} after loading PGFPlots helps. – Stefan Pinnow Oct 17 '16 at 14:47
  • (edit conflict) tex.stackexchange.com/questions/86023/… says it all. Basically, fr babel redefines ';' as a macro and this makes declare function={...;} fail because pgf's parser. Being the one guy out of a million that needs pgfplots with french (with ';' catcode issues) on beamer (which handles in-frame catcodes strangely), the workarounds need the fragile frame option. – JM114516 Oct 17 '16 at 14:54
0

Here is a way, but it is somewhat limited as currently xintexpr coverage of math functions beyond algebra is limited to the square root.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots} 

\usepackage{xintexpr}

\begin{document}

    \begin{tikzpicture}
    \newcommand{\myxlist}{1,2,3,5}
    \begin{axis}[
    xmin=0,xmax=10,
    ymin=0,ymax=4,
    xtick/.expanded=\myxlist,
    ytick/.expanded={\xintthefloatexpr seq(sqrt(x), x=\myxlist)\relax},
    ]

    \addplot+[domain=0:10,samples=100,no markers]{sqrt(x)};

    \end{axis}

    \end{tikzpicture}

\end{document}

I use /.expanded as guess work as I am not familiar with TikZ keys, and I needed to add braces, but then all went well.

enter image description here

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.