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

enter image description here

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:

enter image description here

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.