Plotting a single value with gnuplot? - bash

I have the following csv file:
timestamp,unit,maximum,average
Thu Feb 05 14:54:00 GMT 2015,Percent,13.0,4.503333333333333
When I run the following bash script on it:
#!/bin/bash
graph_results() {
input=cpu-samples.csv
output=cpu-samples.png
gnuplot <<- eor
set terminal png
set output '${output}'
set style data linespoints
set xdata time
set timefmt '%b %d %H:%M:%S GMT %Y'
set format x '%b %d %Y %H:%M'
set datafile separator ","
set xlabel "timestamp"
set ylabel "percent"
set xtics rotate
plot '< tail -n +2 ${input} | cut -f 1 --complement -d" "' using 1:3 title 'Maximum', '' using 1:4 title 'Average'
eor
}
graph_results
I get the following error:
bash-4.1$ ./run_gnuplot
Could not find/open font when opening font "arial", using internal non-scalable font
Warning: empty x range [4.76463e+08:4.76463e+08], adjusting to [4.71699e+08:4.81228e+08]
And the resulting graph has the correct datapoint and timestamp on it, but the graph is filled out with incorrect date values for the x axis.
It works fine when the csv file has more than one value in it, but doesn't when there is only one value. I realize the error message is because with one value, the start and end range for the x axis is the same (as noted here http://gnuplot.10905.n7.nabble.com/empty-x-range-td1650.html).
I know I can set a range with the following:
set xrange
But unsure how I could use in in my case, since I'm using a custom date format, and I don't know what the start and end dates should be, since the data generated is dynamic?

When using a custom timefmt, the xrange must also be specified using this format:
set xrange ["Feb 04 00:00:00 GMT 2015":"Feb 09 00:00:00 GMT 2015"]
Or you can integers, i.e.a timestamp to set the xrange. With version 5.0 the line below is equivalent to the string settings above:
set xrange [1423008000:1423440000]
Note, that until version 4.6 gnuplot uses the first january 2000 as time reference for its timestamps, and only since 5.0 the standard Unix timestamp. So until 4.6, the equivalent command to the string settings in the first line would be
set xrange [476323200:476755200]

Related

"invalid expression" running gnuplot in bash script

I am running this program SCRIPT.sh,
#!/bin/bash
FFT_FILE="$(find . -type f -iname "HR*.fft")"
FFT_FILE1=$FFT_FILE".GNUPLOT"
od -f -v -w8 $FFT_FILE > $FFT_FILE1
gnuplot -persist <<-EOFMarker
reset
set term postscript enh
set out 'FFT_1.ps'
set xlabel 'Frequency (Hz)'
set key box
filename="$FFT_FILE1"
stats filename nooutput
max_row = STATS_records
plot [(1000.0/4880.0):(1000.0/59.0)] filename u ($0/(max_row*81.92e-6)):(sqrt(($2*$2)+($3*$3))) w l lw 3 title "FFT"
reset
EOFMarker
but the output comes as
gnuplot> plot [(1000.0/4880.0):(1000.0/59.0)] filename u (./SCRIPT.sh/(max_row*81.92e-6)):(sqrt((*)+(*))) w l lw 3 title "FFT"
^
line 0: invalid expression
May I request for detailed explanation and help regarding this situation?
The "HR*.fft" file contains the results of Fast Fourier Transform from PRESTO in binary.

Difference in seconds between user input and current date

I need difference between two dates in seconds. I input datetime in format "YYYY-MM-DD HH:MM" and then calculate difference in seconds, but the run_time is in UTC timezone and current_time is calculated from system timezone.
#!/bin/bash
run_time=$1
run_time=$(date -d "$run_time" +"%s")
current_time="$(date +"%s")"
echo $run_time
echo $current_time
echo "$(($run_time-$current_time))"
How to retrieve absolute value of seconds between current datetime and another one?
Edit: actually that script has worked after restart of computer. No clue why previously it showed up different results. I have not changed anything in settings, nor computer time.
Right #Jetchisel, based on your comment a sample script could look like:
#!/bin/bash
STARTTIME_UTC=$1
STARTTIME_UTC=$(date -u -d "${STARTTIME_UTC}" +"%s")
echo "CURRENT DATE: $(date)"
CURRENTTIME="$(date +"%s")"
echo
echo "STARTTIME_UTC: ${STARTTIME_UTC} sec since"
echo "CURRENTIME: ${CURRENTTIME} sec since"
echo
echo "RUNTIME: $((${CURRENTTIME}-${STARTTIME_UTC})) sec"
As per original question
I input datetime in format "YYYY-MM-DD HH:MM"
the value of input time seconds in ${STARTTIME_UTC} will be set to zero (:00) whereby the value of current time seconds in ${CURRENTIME} will be set to what the clock provides. I.e., if it is 18 seconds before the next minute and the runtime would be almost zero, the script will report a difference of 42 seconds.

GNUPLOT error: When using arithmetic operation on one column of dat file in bash shell

#!/bin/bash
gnuplot -persist <<-EOFMarker
reset
set terminal svg enhanced size 500,500
set output 'plot.svg'
set autoscale # scale axes automatically
unset log # remove any log-scaling
unset label # remove any previous labels
set xtic auto # set xtics automatically
set ytic auto # set ytics automatically
set ylabel "Loading (mmol/gm)"
set xlabel "Pressure (kPa)"
set key left top
set key autotitle columnhead
set grid
plot "all_isotherm_15.dat" using (($2)/100000):3 title 'Simulation273K' with linespoints , \
"all_isotherm_15.dat" using (($2)/100000):5 title 'Simulation298K' with linespoints
EOFMarker
I am getting below error
gnuplot> plot "all_isotherm_15.dat" using (/100000):3 title 'Simulation273K' with linespoints , "all_isotherm_15" using (/100000):5 title 'Simulation298K' with linespoints
^
line 0: invalid expression
You get the $2 interpreted by bash as strings. As they are not defined, they get replaced by nothing.
Why not directly use gnuplot as the interpreter of the shell script, i.e., start the file as
#!/usr/bin/gnuplot -persist
reset
...

shell script of gnuplot: about various input files in a single graph for compare the lines

I am trying to plot a graph and save it as file using gnuplot. I have various text files. The number of text files is not sure. Each text file contains two columns. The text file is about linear absorption spectrum. The first column is the frequency and the second is the intensity. I want to compare the difference between the spectra by plot them in a single graph for all the files. I am using this script to do that.
#!/bin/bash
# plot linear absorption spectrum (las)
# Usage:
# ./lasplot.sh a.ods b.ods c.ods ..
j=1
for i in $*
do
echo "Normalization $i"
maxle=`cat $i|tr -s "," " "|awk 'BEGIN{max=0} {if($2>max) max=$2}END{print max}'`
echo " The max value is $maxle"
max[$j]=$maxle
filename[$j]=$i
((j=$j + 1))
done
num=$#
echo ${filename[*]}
echo $num
read -p "Please select set data range (1) or auto set(2): " setrange
case $setrange in
1)
read -p "set min x range: " minx
read -p "set max x range: " maxx
;;
esac
# call gnuplot to plot the 1D map
gnuplot << EOF
set datafile separator ","
set title 'Linear Absorption Spectra'
set xlabel '{/Symbol w} (cm^{-1})'
set ylabel 'Intensity (a.u.)'
#set data range
if (${setrange}==1){
set xrange [$minx:$maxx]
set yrange [0:1.1]
} else {
#set xrange [0:50]
#set yrange [0:50]
}
set size 1,1
set key right top
plot "${filename[1]}" using 1:(column(2)/${max[1]}) with lines linewidth 2 ,\
"${filename[2]}" using 1:(column(2)/${max[2]}) with points pointtype 21
pause mouse keypress "Type a letter"
set term pdfcairo font "arial,12"
set term pdfcairo enh
set term pdfcairo size 6,5
set output "las.pdf"
plot "${filename[1]}" using 1:(column(2)/${max[1]}) with lines linewidth 2 ,\
"${filename[2]}" using 1:(column(2)/${max[2]}) with points pointtype 21
EOF
My script can only plot two text files? How can change it to plot multiple input files?
you could prepare the plot command in your script before invoking gnuplot, store it into a variable and then reuse it in the gnuplot input (also avoiding thus repetition):
plotCmd="plot"
for((i=1;i<=${num};i++))
do
if [ $i -eq 1 ]; then
join=" "
else
join=", "
fi
plotCmd="${plotCmd}${join}\"${filename[$i]}\" using 1:2 with lines"
done
and then:
gnuplot << EOF
... some other stuff ...
${plotCmd}
EOF

Updating File Created Date by x number of days Mac OSX

I have a folder of videos (Mac OSX Yosemite) for which I need to change the Created Date by adding 2180 days to the existing Created Date.
Using SetFile from Terminal I am able to manipulate the Created Date, for example I can set it as equivalent to the Modified Date of the same file:
SetFile -d "$(GetFileInfo -m /Users/myfilename.mov)" /Users/myfilename.mov
However, if I try to add the ‘Add 2180 days’ part it stops working:
SetFile -d "$(GetFileInfo -d /Users/myfilename.mov) +2180 days" /Users/myfilename.mov
I suspect it is an issue with bracket and speech marks but the following did not work either:
SetFile -d "$(GetFileInfo -d /Users/myfilename.mov +2180 days)" /Users/myfilename.mov
How exactly should I be incorporating the '+2180 days' into it?
Edi: Mark Setchell has a solution which works but I am keen to know if there is in fact a way to incorporate '+2180 days' into the GetFileInfo-based -d date variable.
That's a lot of fun for something apparently so simple!!!! I think this works, but test it out on some sample files. I left my debugging statements in, but you can safely remove all the echo statements.
#!/bin/bash
# Get name of file as supplied as parameter
file=$1
# Get its timestamp in format "02/08/2015 21:14:44"
timestamp=$(GetFileInfo -d "$1")
echo timestamp:$timestamp
# Convert that to seconds since the Unix Epoch, e.g. 1423430084
epoch=$(date -j -f "%m/%d/%Y %H:%M:%S" "$timestamp" +%s)
echo epoch:$epoch
# Calculate seconds in 2180 days
((offset=2180*3600*24))
echo offset:$offset
# Add offset to epoch
((epoch+=offset))
echo new epoch:$epoch
# Get new date in format that SetFile wants
newdate=$(date -r $epoch "+%m/%d/%Y %H:%M:%S")
echo new date:$newdate
# And finally set the date of the input file
SetFile -d "$newdate" "$file"
Save it as ReDate and make it executable (only necessary once) with
chmod +x ReDate
and run it like this:
./ReDate /Users/myfilename.mov
Sample run:
./ReDate "/Users/Mark/tmp/file with sapce in name.mov"
timestamp:02/09/2015 09:54:01
epoch:1423475641
offset:188352000
new epoch:1611827641
new date:01/28/2021 09:54:01
I know this is an older thread, but I wanted to do something like this. The OP #MrDave is asking about adding via normal speech. This can be accomplished with AppleScript.
A bit verbose, but it works:
on run {input}
set filename to input as text
set fileDate to (creation date of (get info for input))
set newDate to fileDate + (1 * days)
set newMonth to month of newDate as number
set newMonth to lessThanTen(newMonth)
set newDay to day of newDate as number
set newDay to lessThanTen(newDay)
set newYear to year of newDate as number
set newHour to hours of newDate as number
set newHour to lessThanTen(newHour)
set newMinute to minutes of newDate as number
set newMinute to lessThanTen(newMinute)
set divider to "/"
set newSetDate to newMonth & divider & newDay & divider & newYear & " " & newHour & ":" & newMinute as text
set printNewDate to "\"" & newSetDate & "\"" as string
log printNewDate
-- date format for SetFile: mm/dd/yyyy hh:mm
do shell script ("SetFile -d " & printNewDate & " -m " & printNewDate & " " & input)
end run
on lessThanTen(num)
set thisNum to num as number
if thisNum is less than 10 then
set newNum to "0" & thisNum
else
set newNum to thisNum
end if
return newNum as string
end lessThanTen
now from terminal run:
osascript /Users/path/to/scriptName.scpt filename
and here you can actually just drag the file from Finder onto the Terminal instead of typing the filename itself, then hit enter

Resources