11

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 1

11

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.

IR plot with linked axes

\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}
3
  • 1
    @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
    Commented May 24, 2011 at 13:06
  • 1
    @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
    Commented May 26, 2011 at 11:07
  • With the current version of pgfplots (1.5.1) this now also works without providing xmin and xmax explicitly.
    – Jake
    Commented May 30, 2012 at 10:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .