How to plot all data files in the directory with gnuplot? - gnuplot

How to plot all data files in the directory with gnuplot? I mean that from each data file a figure will be created. Data files have different names. I tried:
j=0;do for [i in system("ls")] { j=j+1; set term png; set output ''.i.'.png' ; p i u 1:2 w lines lc rgb "navy" t ''.i }
which lead to the error: x range is invalid
plot for [fn in system("ls")] fn with lines title ''.i
which lead to the error: internal error : STRING operator applied to undefined or non-STRING variable
This plot all data in one figure
a=system('a=`tempfile`;cat *.dat > $a;echo "$a"')
plot a u 1:2

I expected this to be a frequently asked question with well documented answers, however, I can't find a suitable example right away...
Edit:
you can do it in a "platform-independent" way using gnuplot's variable GPVAL_SYSNAME, which holds the name of the operating system.
Furthermore, the user variables DIR for the directory and EXT for file extension are used. If the output files should be in a different directory, e.g. DIR_IN and DIR_OUT could be defined instead of DIR.
Script:
### plot all datafiles in a directory
reset session
set term pngcairo
DIR = 'Test/' # directory; use '' for current directory
EXT = '.dat' # file extension
FILES = GPVAL_SYSNAME[1:7] eq 'Windows' ? system(sprintf('dir /B %s*%s',DIR,EXT)) : \
system(sprintf('ls %s*%s',DIR,EXT)) # Linux/MacOS
myInput(s) = sprintf('%s%s',DIR,s)
myOutput(s) = sprintf('%s%s.png',DIR,s[1:strlen(s)-strlen(EXT)]) # replace file extension with .png
do for [FILE in FILES] {
set output myOutput(FILE)
plot myInput(FILE) u 1:2 w lines lc "red" title FILE
}
set output
### end of script

Related

How to use grep command in a loop in gnuscript

sorry, I am asking multiple questions.
I have a case.dat file which is having multiple columns and I want to extract array of the data according to colum 2 in the gnuscript.
I tried with below script but it is giving me error
array=""
do for [i=300:800:100] { # I mean start:end:increment. so it should read 300, 400, 500, 600, 700, 800 here
val ="grep i case.dat" # Want to store the command in a valuel/variable
print val > i.dat #Here I need to store the data in i.dat
}
error
line 45: undefined variable: dat
my bash script is like below
##!/bin/bash
case="data"
for i in `seq 100 100 800`
do
awk '$2=='$i'{print $0}' $case.dat > $i.dat
done
that I want to use at the start of the gnu-script so that the further operation can be done in the rest part of the gnu-script.
gnuplot script:
do for [i=300:800:100] {
outfile = sprintf("%d.dat", i)
command = sprintf("grep %d case.dat",i)
set print outfile
print system(command)
unset print
}
This will create separate files 300.dat 400.dat 500.dat and so on.
If you want to keep these data subsets entirely internal to gnuplot, i.e. not create any new files, you could instead create named datablocks $data_300 $data_400 etc:
do for [i=300:800:100] {
eval( sprintf("set print $data_%3d", i) )
print( sprintf("grep %d case.dat") )
unset print
}
Named datablocks can in general be used anywhere you could use a file name, e.g.
plot $data_500 with lines.

Watson LT SDK create_model() fails if forced_glossary is in /tmp/ folder

The Watson LT create_model() fails if the glossary file is in a folder outside the local dir. Kinda crazy... why would location of TMX file matter?
It works if I just the basename (CustomModel_xxxx.tmx) w/o a folder.
If fails with error below if I use /tmp/CustomModel_xxxx.tmx
I don't want tmx files created in my code base...
Running on Py 3.5. in a jupyter notebook
WatsonApiException: Error: Error while uploading file(s). Please try again!, Code: 500 , X-dp-watson-tran-id: gateway02-898567107 , X-global-transaction-id: ffea405d5bfc5adf358f0bc3
CODE:
from watson_developer_cloud import LanguageTranslatorV3
lt = LanguageTranslatorV3(....)
DIR = kwargs.get('folder','/tmp')
bn = 'CustomModel_%d.tmx' % os.getpid()
# Fails
tmx_name = os.path.join(DIR, bn)
# Is ok
#tmx_name = bn
with open(tmx_FN,'r', encoding='U8') as fio:
x = fio.read()
print("Read ok",)
r = lt.create_model(
base_model_id=model_id,
name = 'xxx',
**{'forced_glossary': fio}
)
I tried your example with Python 2.7 and it works fine on my system. My best guess is that you have some kind of permissions problem with /tmp on your system. Or maybe jupyter is remapping /tmp somehow. What happens if you run this as a standalone python app?

tcl split string with variables

how can split the name in tcl?
NEW in ARCHIVE XVID/J/JURASSIC.WORLD
path is not always the same, it may also be so
/XVID-BOXSET/007.A.VIEW.TO.A.KILL
and set this as variable, one variable set the name and one the path.
I need the following variables:
Name example : JURASSIC.WORLD bzw 007.A.VIEW.TO.A.KILL
Path example : XVID/J/ bzw /XVID-BOXSET/
set pn [lindex {NEW in ARCHIVE XVID/J/JURASSIC.WORLD} 3]
# -> XVID/J/JURASSIC.WORLD
set path [file dirname $pn]
# -> XVID/J
set name [file tail $pn]
# -> JURASSIC.WORLD

Read function coefficients from file

Say I have the following file:
1,2,3
4,5,6
7,8,9
I would like to have gnuplot plot 3 polynomials of the form ax^2 + bx +c, using the file values as coefficients. Performing this directly, I would do:
plot x**2+2*x+3, 4*x**2+5*x+6, 7*x**2+8*x+9
But I would like to do this programatically, for an arbitrary number of lines in the input file.
I think I might be close with code inspired by this answer:
n= "`awk 'END {print NR}' < test.dat`"
i=0
while i<n{
f(a,b,c,x)=a*x**2+b*x+c
plot 'test.dat' every ::i::i using f($1,$2,$3,x)
}
But this fails with undefined variable: x
I've had the same problem for ages and finally I managed to find a solution.
It requires a creative use of the stats function to assign the values from the file to the variables and a couple of do for [...] loops to store some commands in a temp file
filename = "InputFileName.dat"
stats filename nooutput
nlines = STATS_records-1
set print "temp.gnuplot"
do for [i=0:nlines] {\
print sprintf("stats filename every ::%i::%i using (a%i=$1,b%i=$2,c%i=$3,0):(0) nooutput",i,i,i,i,i)}
set print
load "temp.gnuplot"
set print "temp.gnuplot"
do for [i=1:nlines] {print sprintf("replot a%i*x**2 + b%i*x + c%i",i,i,i)}
plot a0*x**2 + b0*x +c0
load "temp.gnuplot"
set print
Change the filename variable as you need. You can remove the temp file once you are finished with a system call like this ! rm temp.gnuplot.
I know is not particularly elegant and I especially don't like the use of a temp file, if somebody knows how to execute a string variable I'd be happy to know. But hey, it works (even under Windows)!
Edit: forgot to credit thse for the input.
It's an old thread but thanks to the previous answer, I can propose an upgraded version using strings instead of a temp file. That one, there is no need to bother deleting the useless temp file afterwards.
filename = "InputFileName.dat"
stats filename nooutput
nlines = STATS_records-1
paramstr(N) = sprintf("stats filename every ::%i::%i using (a%i=$1,b%i=$2,c%i=$3,0):(0) nooutput",N,N,N,N,N)
do for [i=0:nlines] {
eval(paramstr(i))
}
plotstr = "p "
do for [i=0:nlines] {
plotstr = plotstr . sprintf("a%i*x**2 + b%i*x + c%i%s",i,i,i,(i == nlines) ? "" : ", ")
}
eval(plotstr)
Maybe that some set xrange and set yrange tuning will be necessary to look at what you are interested in though.
This question is similar to Plotting a function directly from a text file, however, with more parameters and in several lines.
At the time of OP's question there were no arrays in gnuplot, but you can simply store your values in a string and address them via some functions using word() and real(), check help word and help real).
There is no need for awk (as in the link), no temporary files (solution of #Joseph D'Arimathea) and no extra loops or eval() (solution of #afagot).
Data: SO26680694.dat
1,2,3
4,5,6
7,8,9
Script: (works with gnuplot 4.6.0, March 2012)
### extract multiple parameters from a datafile
reset
FILE = "SO26680694.dat"
set datafile separator ','
myParams = ''
stats FILE u (myParams = myParams.sprintf(' %g %g %g', $1, $2, $3),0) nooutput
myParam(s,i) = real(word(myParams,(s-1)*3+i))
a(s) = myParam(s,1)
b(s) = myParam(s,2)
c(s) = myParam(s,3)
f(x,a,b,c) = a*x**2 + b*x + c
plot for [i=1:3] f(x,a(i),b(i),c(i)) title sprintf("%gx^2 + %gx + %g",a(i),b(i),c(i))
### end of script
Result:

Xlsx or csv retrieve in Matlab

I have points data in .xlsx and I want to read and store them in p array in Matlab. These points are only 3D co-ordinates of x,y,z such that having understood three columns and not prdfined rows. How I can retrieve them from .xlsx or .csv if I need fast retrieval as I tried to retrieve .xlsx and its response time is slow and returns an empty array. Possibly store them in transposed form and transpose it back.
My Code: .Xls read
A = xlsread('data.xlsx')
Output:
A =
[]
My Code: .CSV read
M = csvread('data.csv')
Output:
Error using dlmread (line 139)
Mismatch between file and format string.
Trouble reading number from file (row 2u, field 1u) ==> ;\n
Error in csvread (line 48)
m=dlmread(filename, ',', r, c);
Points Set 1:
-191.2442 187.7193 1.0000;
-155.2995 152.6316 2.0000;
-182.0276 104.6784 3.0000;
-148.8479 84.7953 4.0000;
Points Set 2:
-142.3963 83.6257 5.0000;
-102.7650 133.9181 6.0000;
-56.6820 164.3275 7.0000;
-30.8756 124.5614 8.0000;
-23.5023 118.7135 7.0000;
-9.6774 110.5263 6.0000;
26.2673 90.6433 5.0000;
-42.8571 -6.4327 4.0000;
10.5991 7.6023 3.0000;
Points Set 3:
-73.2719 84.7953 9.0000;
-137.7880 15.7895 10.0000;
-92.6267 -30.9942 9.0000;
-42.8571 19.2982 8.0000;
41.0138 -15.7895 4.0000;
71.4286 -41.5205 6.0000;
90.7834 -14.6199 5.0000;
See if this slightly twisted one using importdata works for you -
C1 = importdata(file1) %%// file1 is your CSV filename
t1 = regexp(C1,'\s','Split')
t2 = horzcat(t1{:})
t2 = strrep(t2,';','')
M = cellfun(#str2num,reshape(t2(~strcmp(t2,'')),3,[])')
Edit 1: This case assumes you have a CSV file that has all the Point Sets clustered together but one by one (without spaces between the Point Sets and their data and also between the end of a Point Set and the declaration of the arrival of the next Point Set).
So, the input CSV file would look like this for the given data in the question -
Points Set 1:
-191.2442 187.7193 1.0000;
-155.2995 152.6316 2.0000;
-182.0276 104.6784 3.0000;
-148.8479 84.7953 4.0000;
Points Set 2:
-142.3963 83.6257 5.0000;
-102.7650 133.9181 6.0000;
-56.6820 164.3275 7.0000;
-30.8756 124.5614 8.0000;
-23.5023 118.7135 7.0000;
-9.6774 110.5263 6.0000;
26.2673 90.6433 5.0000;
-42.8571 -6.4327 4.0000;
10.5991 7.6023 3.0000;
Points Set 3:
-73.2719 84.7953 9.0000;
-137.7880 15.7895 10.0000;
-92.6267 -30.9942 9.0000;
-42.8571 19.2982 8.0000;
41.0138 -15.7895 4.0000;
71.4286 -41.5205 6.0000;
90.7834 -14.6199 5.0000;
Please note that the result from the codes would be a struct of arrays.
Code
C1 = importdata(file1) %%// file1 is your CSV filename
ind1 = cellfun(#isempty,strfind(C1,'Points'))
start_ind = find(~ind1)+1
s1 = find(~ind1)-1;
stop_ind = [s1(2:end) ; numel(ind1)]
for k = 1:numel(start_ind)
data1 = C1(start_ind(k):stop_ind(k))
t1 = regexp(data1,'\s','Split')
t2 = strrep(horzcat(t1{:}),';','')
t2 = t2(~strcmp(t2,''))
array(k).data = cellfun(#str2num,reshape(t2,3,[])'); %%//'
end
You are using the row separator ;\n (semicolon + new line). I don't know any function understand this format. Using texstscan is probably the best option:
fid=fopen(...)
M=cell2mat(textscan(line,'%f,%f,%f;\n'));
fclose(fid);

Resources