Occurs with latest tip (77db33714257)
$ cat test.data April 24 2019,694000 $ cat test.script set datafile separator ',' set xdata time set timefmt "%B %d %Y" set table "temp" separator comma print "preplot" plot "test.data" using (strftime('%B %d %Y', $$1)):2 with table print "postplot" $ ~/src/personal/gnuplot-gnuplot-main/src/gnuplot -c test.script preplot [HANG]
I traced though the code and strftime is being entered with NaN and goes into an endless noop. The NaN is pushed onto the stack in f_column() as a result of the code block:
else if (column < 1 || column > df_no_cols) { undefined = TRUE; /* Nov 2014: This is needed in case the value is referenced */ /* in an expression inside a 'using' clause. */ push(Gcomplex(&a, not_a_number(), 0.0));
But not being familiar with the code it seemed easier to open a bug.
You can see the NaN issue literally if you change strftime() to gprintf("%s")
$ cat test.data April 24 2019,694000 $ cat test.script set datafile separator ',' set xdata time set timefmt "%B %d %Y" set table "temp" separator comma print "preplot" plot "test.data" using (gprintf("%s", $$1)):2 with table print "postplot" $ ~/src/personal/gnuplot-gnuplot-main/src/gnuplot -c test.script preplot postplot $ cat temp nan, 694000
There seem to be some issues with hpw the text is formatted in the above. Here is tarball of the files.
Diff:
I suspect the key issue here is that you're mixing up the two possible ways of handling time/date data. You should either use
xdata time
mode throughout (withset format x
to determine the output), or not at all (strftime(..., strptime(strcolumn()))
).It shouldn't hang.
I didn't pick that syntax out of choice, I can't get any of the simpler options to work.
It's a 10 line example. with a provided input file. If you have a solution can you paste a similar number of lines that show what you're suggesting? The goal is to write out a temp table which has the time/date in the same "%B %d %Y" format so the temp table can be processed by a subsequent plot command.
Just doing "using 1:2" doesn't work as the time is written out as %f. Specifying "set format x "%B %d %Y" changes nothing. Trying to have a subsequent plot use the temp data results in the wonderfully cryptic error "Need full using spec for x time data". If the time was written as integer seconds since epoch) perhaps "set timefmt "%s" could parse it.
$ cat test2.script
set datafile separator ','
set xdata time
set timefmt "%B %d %Y"
set table "temp" separator comma
print "preplot"
set format x "%B %d %Y"
plot "test.data" using 1:2 with table
print "postplot"
$ ~/src/personal/gnuplot-gnuplot-main/src/gnuplot -c test2.script
preplot
postplot
$ cat temp
1.55606e+09, 694000
I will re-order the if/else codeblock in time.c so that NaN does not cause an infinite loop. But that will do nothing to address the question of why NaN is being generated in the first place.
Can you reduce your problem case to a single-line command that return NaN when asked to parse a time string? I can't work out from your script where exactly this comes from.
You may have simplified the example too much to capture what you really need, but as stated it seems you could skip all the time stuff and just save the first column as a string?
plot "test.data" using (sprintf("%s", strcol(1)):2 with table
Turns out I'd not simplied too much as the above solution works (needs one extra close parenthesis). THANK YOU. I wasn't trying to argue, rather I had no idea what syntax I needed to implement Hans' suggestion. strcol(1) was what I needed to know.
I am curious why I can't just do "using 1:2", i.e why when doing it this spits (1) out as %f with exponent.
Last edit: Tony Jones 2019-04-27
Normally gnuplot deals with numerical input, and if it encounters a string it tries to convert it to a number. There are exceptions where gnuplot knows that in fact the content must be a string rather than a number, e.g.
plot foo using 1:2:3 with labels
where it knows column 3 must be a string since it is being used to load a label. You can force the content to be treated as a string by accessing it through the function strcol().I now realize that the example I gave can be made even simpler.
strcol(1)
is already a string, so you don't need to print it again with sprintf.