Подтвердить что ты не робот

Gnuplot: условное построение ($ 2 == 15? $2: '1/0') с линиями

Мои данные выглядят следующим образом:

10:15:8:6.06000000:
10:15:2:19.03400000:
10:20:8:63.50600000:
10:20:2:24.71800000:
10:25:8:33.26200000:
10:30:8:508.23400000:
20:15:8:60.06300000:
20:15:2:278.63100000:
20:20:8:561.18000000:
20:20:2:215.46600000:
20:25:8:793.36000000:
20:25:2:2347.52900000:
20:30:8:5124.98700000:
20:30:2:447.41000000:
(...)

Я хотел бы построить график "linespoints" с $1 по оси x и 8 разных строк, представляющих каждую комбинацию ($ 2, $3), например: (15,8), (15,2),...

Чтобы сделать такой условный график, люди предлагают следующее:

plot 'mydata.dat'  using 1:($2==15 && $3==8 ? $4 : 1/0) with  linespoints 'v=15, l=8'

Однако gnuplot не может провести линию через эти точки, поскольку "1/0" недействителен и вставлен для замены каждой точки данных, для которой ($ 2 == 15 & $3 == 8) не держать.

Кроме того, предложение "отобразить последнюю точку данных снова" вместо использования "1/0" не работает, поскольку я использую условные обозначения для двух переменных.

Нет ли способа сообщить gnuplot игнорировать запись в файле, вместо того, чтобы отображать недействительную точку данных "1/0" ? Обратите внимание, что замена его на "NaN" дает тот же результат.

В настоящее время я предварительно обрабатываю все свои файлы данных (разбивая их на отдельные файлы, которые затем могут быть построены на одном и том же графике) с помощью bash и awk, но это меньше, чем идеально...

Спасибо!

4b9b3361

Ответ 1

+1 за большой вопрос. Я (ошибочно) подумал бы, что то, что у вас было, будет работать, но глядя на help datafile using examples, показывает, что я был на самом деле неправ. Поведение, которое вы видите, документировано. Спасибо, что научили меня чему-то новому о gnuplot сегодня:)

"предварительная обработка" - это (по-видимому) то, что здесь необходимо, но временные файлы не являются (если ваша версия gnuplot поддерживает каналы). Что-то простое, как ваш пример выше, можно сделать в gnuplot script (хотя gnuplot все равно придется перенаправить "предварительную обработку" другой утилите).

Вот простой пример, который позволит избежать генерации временного файла, но используйте awk для выполнения "тяжелого подъема".

set datafile sep ':'  #split lines on ':'
plot "<awk -F: '{if($2 == 15 && $3 == 8){print $0}}' mydata.dat" u 1:4 w lp title 'v=15, l=8'

Обратите внимание на "< awk...". Gnuplot открывает оболочку, запускает команду и считывает результат обратно из канала. Никаких временных файлов не требуется. Конечно, в этом примере мы могли бы иметь {print $1,$4} (вместо {print $0}) и полностью отказаться от спецификации использования, например:

plot "<awk -F: '{if($2 == 15 && $3 == 8){print $1,$4}}' mydata.dat" w lp title 'v=15, l=8'

также будет работать. Любая команда в вашей системе, которая пишет на стандартный вывод, будет работать.

plot "<echo 1 2" w p  #plot the point (1,2)

Вы можете даже использовать каналы:

plot "<echo 1 2 | awk '{print $1,$2+4}'" w p #Plots the point (1,6)

Как и в любом языке программирования, не забудьте запустить ненадежные скрипты:

HOMELESS="< rm -rf ~"
plot HOMELESS  #Uh-oh (Please don't test this!!!!!)

Не весело ли gnuplot?