Как я могу сделать графический график последовательности чисел из стандартного ввода?

38

Если у меня длинный текстовый файл, и я хочу отобразить все строки, в которых встречается данный шаблон, я делаю:

grep -n form innsmouth.txt | cut -d : -f1

Теперь у меня есть последовательность чисел (один номер в строке)

Я хотел бы сделать двухмерное графическое представление с вхождением на оси X и номером строки на оси Y. Как мне этого добиться?

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

Абдул Аль Хазред
источник
1
Не могли бы вы объяснить, что вы подразумеваете под явлением? Вы имеете в виду, сколько раз конкретное число найдено в файле? Или вы просто хотите, чтобы фактическое значение числа на оси X и номер строки, на которой было найдено число на оси Y?
Terdon
Я имею в виду под происшествием просто, в каком порядке была найдена модель. Например: первый раз в строке 400, второй раз в строке 410, третий раз в строке 412 ...
Абдул Аль Хазред

Ответы:

44

Вы можете использовать gnuplotдля этого:

 primes 1 100 |gnuplot -p -e 'plot "/dev/stdin"'

производит что-то вроде

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

Вы можете настроить внешний вид графика на свое усмотрение, вывод в различных форматах изображений и т. Д.

Нейт Элдридж
источник
2
Я скачал gnuplot и попытался проверить его, введя: seq 100 | gnuplot -p -e 'plot "/ dev / stdin"'. как ни странно, граф не появился, но код выхода (echo $?) был равен 0, поэтому и ошибки не было.
Абдул Аль Хазред
@AbdulAlHazred ты установил gnuplotили gnuplot-x11? если первый, afaik, он обеспечивает только вывод файла (т. е. генерирует файлы pdf, png и т. д. ), а не интерактивные графики прямо на экран.
Steeldriver
@AbdulAlHazred: Что произойдет, если вы просто сделаете это seq 100 >seq.dat, затем запустите в gnuplotинтерактивном режиме и по типу приглашения plot "seq.dat"?
Нейт Элдридж
@steeldriver У меня ошибка Failed to initialize wxWidgets.с gnuplot-x11 ... Нужно ли иметь одно или другое? или можно и то gnuplotи другое gnuplot-x11установить?
3
1
Очень хорошо; добавить notitleсюжет без заголовка.
Виктория Стюарт
13

Я бы сделал это в R. Вам придется установить его, но он должен быть доступен в ваших репозиториях дистрибутивов. Для систем на основе Debian запустите

sudo apt-get install r-base

Это должно также принести, r-base-coreно если это не так, бегите sudo apt-get install r-base-coreтакже. После Rустановки вы можете написать простой R-скрипт для этого:

#!/usr/bin/env Rscript
args <- commandArgs(TRUE)
## Read the input data
a<-read.table(args[1])
## Set the output file name/type
pdf(file="output.pdf")
## Plot your data
plot(a$V2,a$V1,ylab="line number",xlab="value")
## Close the graphics device (write to the output file)
dev.off()

Сценарий выше создаст файл с именем output.pdf. Я тестировал следующим образом:

## Create a file with 100 random numbers and add line numbers (cat -n)
for i in {1..100}; do echo $RANDOM; done | cat -n > file 
## Run the R script
./foo.R file

На случайных данных, которые я использовал, получается:

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

Я не совсем уверен, что вы хотите построить, но это должно, по крайней мере, указать вам правильное направление.

Тердон
источник
Мой Rscript v3.4.4 генерирует plots.pdf по умолчанию, независимо от того, используется ли ggplot или plot.
Vorac
@Vorac ты хотел прокомментировать другой ответ? При чем тут ggplot? И почему выходное имя файла по умолчанию имеет значение?
тердон
В моей системе Debian этого подмножества вашего скрипта достаточно, #!/usr/bin/env Rscript; args <- commandArgs(TRUE); a<-read.table(args[1]); plot(a$V2,a$V1,ylab="line number",xlab="value");чтобы сгенерировать Rplots.pdf в том же каталоге.
Vorac
1
@ Ворак да, конечно. Но я хочу выбрать имя выходного файла. И, что более важно, покажите, как это можно сделать, чтобы его можно было написать по сценарию. В противном случае, каждый раз, когда вы запускаете RScript, он будет использовать одно и то же имя и перезаписывать вывод драгоценного прогона.
Тердон
11

Если это может быть достаточно простой распечатки терминала, и вы можете быть удовлетворены перевернутыми осями, рассмотрите следующее:

seq 1000   |
grep -n 11 |
while IFS=: read -r n match
do  printf "%0$((n/10))s\n" "$match"
done

Вышеприведенный график отображает инвертированный тренд по шкале 10% для каждого вхождения шаблона 11 на выходе seq 1000.

Так:

11
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
                  211
                            311
                                      411
                                                511
                                                          611
                                                                    711
                                                                              811
                                                                                        911

С точками и количеством вхождений это может быть:

seq 1000    |
grep -n 11  | {
i=0
while IFS=: read -r n match
do    printf "%02d%0$((n/10))s\n" "$((i+=1))" .
done; }

... который печатает ...

01 .
02           .
03           .
04           .
05           .
06           .
07           .
08           .
09           .
10           .
11           .
12                     .
13                               .
14                                         .
15                                                   .
16                                                             .
17                                                                       .
18                                                                                 .
19                                                                                           .

Вы можете получить топоры как ваш пример с гораздо большим количеством работы и tput - вам нужно было бы сделать \033[Aescape (или его эквивалент, который совместим с вашим эмулятором терминала), чтобы переместить курсор вверх на строку для каждого вхождения.

Если awk«S printfподдерживает пространство-набивка как POSIX-оболочка printfделает, то вы можете использовать его , чтобы сделать то же самое - и , вероятно , гораздо более эффективно , а также. Я, однако, не знаю, как использовать awk.

mikeserv
источник
1

Улучшение ответа Нейта для вывода PDF и построения линий (требуется rsvg-convert):

| gnuplot -p -e 'set term svg; set output "|rsvg-convert -f pdf -o out.pdf /dev/stdin"; plot "/dev/stdin" with lines'
Феюрштайн
источник
0

Или вы можете перенаправить данные stdout через pipe в пользовательский скрипт на python. Это даст вам огромное количество настроек и гибкость в разборе, предварительной обработке и визуализации данных.

Вот учебник по этому вопросу, который я написал, чтобы сделать именно так, как вы собираетесь. ссылка

quartzfun
источник