Search code examples
plotgnuplotspectruminfraredchemistry

Plotting an IR Spectrum with Gnuplot


I have an infrared spectrum for a compound of interest that I would like to plot, and I have a spectrum.dat file with all of the data points. It is of the form:

    # X  Y     
    300  100
    301  100
    302   99
    303   70
    ...
    3999  98
    4000 100

I would like to plot this using an x axis typical of IR spectra, but I am having trouble doing so. If you are unfamiliar, this is what a typical IR spectrum might look like (aside from the labels on the graph itself). Notice that the x-axis is reversed, and that it abruptly doubles its scaling above 2000 units (reciprocal centimeters). Is there a way to coerce Gnuplot into plotting my data this way? I so far have managed to come up with the following script:

    # Make an SVG of size 800x500
    set terminal svg size 800,500 fname 'CMU Sans Serif' fsize '10'
    set output 'ir.svg'
    # Color definitions
    set border linewidth 1.5
    set style line 1 lc rgb '#a0a0a0' lt 1 lw 2 pt 7 # gray
    # Format graph
    unset key
    set xlabel 'Wavenumbers'
    set ylabel 'Transmittance'
    set xrange [4000:300]
    # Plot data
    plot 'spectrum.dat' with lines ls 1

This reverses the x-axis nicely, but I can't figure out how to change the scaling in such an unusual way.


Solution

  • andyras' answer is a nice one, this is an arguably simpler (more elegant :-P) solution in terms of layout options. This should also be a more universal solution. If there are not too many tics (read below the figure if there are too many), then this could be done scaling the curve itself beyond 2000, and then adding all the tics by hand. Since I don't have IR spectrum data available I will use the dummy file "+" and plot log(x) from 4000 to 500:

    xmax=4000 ; xmin = 500
    pivot = 2000 ; rescfactor = 2.
    rescale(x) = (x >= pivot ? x : pivot + rescfactor*(x-pivot))
    set xrange [rescale(xmax):rescale(xmin)]
    set xtics ("4000" 4000, "3000" 3000, "2000" 2000, \
    "1500" rescale(1500), "1000" rescale(1000), "500" rescale(500))
    plot "+" u (rescale($1)):(log($1)) w l
    

    enter image description here

    In your case you just substitute log($1) by 2 or whatever you're plotting.

    In newer versions of gnuplot (starting from 4.4) adding the tics can be done automatically using a loop:

    xmax = 4000 ; xmin = 500 ; step = 500
    set xtics (sprintf("%i",xmax) rescale(xmax)) # Add the first tic by hand
    set for [i=xmin:xmax-step:step] xtics add (sprintf("%i",i) rescale(i))
    

    Starting from gnuplot 4.6 also a different for construction can be made using do for:

    do for [i=xmin:xmax-step:step] {set xtics add (sprintf("%i",i) rescale(i))}