|
From: theozh <th...@gm...> - 2017-08-02 09:28:31
|
Hello,
I am trying to plot with a "double loop" into one single plot.
For example something like:
plot for [i=1:5][j=1:5] sin(i*j*x) w l
But a 2D loop apparently does not exist in gnuplot?!
First trial:
set label 1 "This is a double loop"
do for [i=1:5] {
plot for [j=1:5] sin(i*j*x)
}
This basically works, however, the axis and labels are printed several
times on top of each other such that the output (axis and labels) look
blurry or pixelated.
Second trial:
Same thing if I use multiplot.
set multiplot layout 1,1
do for [i=1:5] {
plot for [j=1:5] sin(i*j*x)
set multiplot previous
}
unset multiplot
Third trial:
Unsetting border, label, tics, ... after the first plot
unset border
unset label
unset xtics
However, this changes the following plot sizes...
Any ideas how to circumvent that several identical axis and labels are
plotted on top of each other and start looking blurry/pixelated?
|
|
From: thse <t.s...@fz...> - 2017-08-02 12:14:14
|
multiple for-loops are possible:
gnuplot> help for
...
...
Nested iteration is supported:
set for [i=1:9] for [j=1:9] label i*10+j sprintf("%d",i*10+j) at i,j
...
i.e.,
plot for [i=1:5] for [j=1:5] sin(i*j*x)
will work.
--
View this message in context: http://gnuplot.10905.n7.nabble.com/How-to-realize-a-single-plot-in-a-double-loop-tp20830p20831.html
Sent from the Gnuplot - User mailing list archive at Nabble.com.
|
|
From: Dave H. <da...@ho...> - 2017-08-02 15:24:09
|
On Wed, 2 Aug 2017, thse wrote:
> multiple for-loops are possible:
>
> gnuplot> help for
> ...
> ...
> Nested iteration is supported:
>
> set for [i=1:9] for [j=1:9] label i*10+j sprintf("%d",i*10+j) at i,j
> ...
>
> i.e.,
> plot for [i=1:5] for [j=1:5] sin(i*j*x)
> will work.
Well, if I could print that out in A0 it would make a surreal picture on
my wall...
--
Dave Horsfall DTM (VK2KFU) "Those who don't understand security will suffer."
|
|
From: theozh <th...@gm...> - 2017-08-02 13:10:24
|
Thank you! You're right.
Well, if you check help starting with "plot" I see a link to subtopics
"for loops in plot command". But there, nested iteration is not
mentioned. Might be helpful there to set a link to "for". Unfortunately,
I haven't checked help for "for".
However, I just noticed that in order to illustrate my problem I
simplified it too much. This nested loop will actually not (yet) solve
my problem.
Let me try to explain:
I have datafiles which are named with the following scheme:
Data_<1>_<2>_<3>
<1> is a known, limited range e.g. A,B,C,D,E,F,G,H,I
<2> is a unknown, variable range, e.g. a,b,c,d,...
<3> is a unknown, variable range, e.g. 1,2,...
What I would like to plot is in a Multiplot:
All Data_A in the first plot, Data_B in the second, etc...
where a,b,c,... determines the color of the line
and 1,2,... are just data from repeated measurements.
The difficulty is that not files for all combinations, e.g. A_a_1, ...
I_d_9 might exist.
I get the existing filenames via one or several system calls, e.g.
FileList = system("dir /B /S Data_A_*.dat")
or
FileList = system("dir /B /S Data_A_a_*.dat")
I currently do not see how to loop this for each plot of the multiplot.
|
|
From: theozh <th...@gm...> - 2017-08-02 14:46:38
|
ok... maybe I simply loop all the files
"Data_<Index1>_<Index2>_<Index3>.dat"
with respect to the first two indices and put them all in one list per
plot. Additionally, in parallel I need to create a color list which
corresponds to <Index2>.
With this gnuplot checks [A...I] (9) x [a...f] (6) =54 times whether are
files existing. Not very elegant, but seems feasible...
Regular expressions in gnuplot might be nice e.g. to create sublists or
define the color from the filenames...
### gnuplot code
Index1 = [A B C D E F G H I]
Index2 = [a b c d e f]
ColorList = ""
AllFileList = ""
set multiplot layout 3,3
do for [iii = 1:words(Index1)] {
do for [jjj = 1:words(Index2)] {
FileList = system('dir /B /S Data_'.Index1.'_'.Index2.'_'*.dat')
do for [kkk = 1:words(FileList)] { ColorList = ColorList." ".jjj }
AllFileList = AllFileList." ".FileList
}
plot for [mmm = 1:words(AllFiles)] word(AllFiles,mmm) u 1:2 w l lc
word(ColorList,mmm) notitle
}
unset multiplot
### end gnuplot code
### Still needs to be tested when several files are not existing.
|
|
From: sfeam <sf...@us...> - 2017-08-02 16:04:35
|
On Wednesday, 02 August 2017 16:46:27 theozh wrote:
> ok... maybe I simply loop all the files
> "Data_<Index1>_<Index2>_<Index3>.dat"
> with respect to the first two indices and put them all in one list per
> plot. Additionally, in parallel I need to create a color list which
> corresponds to <Index2>.
> With this gnuplot checks [A...I] (9) x [a...f] (6) =54 times whether are
> files existing. Not very elegant, but seems feasible...
>
> Regular expressions in gnuplot might be nice e.g. to create sublists or
> define the color from the filenames...
>
> ### gnuplot code
> Index1 = [A B C D E F G H I]
> Index2 = [a b c d e f]
> ColorList = ""
> AllFileList = ""
>
> set multiplot layout 3,3
> do for [iii = 1:words(Index1)] {
> do for [jjj = 1:words(Index2)] {
> FileList = system('dir /B /S Data_'.Index1.'_'.Index2.'_'*.dat')
> do for [kkk = 1:words(FileList)] { ColorList = ColorList." ".jjj }
> AllFileList = AllFileList." ".FileList
> }
You are either inventing syntax that doesn't exist or mangling syntax
that does exist. I think your intent is something like
array index1 = ["A", "B", "C", "D", "E", "F", "G", "H", "I"]
file(i,j) = sprintf("%s_%d.dat", index1[i], j)
do for [iii = 1:|index1|] for [jjj = 1:*] {
plot file(i,j) with ... lc variable
}
I left out the color because it wasn't clear to me where it comes from,
but it sounds like you want to use it as a variable to color the lines
rather than as an element to loop over. So that would be something
involving "lc variable"
> unset multiplot
> ### end gnuplot code
> ### Still needs to be tested when several files are not existing.
missing files should not be a problem except that the iteration
[jjj = 1:*] will terminate at the first missing file. So if there are gaps
in the numbering you must give an explicit upper bound rather than *.
See for instance the second plot in
http://gnuplot.sourceforge.net/demo_cvs/iterate.html
At least that's the intent. If you find otherwise please report it as a bug.
Ethan
|
|
From: theozh <th...@gm...> - 2017-08-04 11:30:31
|
Thank you, Ethan!
I learnt again a few things.
1. I shouldn't post code which is not fully tested
2. I wasn't yet aware of Arrays in gnuplot.
Actually, in my code it should have been a string and read Index1 = "A
B C D E F G H I"...
3. It's a good idea to create the filename via formula and sprintf()
So with your suggestions the following code looks compact and is tested
;-). Color is determined by <Index2>.
However, two issues:
1. The multiplot will not finish, e.g. when none of Data_E-files exist.
How to cope with this?
It looks like a threefold nested "for loop" is also possible. But how to
move on to the next multiplot and place "label 1 Data_<Index1>"
in every plot?
2. minor thing: Files with different <Index3> are just repeated
measurements of Data_<Index1>_<Index2> and do not need individual titles
in the key. How would it be possible to have just one per
Data_<Index1>_<Index2> per plot?
### start gnuplot code
# DataFile name scheme: Data_<Index1>_<Index2>_<Index3>.dat
# Plot all <Index1> into one plot
# Plot all <Index2> with same color
#
reset
set colorsequence classic
array Index1[9] = ["A", "B", "C", "D", "E", "F", "G", "H", "I"]
array Index2[6] = ["a", "b", "c", "d", "e", "f"]
MaxIndex3 = 3
FileName(i,j,k) = sprintf("Data_%s_%s_%d.dat",i,j,k)
set multiplot layout 3,3
do for [i=1:|Index1|] {
set label 1 sprintf("Data_%s",Index1[i]) at graph 0.05,0.9
plot for [j=1:|Index2|] for [k=1:MaxIndex3]
FileName(Index1[i],Index2[j],k) w l lc j title sprintf("%s",Index2[j])
}
unset multiplot
### end gnuplot code
|
|
From: ivana r. <iva...@mf...> - 2017-08-05 14:38:55
|
Hi Theo,
> 1. The multiplot will not finish, e.g. when none of Data_E-files exist.
> How to cope with this?
As told before, you may use empty plots.
> It looks like a threefold nested "for loop" is also possible. But how to
> move on to the next multiplot and place "label 1 Data_<Index1>"
> in every plot?
It would be sometimes useful if "title NONE" does the same as
"notitle" and if one could alter iteration variable inside the loop.
Anyhow, there are few possible solutions. The following code shows one
of them.
### start gnuplot code
# DataFile name scheme: Data_<Index1>_<Index2>_<Index3>.dat
# Plot all <Index1> into one plot
# Plot all <Index2> with same color
#
# test a version
if ( GPVAL_VERSION < 5.2 ) {
printerror "Need at least version 5.2"
exit 1
}
# clear session, set favorite colors
reset
set colorsequence classic
# OS-dependence
___system = strstrt(GPVAL_SYSNAME, "Windows") #1: Windows; 0: others
__list = ___system ? "dir /b " : "ls "
__nowhere = ___system ? "NUL" : "/dev/null"
__silent = ' 2> '.__nowhere
# Indexes
array Index1[9] = ["A", "B", "C", "D", "E", "F", "G", "H", "I"]
array Index2[6] = ["a", "b", "c", "d", "e", "f"]
array first[|Index2|]
MinIndex3 = 1
MaxIndex3 = 3
if ( MaxIndex3 < MinIndex3 || MaxIndex3 > 9 ) {
printerror "Limits for Index3 are not set properly."
exit 2
}
# data files (at the 3rd position accepts strings and integers, both length 1)
FileName(i, j, k) = sprintf("Data_%s_%s_%.1s.dat", i, j, "".k)
# go on
set multiplot layout 3,3
set key right
#the main loop
do for [i=1:|Index1|] {
# something to plot?
# preprocessing init
NoFile = 1
# try to find sets and first files in them
do for [j=1:|Index2|] {
# list all files in the current "i-j" set
first[j] = files = system(__list.FileName(Index1[i], Index2[j], "?").__silent)
# get Index3 of the first existing file in the given range
do for [k=1:words(files)] {
flen = strlen(first[j] = word(files, k))
first[j] = first[j][flen-4:flen-4]
if ( first[j] >= MinIndex3 && first[j] <= MaxIndex3 ) {
break
} else {
first[j]=""
}
}
# proceed the result
if ( first[j] eq "" ) {
# minimize warning for empty sets
first[j] = MaxIndex3
} else {
# at least one set was found for current "i"
NoFile = 0
}
}
# preprocessing ended
# Choose what to plot
if (NoFile) {
set notics
set key title "Nothing to plot for Data_".Index1[i]
plot [0:10] [0:10] 1/0 not
} else {
set tics
set key title "Data_".Index1[i]
plot \
for [j=1:|Index2|] FileName(Index1[i], Index2[j], first[j]) \
w l lc j title sprintf("%s", Index2[j]), \
for [j=1:|Index2|] for [k=(first[j]):MaxIndex3] \
FileName(Index1[i], Index2[j], k) w l lc j not
}
}
unset multiplot
### end gnuplot code
So, the first file of set is find and plot with the title, while
remaining items are plotted without (actually the first one is also
repeated to prevent some limit trouble cases).
Another solution is, e.g., to plot real sets of files only and
determine the linecolor from the file name.
The above code was never tested on Windows, so you may need to tune
some system specific variables.
> It looks like a threefold nested "for loop" is also possible. But how to
> move on to the next multiplot and place "label 1 Data_<Index1>"
> in every plot?
I'm not sure what would like to code. Could you give an example?
Iva
|
|
From: theozh <th...@gm...> - 2017-08-08 06:54:45
|
Hi Iva,
thank you very much for your multi-OS, all-inclusive code...
Well, the codes get's pretty lengthy and complicated in order to check
all sorts of things. This probably can't be avoided.
I'm sure with some testing and maybe some modifications your code will
work and will give the desired result :-).
>> It looks like a threefold nested "for loop" is also possible. But how to
>> move on to the next multiplot and place "label 1 Data_<Index1>"
>> in every plot?
>
> I'm not sure what would like to code. Could you give an example?
>
Well, as I said: I have data files with a clear file name structure, namely
"Data_<Index1>_<Index2>_<Index3>.dat"
The goal is to decide depending on the filename where to plot the data
in a multiplot and how to color it. Sounds like a rather simple task...
I currently see basically two options:
A) put all exisiting files into a list and depending on the filename
distribute it into the corresponding plot. However, deciding based on
the filename in which graph to plot the data, would probably require
some kind of "Regular Expressions" within gnuplot which I do not see how
to realize.
B) loop all possible filenames in a threefold plot loop within a certain
maximum range. Depending on how large the <Index> ranges are you might
get lengthy list of error messages (but, ok, who cares?). However, with
a threefold plot loop I don't (yet) see a way to distribute the data
into the corresponding multiplots.
Since I do not see a solution for A) and for B) is probably has to be a
mix of both. Or as your code is... three loops with a few if {} cases
and helper variables...
I just thought, I overlooked a very simple, short and efficient method.
Seems not to be the case. Thank you for your help!
|
|
From: ivana r. <iva...@mf...> - 2017-08-13 09:48:11
|
Hi Theo, I've noticed that 'title "" ' erase the corresponding key item, so the code could be bit easier...much easier if onecould be sure that Index3=1 always exists prior to higher values. > I just thought, I overlooked a very simple, short and efficient method. > Seems not to be the case. well, 1, gnuplot is a "unix" program. As such, it can do something quite well: to plot. It doesn't care about files. It supposes that you know what you want to plot and provide requested files. Under Unix/Linux, It'd be the default solution to generate a plot script for each directory outside gnuplot. So, the primary task is how simple can be this shell/pearl/... script. Secondly, it's nice that you can even do inside script as well now in V5+, although you need to run syscalls. (Personally, I'd appreciate if I can disable all syscalls on startup at all. Otherwise I need to check if there are commands such 'rm -rf /', 'chmod -R a+r ~/.ssh', etc. in other-hands scripts.) 2, gnuplot is currently highly developed. Iteration and arrays will probably continue development. Currently, on my wish-list there is (1) a possibility to index arrays by letters OR get ascii code of chars, and (2) to manipulate the iterating variable. Both would helpful also in your case. And you should install Ethan's patch sourceforge.net/p/gnuplot/bugs/_discuss/thread/fcab9784/ af51/attachment/iteration_bug_v5.patch for correct execution of iterations. 3, As I mentioned, the code can be rewritten to be more "word"-oriented. In my opinion, such a code is more straight. You can found one here: pebble.matfyz.cz/for_Theo.gplot (I previously choose the pure-array version since you seem you like it.) 4, note that the code may be simpler if one would know what you prefer to do if something. E.g., do you prefer make empty plots to keep the Index1-based layout or would it be OK if plots fold? Is there sometimes void in Index3 series? Etc. 5, under Unix/Linux, you can avoid warnings redirecting fd2: - run "gnuplot 2>/dev/null" - and inside code 'set print "/dev/stdout"' - note that this disable warnings as well as errors. To see errors, you can run e.g., ``if (GPVAL_ERRNO) { print "Error ", GPVAL_ERRNO, ": ", GPVAL_ERRMSG; reset error; }'' when ever you except any. (I'm not sure how to convert this for Windows, but I guess it should be possible to work with STDOUT and STDERR there.) Sincerely Iva <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> Virusfritt. www.avast.com <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> |
|
From: Ethan A M. <EAM...@gm...> - 2017-08-13 17:19:36
|
On Sunday, 13 August 2017 11:48:03 ivana richterova wrote:
> 1, gnuplot is a "unix" program. As such, it can do something quite
> well: to plot. It doesn't care about files. It supposes that you know
> what you want to plot and provide requested files.
>
> Under Unix/Linux, It'd be the default solution to generate a plot
> script for each directory outside gnuplot. So, the primary task is how
> simple can be this shell/pearl/... script.
>
> Secondly, it's nice that you can even do inside script as well now in
> V5+, although you need to run syscalls. (Personally, I'd appreciate if
> I can disable all syscalls on startup at all. Otherwise I need to
> check if there are commands such 'rm -rf /', 'chmod -R a+r ~/.ssh',
> etc. in other-hands scripts.)
This idea has been raised before.
The major problem I see with it is that gnuplot gains a lot of power from
being able to filter input and output through pipes. It is common to filter
input data through standard system tools like awk or grep, or convert
output on-the-fly using image conversion or display utilities.
Or both at once:
gnuplot> set term png
gnuplot> set output "| display png:-"
gnuplot> plot "< grep May annual.dat"
The concern is that every time you create a pipe you open a window
of vulnerability. If you are operating in an untrusted environment then
the use of pipes is exactly as dangerous as direct use of system
or shell commands. It would make no sense to disable one but not
the other, and a non-piping gnuplot would be substantially less useful.
Current gnuplot does its initial setup in a restricted mode that
disables both system commands and pipes. Neither is permitted in
a system or private initialization file ~/.gnuplot or $SOMEWHERE/gnuplot.rc
That provides a minimal level of protection against issuing the "gnuplot"
command in a potentially booby-trapped environment, but once the
program is initialized and accepting user commands pipes are reenabled.
> 2, gnuplot is currently highly developed. Iteration and arrays will
> probably continue development. Currently, on my wish-list there is (1)
> a possibility to index arrays by letters OR get ascii code of chars,
> and (2) to manipulate the iterating variable. Both would helpful also
> in your case.
Characters as numerical array indices does not seem feasible.
gnuplot accepts (indeed defaults to) multibyte encoding, usually UTF-8.
You can manipulate a multibyte character easily enough, e.g.
gnuplot> s = "mør"
gnuplot> print s[2:2]
ø
but the only character->numerical mapping that might be feasible is
mapping to a unicode code point.
I suppose one could have associative arrays, or LEAP/SAIL style
associative triplets. I'd want to see a solid use case for such an
extension before considering it further. Do you have an example
application for which using a character as an array index is a big win?
Ethan
|
|
From: ivana r. <iva...@mf...> - 2017-08-14 14:29:24
|
Hi Ethan,
>> I can disable all syscalls on startup at all. Otherwise I need to
>> check if there are commands such 'rm -rf /', 'chmod -R a+r ~/.ssh',
> This idea has been raised before.
> The major problem I see with it is that gnuplot gains a lot of power from
> being able to filter input and output through pipes.
yes, I know. Pipes are nice and useful, but safe-check of other-hand
scripts quite annoying. Maybe it would helpful widespread if there are
strict simple rules for pipes and syscalls which can be demanded
irrevocably at startup via init-file, as:
- exact list of allowed commands including full path (e.g. /bin/grep,
/bin/cat) with possibility to define aliases for them (e.g.,
grep=/bin/grep)
- do not read or write and access files and directories (except
executing the allowed commands) outside the current directory tree at
startup.
- namely allow file extensions for files that can be (over)written.
- allow or not creating new subdirs.
- define permissions for new files and dirs.
>> probably continue development. Currently, on my wish-list there is (1)
>> a possibility to index arrays by letters OR get ascii code of chars,
>
> extension before considering it further. Do you have an example
> application for which using a character as an array index is a big win?
If I proceed letter-indexed files inside loops, then there are several
ways how to access filename-related variables.
I'd like, e.g., to fit files Data_<letter>.dat in one loop and used
the fitted values in another loop.
-------------------------------
1, eval, no arrays, so a "classic" way:
``
# filename format: Data_<letter>.dat
ind(filename) = filename[6:6]
# declare function myvar(x) that decodes myvarX
cls=' myvar(x)=('
do for [ i = 1 : 26 ] { cls = sprintf("%s x eq '%c' ? myvar%c :", cls,
i+96, i+96) }
cls=cls." 1/0 )
eval cls
# set all myvarX to NaN
cls=''
do for [ i = 1 : 26 ] { cls = sprintf("%s myvar%c = NaN;", cls, i+96) }
eval cls
# loop1
do for [ file in files1 ] {
fit ..... via ____myvar;
eval "myvar" . ind(file) . " = ____myvar"
}
# loop2, files2 can differ from files1
plot for [ file in files2 ] file t sprintf("fit: %.2g", myvar(ind(file)))
# loop3, whole range
all=''
do for [ i = 1 : 26 ] { all = sprintf("%s %c", cls, i+96) }
filename(x)="Data_".x.".dat"
plot for [ x in all ] filename(x) t sprintf("fit: %.2g", myvar(x))
''
-------------------------------
2, index an array by associate "internal" varnames ____<letter>____
for a..z with numbers 1..26:
``
# declare vars ____<letter>____
cls = ''
do for [ i = 1 : 26 ] { cls = sprintf("%s ____%c____ = %i;", cls, i+96, i) }
eval cls
# convert letter to index array (set 1 for "")
letter2number(c) = ( c eq "" ? 1 : value( "____".c."____") )
# filename format: Data_<letter>.dat
ind(filename)=letter2number(filename[6:6])
# set array myvar[26] to NaN
array myvar[26]
do for [ i = 1 : 26 ] { myvar[i] = NaN }
# loop1
do for [ file in files1 ] {
fit ..... via myvar[ind(file)];
}
# loop2, files2 can differ from files1
plot for [ file in files2 ] file t sprintf("fit: %.2g", myvar[ind(file)])
# loop3, whole range
array all[|myvar|]
do for [ i = 1 : |all| ] { all[i] = sprintf("%c", i+96) }
filename(x)="Data_".x.".dat"
plot for [ i = 1 : |all| ] filename(x = all[i]) t sprintf("fit: %.2g", myvar(x))
''
-------------------------------
3, index arrays via letters:
# currently not implemented.
``
# filename format: Data_<letter>.dat
ind(filename) = filename[6:6]
# set array myvar["a":"z"] to NaN
array myvar["a":"z"]
do for [ x = "a" : "z" ] { myvar[x] = NaN }
# loop1
do for [ file in files1 ] {
fit ..... via myvar[ind(file)];
}
# loop2, files2 can differ from files1
plot for [ file in files2 ] file t sprintf("fit: %.2g", myvar[ind(file)])
# loop3, whole range
filename(x)="Data_".x.".dat"
plot for [ x = "a" : "z" ] filename(x) t sprintf("fit: %.2g", myvar(x))
''
-------------------------------
disclaimer: the example code is not tested so it can miss some bracket etc.
-------------------------------
As I said I do not miss associative arrays yet, I'd preferred to find
a way without named letter variables (since they are not universal),
how to convert basic ascii letters to numbers as well.
Anyhow, implementing basic ascii letters as
predecessor/successor-system (in a way ``for [ x = "a":"g" ]'' would
be also nice -- at least looking intuitively in some cases.
Iva
|
|
From: Ethan M. <eam...@gm...> - 2017-08-14 21:47:03
|
>
> Anyhow, implementing basic ascii letters as
> predecessor/successor-system (in a way ``for [ x = "a":"g" ]'' would
> be also nice -- at least looking intuitively in some cases.
I don't like the idea of adding any syntax that depends on ascii encoding.
I would instead suggest a scheme like
gnuplot> array CityNames[25] =
> ["Atlanta","Boston","Charleston","Dallas","Ephrata","Fargo",,,]
> gnuplot> City(letter) = CityNames[
> strstrt("abcdefghijklmnopqrstuvwxyz",letter) ]
> gnuplot> print City("d")
> Dallas
> gnuplot>
That works as shown for ascii a-z but works equally well for non-ascii
gnuplot> GreekCity(letter) = GreekCityNames[
> strstrt("αβγδεζηθικλμνξοπρςστυφχψω", letter) ]
> gnuplot> print GreekCity("β")
> Βούλα
> gnuplot>
>
Ethan
On Mon, Aug 14, 2017 at 7:29 AM, ivana richterova <
iva...@mf...> wrote:
> Hi Ethan,
>
> >> I can disable all syscalls on startup at all. Otherwise I need to
> >> check if there are commands such 'rm -rf /', 'chmod -R a+r ~/.ssh',
>
> > This idea has been raised before.
> > The major problem I see with it is that gnuplot gains a lot of power from
> > being able to filter input and output through pipes.
>
> yes, I know. Pipes are nice and useful, but safe-check of other-hand
> scripts quite annoying. Maybe it would helpful widespread if there are
> strict simple rules for pipes and syscalls which can be demanded
> irrevocably at startup via init-file, as:
>
> - exact list of allowed commands including full path (e.g. /bin/grep,
> /bin/cat) with possibility to define aliases for them (e.g.,
> grep=/bin/grep)
> - do not read or write and access files and directories (except
> executing the allowed commands) outside the current directory tree at
> startup.
> - namely allow file extensions for files that can be (over)written.
> - allow or not creating new subdirs.
> - define permissions for new files and dirs.
>
> >> probably continue development. Currently, on my wish-list there is (1)
> >> a possibility to index arrays by letters OR get ascii code of chars,
> >
> > extension before considering it further. Do you have an example
> > application for which using a character as an array index is a big win?
>
> If I proceed letter-indexed files inside loops, then there are several
> ways how to access filename-related variables.
>
> I'd like, e.g., to fit files Data_<letter>.dat in one loop and used
> the fitted values in another loop.
>
> -------------------------------
> 1, eval, no arrays, so a "classic" way:
> ``
> # filename format: Data_<letter>.dat
> ind(filename) = filename[6:6]
>
> # declare function myvar(x) that decodes myvarX
> cls=' myvar(x)=('
> do for [ i = 1 : 26 ] { cls = sprintf("%s x eq '%c' ? myvar%c :", cls,
> i+96, i+96) }
> cls=cls." 1/0 )
> eval cls
>
> # set all myvarX to NaN
> cls=''
> do for [ i = 1 : 26 ] { cls = sprintf("%s myvar%c = NaN;", cls, i+96) }
> eval cls
>
> # loop1
> do for [ file in files1 ] {
> fit ..... via ____myvar;
> eval "myvar" . ind(file) . " = ____myvar"
> }
>
> # loop2, files2 can differ from files1
> plot for [ file in files2 ] file t sprintf("fit: %.2g", myvar(ind(file)))
>
> # loop3, whole range
> all=''
> do for [ i = 1 : 26 ] { all = sprintf("%s %c", cls, i+96) }
> filename(x)="Data_".x.".dat"
> plot for [ x in all ] filename(x) t sprintf("fit: %.2g", myvar(x))
> ''
> -------------------------------
>
> 2, index an array by associate "internal" varnames ____<letter>____
> for a..z with numbers 1..26:
> ``
> # declare vars ____<letter>____
> cls = ''
> do for [ i = 1 : 26 ] { cls = sprintf("%s ____%c____ = %i;", cls, i+96, i)
> }
> eval cls
> # convert letter to index array (set 1 for "")
> letter2number(c) = ( c eq "" ? 1 : value( "____".c."____") )
> # filename format: Data_<letter>.dat
> ind(filename)=letter2number(filename[6:6])
>
> # set array myvar[26] to NaN
> array myvar[26]
> do for [ i = 1 : 26 ] { myvar[i] = NaN }
>
> # loop1
> do for [ file in files1 ] {
> fit ..... via myvar[ind(file)];
> }
>
> # loop2, files2 can differ from files1
> plot for [ file in files2 ] file t sprintf("fit: %.2g", myvar[ind(file)])
>
> # loop3, whole range
> array all[|myvar|]
> do for [ i = 1 : |all| ] { all[i] = sprintf("%c", i+96) }
> filename(x)="Data_".x.".dat"
> plot for [ i = 1 : |all| ] filename(x = all[i]) t sprintf("fit: %.2g",
> myvar(x))
> ''
> -------------------------------
>
> 3, index arrays via letters:
> # currently not implemented.
>
> ``
> # filename format: Data_<letter>.dat
> ind(filename) = filename[6:6]
>
> # set array myvar["a":"z"] to NaN
> array myvar["a":"z"]
> do for [ x = "a" : "z" ] { myvar[x] = NaN }
>
> # loop1
> do for [ file in files1 ] {
> fit ..... via myvar[ind(file)];
> }
>
> # loop2, files2 can differ from files1
> plot for [ file in files2 ] file t sprintf("fit: %.2g", myvar[ind(file)])
>
> # loop3, whole range
> filename(x)="Data_".x.".dat"
> plot for [ x = "a" : "z" ] filename(x) t sprintf("fit: %.2g", myvar(x))
> ''
> -------------------------------
>
> disclaimer: the example code is not tested so it can miss some bracket etc.
> -------------------------------
>
> As I said I do not miss associative arrays yet, I'd preferred to find
> a way without named letter variables (since they are not universal),
> how to convert basic ascii letters to numbers as well.
>
> Anyhow, implementing basic ascii letters as
> predecessor/successor-system (in a way ``for [ x = "a":"g" ]'' would
> be also nice -- at least looking intuitively in some cases.
>
> Iva
>
|
|
From: ivana r. <iva...@mf...> - 2017-08-15 05:52:48
|
Hi Ethan,
> I would instead suggest a scheme like
>
> gnuplot> array CityNames[25] =
>> ["Atlanta","Boston","Charleston","Dallas","Ephrata","Fargo",,,]
>> gnuplot> City(letter) = CityNames[
>> strstrt("abcdefghijklmnopqrstuvwxyz",letter) ]
>> gnuplot> print City("d")
>> Dallas
>> gnuplot>
the scheme looks great. I hope it will be postponed to demos. Thanks
for the tip!
Iva
|