There are some great charting packages out there, but for quick tests and playing around it’s nice to keep things simple. I wanted to do some basic Raspberry Pi charting and found that with the Gnuplot utility it took as little as 1 line of Bash to get the job done.
This blog shows some examples, probably the key points are:
- Data can be piped to Gnuplot
- Bash While-loops can be used to create real time/dynamic plots
Single Line Chart from a File
Gnuplot plot has a full scripting interface that allows users to create very complex presentations.
Gnuplot script can also be passed on the command line, with the options: -p (persist, spawn chart) and -e (execute command):
$ # Plot a file with 5 points, show file first
$ cat 5pnts.txt
2.7
3.5
4.1
3.9
5.6
$ # Plot the file as a line
$ gnuplot -p -e "plot '5pnts.txt' with lines title '5 Test Points' "

Multi-line Chart
The multi-line example is like the single line chart with the exception that the using statement is called for each plot line, 1:2 is the first line (x-axis column):(y-axis column) , and 1:3 is the second series line.
$ # Show the first 5 line of the data
$ head -n 5 data1.txt, Note: Gnuplot skips row starting with "#"
#t Angle Error
0.0 -14.7 3.6
1.0 8.6 3.6
2.1 28.8 3.0
3.1 46.7 3.4
$
$ # plot, first column is x, next 2 columns are y series
$ gnuplot -p -e "plot 'data1.txt' \
using 1:2 with lines title 'Angle','data1.txt' \
using 1:3 with lines title 'Error'"

For-Loop Piped to a Line Chart
Rather than creating a text file, the output from a group of echo statements can be piped to Gnuplot. The ‘<cat’ definition is used for piped input.
$# Plot 10 random points
$ ( for i in `seq 1 10`; do echo "$RANDOM\n"; done )| \
gnuplot -p -e "plot '<cat' with lines title '10 Random Pts'"

A more complex example would be to add a time on the X-axis and run a calculation at a sampled interval.
# Create a calc function
mycalc() {
# Show the time and cpu idle time
thetime=$(date +'%T')
idle=$(top -n 1 | grep id | awk '{print $8}')
echo "$thetime $idle\n"
}
# Run the calc function in the for-loop
# Define the y range, x scale as time
( for i in `seq 1 20`; do mycalc; sleep 1; done )| \
gnuplot -p -e "set yrange [50:100]; set xdata time; \
set timefmt '%H:%M:%S';set format x '%H:%M:%S'; \
plot '<cat' using 1:2 with lines title 'CPU Idle Time' "

Bar Charts from a File
For the bar chart example the plot options are defined in a variable. This example uses the iostat command to get the user and idle time usage. Awk is used to parse the 4th row and then get the individual values.
# Create a file with user and idle CPU usage
# Column: 1=bar position, 2=value, 3=label
iostat | awk '{if(NR==4) print "0 " $1 " user"}' > cpu0.dat
iostat | awk '{if(NR==4) print "1 " $3 " idle" }' >> cpu0.dat
# Define the options as a variable
options="set title 'CPU Diagnostics'; set boxwidth 0.5; \
set style fill solid; "
# Plot the bars with labels, note: the label offset
gnuplot -p -e "$options ;plot 'cpu0.dat' \
using 1:2:xtic(3) with boxes notitle, \
'' using 1:2:2 with labels font 'Helvetica,15' \
offset 0.9,0.8 notitle"

Bars with Dynamic Updates
A Bash while-loop can be used to dynamically get new data and pass it to Gnuplot.
Below is an example that refreshes a bar chart every 5 seconds. The refresh time is shown in the bar series title.
mycalc2() {
# Show the time and user/cpu idle time
# note: top gets instantaneous values, iostat uses averages
top -n 1 | grep %Cpu | awk '{print "0 " $2 " user"}' > cpu0.dat
top -n 1 | grep %Cpu | awk '{print "1 " $8 " idle"}' >> cpu0.dat
}
# define chart options
options="set title 'CPU Diagnostics'; set boxwidth 0.5; \
set style fill solid; set yrange [0:100]; set xrange [-0.5:1.5]"
# create an infinite while loop to get data, and then plot
# note1: gnuplot needs a while loop to replot
# note2: use a big pause time in gnuplot or exiting will be tough
( while :; do mycalc2; sleep 10; done )| \
gnuplot -p -e "$options ; plot 'cpu0.dat' \
using 1:2:xtic(3) with boxes \
title \"$(date '+%T')\" ; while (1) { replot; pause 5 }"

Summary
Using Gnuplot with the command line option allows for some quick and easy charting. For more detailed work try creating a Gnuplot script file.
One thought on “Charts in 1 Line of Bash”