Как можно отобразить данные записанные в файл в gnuplot
Есть файл вот такого типа :
1 14 16 17 15 16 15 14 15 14 15 16 16 14 15 16 15 16 15 15 16 14 15 17 17 16 16 16 16 16 16 16 17 16
14 15 15 14 14 15 15 14 15 17 15 16 16 16 16 15 16 15 15 16 16 14 15 14 17 15 13 15 15
2 15 15 17 15 16 15 14 15 14 15 16 16 14 15 16 15 16 15 15 16 14 14 17 17 16 17 17 16 15 16 16 17 15
15 15 15 14 14 15 15 14 15 17 15 16 15 17 16 15 15 16 15 16 16 14 15 14 17 14 14 14 15
Хочу отобразить данные. Пишу в gniplot 'plot "data_1.log" using 1:2 w l, "data_1.log" using 1:3 w l' данные отражает все хорошо. Но очень не удобно для каждого столбца писать 'using 1:2 w l, using 1:3 w l, using 1:4 w l' можно как то написать команду чтобы сразу все столбцы отобразились в виде графиков с разными цветами?
Ответы (1 шт):
Мне не совсем понятен входной формат данных: в приведенном фрагменте не все строки имеют одинаковую длину. Но это, наверное, не очень важно в данном случае.
В последних версиях Gnuplot (не помню точно начиная с которой) можно использовать конструкции типа циклов. Я проверял на версии 5.2 patchlevel 8.
Как простейший вариант можно использовать, например, такую конструкцию:
plot for [i = 2:20] 'data_1.log' using 1:i with lines
В результате, будут построены кривые по первым 20 столбцам (первый столбец будет отвечать за координату x (абсциссу для графика)). У этого варианта есть несколько недостатков:
- мы не знаем, что именно он нарисовал (невнятная легенда);
- цвета линий будут такие, какие он сам (gnuplot) захочет, и не факт, что они не будут повторяться;
- нужно вручную указывать точное количество столбцов (в приведенном примере 20).
Поэтому дальше будем усложнять конструкцию. По примеру из справки мы можем задать через тот же цикл for стили линий:
set for [i = 2:20] style line i lc rgb sprintf("#00%02x%02x",255-10*i, 10*i)
Я здесь задал 19 стилей для линий с номерами от 2 до 20 с зелено-синей палитрой. Можно сделать и больше, если нужно. Это просто для примера. Главное: здесь использована цветовая схема rgb, аргумент (т.е. сам цвет) должен задаваться в виде строки с шестнадцатеричными цифрами, по две цифирки на цвет, а в начале строки идет знак 'диез'. В итоге, в такой строке с цветом должно быть что-то типа: "#FF5CFA". Я использовал функцию для формирования строки sprintf() (которая есть и в языке Си) для формирования строк, задающих цвет. А по какой формуле задавать цвет - это уже дело вкуса.
С легендой можно поступить таким же способом, как и с формированием цветовой палитры, а именно, использовать функцию sprintf().
Ну и осталось только что-то сделать, чтобы не нужно было руками вводить точное число столбцов. Тут нам могут помочь: 1) функция column(N), которая позволяет использовать в сложных выражениях номер столбца (т.е. чтобы номер столбца не был принят гнуплотом за содержимое столбца или просто за какое-то отдельное число); 2) функция valid(N), которая проверяет "правильное" (рисовабельное) содержимое столбца. В итоге получим вот такой кошмар :) (привожу сразу все содержимое скрипта):
reset
set for [i = 1:255] style line i lc rgb sprintf("#00%02x%02x",255-i, i)
plot for [i = 2:200] 'data_1.log' using 1:(valid(i) ? column(i) : 1/0) with lines title sprintf("line %d",i) ls i lw 1.5
Ну и еще несколько слов про этот код и про тернарный оператор, в частности. Я в тернарном операторе использовал выражение 1/0, чтобы сказать гнуплоту, что это не нужно пытаться рисовать (такую конструкцию он понимает; еще, здесь можно было бы использовать NaN). Иначе, он бы начал сыпать ошибки, пытаясь нарисовать несуществующие столбцы.
К сожалению, мне пока не приходит в голову другой способ нарисовать все столбцы из файла (предполагается, что 200 - это максимальное число столбцов, которое может встретиться в файлах, и естественно, здесь можно указать свое число).