# How to have linked axes on plots?

I plot infrared spectra in many reports and I display the energy units in two ways, wavenumbers $cm^{-1}$ on the bottom x-axis and wavelength (nm) on the upper x-axis. The relationship is X(nm)=1e7/Y(cm^{-1}).

for example a spectra running from 4000$cm^{-1}$-400$cm^{-1}$ on the bottom x-axis (a linear scale) corresponds to a wavelength range of 2500nm - 25,000nm a non-linear scale. Is there a way to have this done in pgf, tikz etc? I use Origin to do this and then export as pdf and use \includegraphics{linked-axis-plot.pdf}

## 1 Answer

You could use PGFplots for this. To get a second x-axis, you have to overlay the original plot with a second one of equal dimension that contains only the secondary axis. I've written a style called master axis that calculates and saves the equivalent horizontal dimensions needed for the secondary axis, which in turn uses the style secondary axis to read and set the dimensions.

\documentclass{article}
\usepackage{pgfplots}
\usepackage{siunitx} % For typesetting of units

\pgfplotsset{compat=newest}
\pgfkeys{/pgfplots/.cd,master axis/.style={
scale only axis,
enlarge x limits=false,
x dir=reverse,axis x line*=bottom,
xticklabel shift=3pt,
after end axis/.code={
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
\pgfmathparse{\pgfkeysvalueof{/pgfplots/xmin}}
\global\let\masterxmin=\pgfmathresult
\pgfmathparse{\pgfkeysvalueof{/pgfplots/xmax}}
\global\let\masterxmax=\pgfmathresult
\pgfkeys{/pgf/fpu=false}
}
},
slave axis/.style={
scale only axis,enlarge x limits=false,
x dir=reverse,
axis x line*=top,
axis y line=none,
xmin=\masterxmin,xmax=\masterxmax,ymin=0,ymax=1,
scaled x ticks=false,
xtick={100,400,1000,2000,4000,10000},
xticklabel={
\pgfkeys{/pgf/fpu}
\pgfmathparse{1e7/\tick}
\pgfmathprintnumber{\pgfmathresult}
}
}
}
\begin{document}
\begin{tikzpicture}

\begin{axis}[master axis,
ymin=0,ymax=100,
xmin=400,xmax=4000,
enlarge x limits=false, yticklabel={\SI[round-mode=places,round-precision=0]{\tick}{\percent}}, xlabel=Wavenumber / \si{\per\centi\metre},
ylabel=Transmissivity
]
\addplot[domain=400:4000,samples=100,thick]{-(abs(tan(x/10))-2*rnd)+90};
\end{axis}

\begin{axis}[slave axis,xlabel=Wavelength / \si{\nano\metre}]\end{axis}

\end{tikzpicture}
\end{document}

• @Jake: The image you have put up is what I am looking for unfortunately when I cut and paste the above code into my editor and run it (MiKTeX2.9, Texmaker) I get a series of errors (101 of them, all based on line 44 and 45 of the above code) mainly pgfplots errors etc. Did you have these errors? eg ! Paragraph ended before \pgfmathfloatparse@@ was complete. <to be read again> \par l.44 – Leeser May 24 '11 at 13:06
• @Jake: The errors disappeared when I use an explicit x-range in the slave axis. \begin{axis}[slave axis,xmin=\masterxmin,xmax=\masterxmax,ymin=0,ymax=1, xlabel=Wavelength / \si{\nano\metre}]\end{axis} so thanks for your help and I have accepted the answer – Leeser May 26 '11 at 11:07
• With the current version of pgfplots (1.5.1) this now also works without providing xmin and xmax explicitly. – Jake May 30 '12 at 10:57