I am new to unix and shell. I want to know how to draw a simple histogram with three variables which will be read from a file. The variables are random numbers that range from 1 to 100 and they will go to the Y scale and the X scale will be the time stamp of 10 minute.
Asked
Active
Viewed 1,185 times
1
-
2Do you have to use bash? I can imagine better solutions in python or perl, for example, given those languages' file handling... – Rob I May 19 '12 at 06:17
-
Why bash, if you still want to, take a look at [spark](https://github.com/holman/spark) – karth May 19 '12 at 06:20
-
1If you would accept invoking gnuplot from the command line you can use http://stackoverflow.com/questions/2471884/histogram-using-gnuplot – Ray Toal May 19 '12 at 06:20
-
I have to use bash. Because all the other random generator and saving to the file and calculating the averages are written in bash. Is it possible to write in bash? – soe May 19 '12 at 06:45
-
I like to draw a histogram like graph and point out all the variables. – soe May 19 '12 at 06:56
-
1It would help a lot if you showed some sample data and the code you have so far. – Dennis Williamson May 19 '12 at 11:35
1 Answers
3
Assuming the data consists only of integers.
Edit 2:
#!/bin/bash
limit=40
xtoggle=true
pad=5
xtitle='Seconds'
footnote='5 second intervals'
ytitle='Number (1-100)'
printf ' %*s\n' "$((limit/2 + ${#ytitle}/2 + pad))" "$ytitle"
printf ' %*d' "$pad" 0
for ((i = 5; i <= limit; i += 5))
do
printf '%5d' "$i"
done
printf '\n\n'
while read -r -a data
do
printf -v bar '%*s' "$limit" ''
for i in "${data[@]}"
do
bar=${bar:0:i}x${bar:i+1}
done
if $xtoggle
then
xc=''
xtoggle=false
else
xc="${xtitle:x++:1}"
xtoggle=true
fi
printf '%-*s' "$pad" "$xc"
printf '%s\n' "$bar"
done < bardata
if $xtoggle
then
printf '\n'
fi
for ((i = x; i <= ${#xtitle}; i++))
do
printf '%s\n\n' "${xtitle:i:1}"
done
printf '\n%s\n' "$footnote"
With this data:
0 5 10
10 13 16
14 3 25
8 4 12
2 20 11
5 17 19
7 8 7
14 19 30
27 22 18
11 19 23
3 33 13
8 5 1
36 18 12
This is the output:
Number (1-100)
0 5 10 15 20 25 30 35 40
x x x
S x x x
x x x
e x x x
x x x
c x x x
xx
o x x x
x x x
n x x x
x x x
d x x x
x x x
s
5 second intervals
Previous Edit:
while read -r -a data
do
for i in "${data[@]}"
do
printf -v bar '%*s' "$i" ''
bar=${bar// /*}
printf '%s\n' "$bar"
done
printf '\n'
done < inputfile
For this data:
10 12 13
4 5 6
8 4 7
This is the output:
**********
************
*************
****
*****
******
********
****
*******
Original Answer (None of the indirection trickery below is necessary. ):
while read -r -a data
do
for i in "${!data[@]}"
do
printf -v "bar$i" '%*s' "${data[i]}" ''
temp=bar$i
declare "bar$i"=${!temp// /*}
printf '%s\n' "${!temp}"
done
printf '\n'
done < inputfile

Dennis Williamson
- 346,391
- 90
- 374
- 439
-
Thank you so much for the answer. I want to draw like a graph with x scale and y scale. Thanks. – soe May 19 '12 at 13:04
-
2@soe: The Y scale is horizontal and the X scale is vertical. Please edit your answer and show some sample data and what you'd like the output to look like. – Dennis Williamson May 19 '12 at 13:06
-
Thanks. My scenerio is i have three variables produce at every lets say 5 seconds and i want to show the time interval at x scale and the variables on y scale. So that one time interval will point at 3 different variables on the graph. – soe May 19 '12 at 15:26
-
@soe: That's *exactly* what my script is doing. I can't make it do more based only on guesses. Until you provide more information as I have asked for, I can't do anything more. Your comment simply restates what was already in your question. – Dennis Williamson May 19 '12 at 16:35
-
@soe: Doubles, as in floating point numbers? Two problems, Bash doesn't understand any numbers except integers and character cells on the screen have integral width. You can deal with both of these issues by using `bc` or `awk` to scale the floats and convert the floats to ints (losing some detail). If you want a graph of float values, I would recommend that you use something that produces graphical output like gnuplot. – Dennis Williamson May 21 '12 at 05:32
-
Thanks. I think it would be hard to do with gnuplot. I have awk to do the average of five numbers and cast it into integer and save to another file and do the histogram. Any link to gnuplot for begineers? – soe May 21 '12 at 05:36
-
@soe: If you've already got an awk script, why don't you have it do the histogram? The same techniques in my answer above could be used. Sorry, I don't have any links for you. – Dennis Williamson May 21 '12 at 06:07