How can I make a graphical plot of a sequence of numbers from the standard input?
You could use gnuplot
for this:
primes 1 100 |gnuplot -p -e 'plot "/dev/stdin"'
produces something like
You can configure the appearance of the graph to your heart's delight, output in various image formats, etc.
I would do this in R
. You'll have to install it but it shouold be available in your distributions repositories. For Debian-based systems, run
sudo apt-get install r-base
That should also bring in r-base-core
but if it doesn't, run sudo apt-get install r-base-core
as well. Once you have R
installed, you could write a simple R script for this:
#!/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()
The script above will create a file called output.pdf
. I tested as follows:
## 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
On the random data I used, that produces:
I am not entirely sure what you want to plot but that should at least point you in the right direction.
If it might be that a very simple terminal printout would suffice, and that you could be satisfied by inverted axes, consider the following:
seq 1000 |
grep -n 11 |
while IFS=: read -r n match
do printf "%0$((n/10))s\n" "$match"
done
The above charts an inverted trend on a 10% scale for every occurrence of the pattern 11 in the output of seq 1000
.
Like this:
11
110
111
112
113
114
115
116
117
118
119
211
311
411
511
611
711
811
911
With dots and occurrence count it could be:
seq 1000 |
grep -n 11 | {
i=0
while IFS=: read -r n match
do printf "%02d%0$((n/10))s\n" "$((i+=1))" .
done; }
...which prints...
01 .
02 .
03 .
04 .
05 .
06 .
07 .
08 .
09 .
10 .
11 .
12 .
13 .
14 .
15 .
16 .
17 .
18 .
19 .
You could get the axes like your example with a lot more work and tput
- you'd need to do the \033[A
escape (or its equivalent as is compatible with your terminal emulator) to move the cursor up a line for each occurrence.
If awk
's printf
supports space-padding like the POSIX-shell printf
does, then you can use it to do the same - and likely far more efficiently as well. I, however, do not know how to use awk
.