Построение ИК-спектра с помощью Gnuplot

У меня есть инфракрасный спектр интересующего соединения, которое я хотел бы построить, и у меня есть файл Spectrum.dat со всеми точками данных. Он имеет вид:

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

Я хотел бы изобразить это, используя ось x, типичную для ИК-спектров, но у меня возникают проблемы с этим. Если вы не знакомы, это может быть типичный ИК-спектр. выглядит как (кроме меток на самом графике). Обратите внимание, что ось x перевернута, и что она резко удваивает масштаб, превышающий 2000 единиц (обратные сантиметры). Есть ли способ заставить Gnuplot отображать мои данные таким образом? Мне пока удалось придумать следующий сценарий:

    # 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

Это красиво меняет ось x, но я не могу понять, как изменить масштаб таким необычным способом.


person ChemWes    schedule 21.05.2014    source источник
comment
См. Также gnuplot: как установить собственные нелинейные шкалы если вы используете set link, и вам подойдет разрабатываемая версия gnuplot. В следующей грядущей версии gnuplot 5.0 теперь даже есть релиз-кандидат :)   -  person Christoph    schedule 21.05.2014


Ответы (2)


Ответ Andyras хороший, это, возможно, более простое (более элегантное :-P) решение с точки зрения параметров макета. Это также должно быть более универсальное решение. Если тиков не слишком много (читайте под рисунком, если их слишком много), то это можно сделать, масштабируя саму кривую за пределы 2000, а затем добавляя все тики вручную. Поскольку у меня нет доступных данных по ИК-спектру, я воспользуюсь фиктивным файлом «+» и построю log(x) от 4000 до 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

введите описание изображения здесь

В вашем случае вы просто замените log($1) на 2 или что-то еще, что вы замышляете.

В более новых версиях gnuplot (начиная с 4.4) добавление тиков может выполняться автоматически с помощью цикла:

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))

Начиная с gnuplot 4.6 также можно создать другую for конструкцию с помощью do for:

do for [i=xmin:xmax-step:step] {set xtics add (sprintf("%i",i) rescale(i))}
person Miguel    schedule 21.05.2014
comment
Хороший ответ, единственное изменение, которое я мог бы сделать, - это определить pivot=2000; rescale(x) = ($1 >= pivot ? $1 : pivot + 2.*($1-pivot)), чтобы вы могли вызывать функцию для всех величин. - person andyras; 21.05.2014
comment
@andyras Изменено, я также добавил коэффициент масштабирования. Как ни странно, сегодня мне нужно было использовать это решение на работе для чего-то совершенно несвязанного ... - person Miguel; 21.05.2014
comment
Если вы измените итерацию для xtics на использование set for, он также будет работать с версией 4.4: set for [i=xmin:xmax-step:step] xtics add (sprintf("%i",i) rescale(i)). В версии 4.6 появилась только конструкция do for. - person Christoph; 22.05.2014

Я как химик мотивирован ответить ...

Насколько я знаю, gnuplot не позволяет легко произвольно масштабировать оси (если только у кого-то нет ярких идей о том, как использовать set link). Моя стратегия в такой ситуации состоит в том, чтобы построить две половинки отдельно и соединить их плавно:

#!/usr/bin/env gnuplot

set terminal png size 800,500
set output 'ir.png'

set xlabel 'Wavenumbers' offset 20
set ylabel 'Transmittance'

set tics out nomirror

set key bottom right

set bmargin 4

set yrange [0:1]

set multiplot layout 1,2 title 'IR Spectrum of Cholesterol'

# left half of plot
set xrange [4000:2000]
set rmargin 0
set border 7
plot 'cholesterol.txt' notitle

# right half of plot
set xrange [1999:300]
set lmargin 0
set rmargin 2
set border 13

unset xlabel
unset ylabel
unset ytics

plot 'cholesterol.txt' title 'Cholesterol'

unset multiplot

Моя единственная придирка заключается в том, что 2000 написано дважды и выглядит смелее на моем экране, но я оставлю вам возиться с тиками.

введите описание изображения здесь

person andyras    schedule 21.05.2014