Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}

share|improve this question
add comment

1 Answer

up vote 9 down vote accepted

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}
share|improve this answer
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 May 24 '11 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 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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.