# Calculate xtick positions by formula to mimic plotxx (or plotyy)

\begin{document}
\begin{tikzpicture}

\begin{axis}[%
/pgf/number format/1000 sep={}, % do not delimit per thousand
xmin=19,
xmax=22.5,
xlabel={angle in degree},
xtick pos=left, % bottom ticks
grid=none,
% FIXME: "extra x ticks" should be calculated from xstart, xinc, xend
% xstart=4500; xinc=-250; xend=4000;
% The x tick values below are calculated by: x=4250; asind(1500/x)
extra x ticks={22.02431, 20.66731, 19.47122}, % FIX ME
every extra x tick/.style={
xtick pos=right, % top ticks
xticklabel pos=right, % top tick labels
xticklabel={
\pgfmathparse{1500/sin(\tick)}
\pgfmathprintnumber{\pgfmathresult} m/s
},
xticklabel style={
/pgf/number format/.cd,fixed,fixed zerofill,precision=0,/tikz/.cd,
},
},
]
\end{axis}
\end{tikzpicture}

\end{document}


I plot data (here a linear function) that depends on the variable x, which is here an angle in degree. Now I would like to add a second x-axis on top. Pgfplots does not support this nicely as is discussed here in several other questions. I took the approach of defining extra x ticks and position them on the top.

There I would like to plot a velocity, that is linked to the angle by the formula v=asind(1500/angle). I know want to have velocities with an increment of 250 put on the top axis, e.g. 4500, 4250 and 4000. The line marked with FIX ME defines my issue: I would like to apply that formula to calculate the x-axis locations, that correspond to the velocities. The angle values of extra x ticks are taken in xticklabel and converted back to velocities. This is needed due to the nonlinear relationship of the two axis. A minor issue is that the precision of PGF is limited (4251 instead of 4250). I tried /pgf/fpu=true...

Hopefully I expressed my question clearly.

• I'm not sure I understand exactly what you're trying to do. Do you want to automate the position of the yticks instead of providing the list? In that case, you can simply say ytick=data instead of ytick={0,1,4,9,16,25}. – Jake Mar 20 '15 at 14:58
• @Jake, I clarified my question and adapted the example to make it easier to understand what I try to achieve. – Peter Pablo Mar 20 '15 at 15:05
• I still don't really understand what your aim is: in the example, you place y ticks at 0, 2, 4, 8, 16 and 24, but then you mention that you want to be able to provide \ystart, \yincrement and \yend, which sounds like you want to split the y axis in a linear fashion. Maybe it would be a good idea if you described the final result you want to get, and not the way you want to get there. – Jake Mar 20 '15 at 15:10
• Alright! I wanted to simplify the question but that really isn't working so well. Let me rephrase... – Peter Pablo Mar 20 '15 at 15:11
• @PeterPablo I updated my answer! – darthbith Mar 20 '15 at 15:56

The below is based on the answer of Claudio, here. We have to do some machinations with macros to get this to work, but we can define a new command that does the processing and sets macros for the ticks and the labels. pgfplots also doesn't like to have macros in label definitions in the plot (I don't remember why) so we have to use the \edef construct. This fixes the precision problem, since we don't have to do any computations to set the label.

The syntax of the \deflistticks is the same as for all pgf for loops: start element,second element,...,end element, where the difference between start element and second element sets the increment. You can also use an explicit list of all the coordinates.

The \deflisttick macro works by defining two global macros (\gdef), \extraticks and \listlabels. These global macros will contain the lists of ticks and labels, respectively, that we want to set. The first thing we do is find the number of items in the input list (#1 is the input). Then we loop through the list and do the computations on the passed in values; note that pgf operates in degrees by default. Then we fill our lists. If the element is the last one of the list, we don't append a comma.

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\newcommand{\deflisttick}[1]{
\gdef\extraticks{}
\gdef\listlabels{}
\foreach \x[count=\xi] in {#1}{\global\let\maxitems\xi}
\foreach \x[count=\xi] in {#1}{
\pgfmathsetmacro{\xy}{asin(1500/\x)}
\ifnum\xi=\maxitems
\xdef\extraticks{\extraticks \xy}
\xdef\listlabels{\listlabels \x\ m/s}
\else
\xdef\extraticks{\extraticks \xy,}
\xdef\listlabels{\listlabels \x\ m/s,}
\fi
}
}
\deflisttick{4000,4250,...,4500}
\edef\temp{%
\noexpand\pgfplotsset{%
extra x tick labels list/.style={xticklabels={\listlabels}}
}%
}
\temp
\begin{document}
\begin{tikzpicture}

\begin{axis}[%
/pgf/number format/1000 sep={}, % do not delimit per thousand
xmin=19,
xmax=22.5,
xlabel={angle in degree},
xtick pos=left, % bottom ticks
grid=none,
% FIXME: "extra x ticks" should be calculated from xstart, xinc, xend
% xstart=4500; xinc=-250; xend=4000;
% The x tick values below are calculated by: x=4250; asind(1500/x)
% extra x ticks={22.02431, 20.66731, 19.47122}, % FIX ME
extra x ticks={\extraticks},
every extra x tick/.style={
xtick pos=right, % top ticks
xticklabel pos=right, % top tick labels
extra x tick labels list,
},
]

• Unfortunately I am struggling with putting \ylistticks in extra x ticks. hmmm...: Dimension too large. --- wait... Got it! Will adapt the answer soon. Some polishing to do. – Peter Pablo Mar 20 '15 at 15:48