Jak mogę utworzyć wykres graficzny sekwencji liczb ze standardowego wejścia?

38

Jeśli mam długi plik tekstowy i chcę wyświetlić wszystkie linie, w których występuje dany wzór, wykonuję:

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

Teraz mam sekwencję liczb (jedna liczba na linię)

Chciałbym wykonać graficzną reprezentację 2D z wystąpieniem na osi x i numerem linii na osi y. Jak mogę to osiągnąć?

wprowadź opis zdjęcia tutaj

Abdul Al Hazred
źródło
1
Czy możesz wyjaśnić, co masz na myśli mówiąc o wystąpieniu? Czy masz na myśli, ile razy konkretna liczba znajduje się w pliku? A może po prostu chcesz rzeczywistej wartości liczby na osi x i numeru linii, na której znaleziono liczbę na osi y?
terdon
Chodzi mi po prostu o to, w jakiej kolejności znaleziono wzór. np .: pierwszy raz w linii 400, drugi raz w linii 410, trzeci raz w linii 412 ...
Abdul Al Hazred

Odpowiedzi:

44

Możesz użyć gnuplotdo tego:

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

produkuje coś podobnego

wprowadź opis zdjęcia tutaj

Możesz skonfigurować wygląd wykresu według własnego uznania, wyświetlać go w różnych formatach graficznych itp.

Nate Eldredge
źródło
2
Pobrałem gnuplot i próbowałem go przetestować, wpisując: seq 100 | gnuplot -p -e 'plot' / dev / stdin ''. co dziwne, nie pojawił się wykres, ale kod wyjścia (echo $?) wynosił 0, więc nie pojawił się również błąd.
Abdul Al Hazred
@AbdulAlHazred zainstalowałeś gnuplotlub gnuplot-x11? jeśli ten pierwszy, afaik, zapewnia tylko wyjście pliku (tj. generowanie plików pdf, png itp. ), a nie interaktywne wykresy bezpośrednio na ekran.
steeldriver
@AbdulAlHazred: Co się stanie, jeśli po prostu to zrobisz seq 100 >seq.dat, a następnie uruchom gnuplotinteraktywnie i po wyświetleniu monitu plot "seq.dat"?
Nate Eldredge
@steeldriver Mam błąd związany Failed to initialize wxWidgets.z gnuplot-x11 ... Czy muszę mieć taki czy inny? lub może zarówno gnuploti gnuplot-x11być zainstalowane?
3kstc,
1
Bardzo dobrze; dołącz notitledo fabuły bez tytułu.
Victoria Stuart,
13

Zrobiłbym to w R. Musisz go zainstalować, ale powinien być dostępny w repozytoriach dystrybucji. W przypadku systemów opartych na Debianie uruchom

sudo apt-get install r-base

To również powinno przynieść, r-base-coreale jeśli nie, uruchom sudo apt-get install r-base-coretakże. Po Rzainstalowaniu możesz napisać prosty skrypt R w tym celu:

#!/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()

Powyższy skrypt utworzy plik o nazwie output.pdf. Testowałem w następujący sposób:

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

Na losowych danych, które wykorzystałem, które dają:

wprowadź opis zdjęcia tutaj

Nie jestem do końca pewien, co chcesz knuć, ale to powinno przynajmniej wskazać ci właściwy kierunek.

terdon
źródło
Mój Rscript v3.4.4 domyślnie generuje plots.pdf, niezależnie od tego, czy używasz ggplot czy plot.
Vorac
@Vorac chciałeś skomentować inną odpowiedź? Co ma z tym wspólnego ggplot? I dlaczego domyślna nazwa pliku wyjściowego jest odpowiednia?
terdon
W moim systemie Debian ten podzbiór skryptu wystarcza #!/usr/bin/env Rscript; args <- commandArgs(TRUE); a<-read.table(args[1]); plot(a$V2,a$V1,ylab="line number",xlab="value");do wygenerowania pliku Rplots.pdf w tym samym katalogu.
Vorac
1
@Vorac tak, oczywiście. Ale chcę wybrać nazwę pliku wyjściowego. I, co ważniejsze, pokaż, jak można to zrobić, aby można go było skryptować. W przeciwnym razie za każdym razem, gdy uruchomisz RScript, użyje tej samej nazwy i nadpisze dane wyjściowe cennego uruchomienia.
terdon
11

Jeśli może się zdarzyć, że wystarczy bardzo prosty wydruk terminala, a odwrócone osie spełnią Twoje wymagania, rozważ następujące kwestie:

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

Powyższe pokazuje odwrócony trend w skali 10% dla każdego wystąpienia wzorca 11 na wyjściu seq 1000.

Lubię to:

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

Z kropkami i liczbą wystąpień może to być:

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

... które drukuje ...

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

Możesz uzyskać osie takie jak twój przykład o wiele więcej pracy i tput- musisz zrobić \033[Aucieczkę (lub jej odpowiednik zgodny z emulatorem terminala), aby przesunąć kursor w górę o linię dla każdego wystąpienia.

Jeśli awk„s printfwsporniki czasoprzestrzeni wyściółka jak POSIX-shell printfrobi, wtedy można go używać do tego samego - i prawdopodobnie znacznie bardziej efektywnie, jak to dobrze. Nie wiem jednak, jak korzystać awk.

mikeserv
źródło
1

Ulepszając odpowiedź Nate'a w celu uzyskania danych wyjściowych w formacie PDF i kreślenia linii (wymaga:) rsvg-convert:

| gnuplot -p -e 'set term svg; set output "|rsvg-convert -f pdf -o out.pdf /dev/stdin"; plot "/dev/stdin" with lines'
feuerstein
źródło
0

Lub możesz przekierować dane standardowe przez potok do niestandardowego skryptu python. Umożliwi to ogromną personalizację i elastyczność w przetwarzaniu, przetwarzaniu wstępnym i wizualizacji danych.

Oto samouczek na ten temat, który napisałem dokładnie tak, jak zamierzałeś. połączyć

quartzfun
źródło