reverse tail for gnuplot - output

I would like to display data in a repeated online diagram with:
plot "tail -140 logging.dat | tac -r" with lines
I get an error message file cannot be opened, however in CLI it gives the reverse list of data as expected. Could anyone help me with the correct syntax, please?

Just for the records, here is a gnuplot-only, hence platform-independent solution. Check via stats the total number of lines. If there are less than N lines (here: 140), all lines will be plotted, otherwise only the 140 last ones.
Remark: if you do plot ... with lines, gnuplot will plot column 1 as x and column 2 as y per default. However, the output graph will look the same whether you reverse the data or not. So, I don't see why reversing the data would be necessary, unless you want to plot something what you haven't shown here or e.g. list a reversed table as text.
Script:
### plot N last lines of a file
reset session
FILE = "SO55221113.dat"
# create some random test data
set table FILE
set samples 1000
y0 = rand(0)
plot '+' u 1:(y0=y0+rand(0)-0.5)
unset table
N = 140
stats FILE u 0 nooutput # get total number of lines into STATS_records
M = STATS_records<=N ? STATS_records : STATS_records-N
plot FILE u 1:2 w l lc rgb "green" ti "all values", \
'' u 1:2 every ::M w l lc rgb "red" ti sprintf("last %d values",N)
### end of script
Result:

Related

GnuPlot :: Plotting 3D recorded in an unconventional format

I would like to prepare a script file to draw a 3D plot of some kinetic spectroscopy results. In the experiment the absorption spectrum of a solution is measured sequentially at increasing times from t0 to tf with a constant increase in time Δt.
The plot will show the variation of absorbamce (Z) with wavelength and time.
The data are recorded using a UV-VIS spectrometer and saved as a CSV text file.
The file contains a table in which the first column are the wavelengths of the spectra. Afterwards, a column is added for each the measured spectra, and a number of columns depends on the total time and the time interval between measuerments. The time for each spectra appears in the headers line.
I wonder if the data can be plotted directly witha minimum of preformatting and without the need to rewrite the data in a more estandar XYZ format.
The structure of the data file is something like this
Title; espectroscopia UV-Vis
Comment;
Date; 23/10/2018 16:41:12
Operator; laboratorios
System Name; Undefined
Wavelength (nm); 0 Min; 0,1 Min; 0,2 Min; 0,3 Min; ... 28,5 Min
400,5551; 1,491613E-03; 1,810312E-03; 2,01891E-03; ... 4,755786E-03
... ... ... ... ... ...
799,2119; -5,509266E-04; 3,26314E-04; -4,319865E-04; ... -5,087912E-04
(EOF)
A copy of a sample data is included in this file kinetic_spectroscopy.csv.
Thanks.
Your data is in an acceptable form for gnuplot, but persuading the program to plot this as one line per wavelength rather than a gridded surface is more difficult. First let's establish that the file can be read and plotted. The following commands should read in the x/y coordinates (x = first row, y = first column) and the z values to construct a surface.
DATA = 'espectros cinetica.csv'
set datafile separator ';' # csv file with semicolon
# Your data uses , as a decimal point.
set decimal locale # The program can handle this if your locale is correct.
show decimal # confirm this by inspecting the output from "show".
set title DATA
set ylabel "Wavelength"
set xlabel "Time (min)"
set xyplane 0
set style data lines
splot DATA matrix nonuniform using 1:2:3 lc palette
This actually looks OK with your data. For a smaller number of scans it is probably not what you would want. In order to plot separate lines, one per scan, we could break this up into a sequence of line plots rather than a single surface plot:
DATA = 'espectros cinetica.csv'
set datafile separator ";"
set decimal locale
unset key
set title DATA
set style data lines
set ylabel "Wavelength"
set xlabel "Time (min)"
set xtics offset 0,-1 # move labels away from axis
splot for [row=0:*] DATA matrix nonuniform every :::row::row using 1:2:3
This is what I get for the first 100 rows of your data file. The row data is colored sequentially by gnuplot linetypes. Other coloring schemes are possible.

Reading from csv and plotting Date on x

I am new to gnuplot and got stuck in plotting two trend lines. The file is tracking how investiments of two profiles: low and high risk. Now I want to plot a trend line, as in the below R base plot, but using gnuplot. My data file looks like:
date,investpercent,expenses,savings,low,high,objective
2015-09-25,5.0,1.0,2.0,1,2,2.0
2016-09-25,6.0,1.0,2.0,1,2,2.0
2017-09-26,6.0,1.0,2.0,2,4,2.0
2018-09-27,5.0,40.0,60.0,10,40,-49904.0
2018-09-27,5.0,40.0,60.0,20,50,-169960.0
set key autotitle columnhead
plot '~/Downloads/finances.csv' using 1:5
I am using autotitle because of the header in the first line, it removes an error, but obviously sets a title, which I don't need. It would be nice to know how to ignore the headers too.
My question is:
How can I plot the trend using the values on columns 5 and 6 in y using dates as the x axis using gnuplot?
You could try this:
set key autotitle columnhead
set key top left
set datafile separator ","
set timefmt '%Y-%m-%d'
set xdata time
plot 'test.txt' using 1:5 w l t 'low', 'test.txt' using 1:6 w l t 'high'
which yields:

rotation from csv file in maxscript

Hopefully someone with better maxscript knowledge can help with this.
I have a csv file driving the position of some dummy helpers in 3dsmax. The problem I am having is getting each dummy object to have a local rotation being driven from the csv file. This is a sample from my csv file (actual file has hundreds of points):
0, 975.4222, 2181.8731, 0, 267, 360, 75,
columns 1 through four name the point and position it to an x y and z coordinate. Columns 5 6 and 7 represent a rotation value for each point around the x y z. This is where I am struggling. If i run my code with the random values then the script fails. If however all the values for column 5 are the same and the values for columns 6 and 7 are also the same then the script will run, but each dummy will have the same rotation (obviously). I know i must be doing something slightly wrong. Any help would be really appreciated. My current code is as follows:
-- open the file as text, read mode
f = openFile "c:\\Testtocsv003c.csv" mode:"rt"
prefabPoint = dummy name:"dummy"
-- if it opened successfully (exists, etc)...
if f != undefined do
(
while not eof f do
(
-- Read a line from the file
l = readline f
-- turn that line into an array of strings using commas as delimiters
lf = filterString l ","
if (lf[1]!=undefined ) do
(
newPoint = instance prefabPoint
newPoint.name = lf[1]
x = lf[2] as float -- bracketed number reads column position from text file
y = lf[3] as float -- bracketed number reads column position from text file
z = lf[4] as float -- bracketed number reads column position from text file
xRot = lf[5] as float
yRot = lf[6] as float
zRot = lf[7] as float
newPoint.pos = [x,y,z]
--creates point objects at xyz coordinates from text file. To offset by distance for example change to : [100*x,100*y,100*z]
rotate newPoint (eulerangles xRot yRot zRot) --rotates point
)
)
close f
delete prefabPoint
)
Thanks all. Oh and sorry if the formatting is wrong. This is my first post.
Paul
This really should be in a comment, but I don't have enough reputation.
Anyway, I just ran your code successfully with 500 dummy objects with randomly generated transforms and it ran fine. So it sounds like it might be an issue with memory, possibly related to an open file--I once wrote a script that opened a file to read/write values and I had some strange results when I was doing operations while the file was open. So here's what I would suggest:
Read all values from the file into an array and then close the file before instancing your dummy nodes.
Wrap your operations and turn off the undo stack. This can sometimes help with memory issues when performing a large number of operations:
with undo off (
if (lf[1]!=undefined ) do
(
-- create instances of dummy nodes here ...
)
)
Good luck!

The most efficient way to calculate an integral in a dataset range

I have an array of 10 rows by 20 columns. Each columns corresponds to a data set that cannot be fitted with any sort of continuous mathematical function (it's a series of numbers derived experimentally). I would like to calculate the integral of each column between row 4 and row 8, then store the obtained result in a new array (20 rows x 1 column).
I have tried using different scipy.integrate modules (e.g. quad, trpz,...).
The problem is that, from what I understand, scipy.integrate must be applied to functions, and I am not sure how to convert each column of my initial array into a function. As an alternative, I thought of calculating the average of each column between row 4 and row 8, then multiply this number by 4 (i.e. 8-4=4, the x-interval) and then store this into my final 20x1 array. The problem is...ehm...that I don't know how to calculate the average over a given range. The question I am asking are:
Which method is more efficient/straightforward?
Can integrals be calculated over a data set like the one that I have described?
How do I calculate the average over a range of rows?
Since you know only the data points, the best choice is to use trapz (the trapezoidal approximation to the integral, based on the data points you know).
You most likely don't want to convert your data sets to functions, and with trapz you don't need to.
So if I understand correctly, you want to do something like this:
from numpy import *
# x-coordinates for data points
x = array([0, 0.4, 1.6, 1.9, 2, 4, 5, 9, 10])
# some random data: 3 whatever data sets (sharing the same x-coordinates)
y = zeros([len(x), 3])
y[:,0] = 123
y[:,1] = 1 + x
y[:,2] = cos(x/5.)
print y
# compute approximations for integral(dataset, x=0..10) for datasets i=0,1,2
yi = trapz(y, x[:,newaxis], axis=0)
# what happens here: x must be an array of the same shape as y
# newaxis tells numpy to add a new "virtual" axis to x, in effect saying that the
# x-coordinates are the same for each data set
# approximations of the integrals based the datasets
# (here we also know the exact values, so print them too)
print yi[0], 123*10
print yi[1], 10 + 10*10/2.
print yi[2], sin(10./5.)*5.
To get the sum of the entries 4 to 8 (including both ends) in each column, use
a = numpy.arange(200).reshape(10, 20)
a[4:9].sum(axis=0)
(The first line is just to create an example array of the desired shape.)

How to plot 3D matrix CSV data in Gnuplot with splot using the first row and column as the x y coordinates?

How can I plot (a 3D plot) a matrix in Gnuplot having such data structure. I cannot find a way to use the first row and column as a x and y ticks (or to ignore them)
,5,6,7,8
1,-6.20,-6.35,-6.59,-6.02
2,-6.39,-6.52,-6.31,-6.00
3,-6.36,-6.48,-6.15,-5.90
4,-5.79,-5.91,-5.87,-5.46
Is the splot 'data.csv' matrix the correct parameter to use ?
You can give using a format specification; here we need to tell the seperator ','. The following works for me:
splot 'data.csv' using 1:2:3 '%lf,%lf,%lf,%lf' with linespoints pt 6 ps 2 lw 3
except that the first line is ignored, which is probably right?