bien, sigo volviendo a esto - así que creo Necesitaba la siguiente aclaración aquí:
Dado que gnuplot
, bueno, traza conjuntos de datos como trazados 2D, es un hecho que de alguna manera se ocupa de estructuras 2D o matrices. Es por eso que alguien viene de C, Perl, Python, etc.pensaría naturalmente que es posible indexar de alguna manera el conjunto de datos, y ser capaz de recuperar un valor en una fila y posición de columna; decir, algo así como lo siguiente pseudocódigo:
my_val = "inline.dat"[1][2] # get value in 1st row and 2nd column
O, alternativamente, pseudocódigo:
my_dataset = parse_dataset("inline.dat")
my_val = get_value(my_dataset, 1, 2)
Y pasé un montón de tiempo buscando algo como esto en gnuplot
, y no puede encuentre algo así (un acceso variable directo a los valores del conjunto de datos a través del índice de fila y columna). Parece que el único que uno puede hacer, es plot
el conjunto de datos - y posiblemente acceda a los valores allí, a través de la función llamada en la parte using
.
Eso quiere decir, que si quiero encontrar algunos valores del conjunto de datos de gnuplot
, me tengo para recorrer el conjunto de datos llamando plot
- incluso si necesito esos valores, precisamente para construir una adecuada plot
comunicado :)
Y que tipo de mesa no les gusta que, pensando que la primera plot
puede de alguna manera tornillo hasta el segundo después :)
Sin embargo, como finding maximum value in a data set and subtracting from plot - comp.graphics.apps.gnuplot | Google Groups puntos, uno puedeplot
a un archivo, también stdout
o /dev/null
, y obtener un plano ASCII formateado - así al menos lo que pueda redirigir la primera llamada de esa manera, para que no interfiera con el acto terminal de trazado de la segunda llamada al plot
.
Por lo tanto, a continuación es otro ejemplo de código, donde el primer elemento de la primera columna en el conjunto de datos "inline.dat
" se recupera a través de:
# print and get (in _drcv) first value of first data column:
eval print_dataset_row_column("inline.dat",0,1)
# must "copy" the "return" value manually:
first = _drcv
... por lo que entonces la trama puede ser compensado por first
directamente la llamada plot
.
Nota vez más que print_dataset_row_column
llamadas plot
(redireccionados vía set table
a /dev/null
) - y, como tal, cada vez que la llame para recuperar un único valor , que hará que la iteración a través de la totalidad de conjunto de datos! Por lo tanto, si necesita el primer elemento y el último elemento (y posiblemente otros elementos, como some basic statistics with gnuplot), probablemente sea mejor volver a escribir print_dataset_row_column
para que recupere todos los elementos de una vez.
También sería necesaria una reescritura print_dataset_row_column
si utiliza algunos formatos especiales en su conjunto de datos y la línea using
. Tenga en cuenta que en este ejemplo, la tercera columna es una cadena, que no se acepta de forma predeterminada como una columna de datos de trazado; y como tal, las llamadas a las funciones print_dataset_*
fallarán si tienen que tratar con ellas (vea también gnuplot plot from string).
Así que aquí es el código de ejemplo - vamos a llamarlo test.gp
:
# generate data
system "cat > ./inline.dat <<EOF\n\
10.0 1 a 2\n\
10.2 2 b 2\n\
10.4 3 a 2\n\
10.6 4 b 2\n\
10.8 5 c 7\n\
11.0 5 c 7\n\
EOF\n"
### "dry-run" functions:
# iterate through dataset by calling
# `plot`, redirected to file output (via `set table`)
#
# note: eval (not print) cannot be inside a user-defined function:
# a(b) = eval('c=3') ; print a(4) ==> "undefined function: eval"
# nor you can make multistatement functions with semicolon:
# f(x) = (2*x ; x=x+2) ==> ')' expected (at ';')
#
# so these functions are defined as strings - and called through eval
#
# through a single column spec in `using`:
# (`plot` prints table to stdout)
#
print_dataset_column(filename,col) = "set table '/dev/stdout' ;\
plot '".filename."' using ".col." ;\
unset table"
#
# through two column spec in `using`:
# (`plot` prints table to stdout)
#
print_dataset_twocolumn(filename,colA,colB) = "set table '/dev/stdout' ;\
plot '".filename."' using ".colA.":".colB." ;\
unset table"
#
# print value of row:column in dataset, saving it as _drcv variable
#
# init variable
#
_drcv = 0
#
# create _drc helper function; note assign and "return" in
# true branch of ternary clause
#
_drc(ri, colval, col) = (ri == _row) ? _drcv = colval : colval
#
# define the callable function:
#
print_dataset_row_column(filename,row,col) = "_row = ".row." ;\
set table '/dev/null' ;\
plot '".filename."' using (_drc($0, $".col.", ".col.")) ;\
unset table ;\
print '".filename."[r:".row.",c:".col."] = ',_drcv"
#
#
### end dry run functions
#
# test print_dataset_* functions:
#
eval print_dataset_column("inline.dat",0)
eval print_dataset_twocolumn("inline.dat",0,0)
# string column - cannot directly:
# set table '/dev/stdout' ;plot 'inline.dat' using 3 ;unset table
# ^
# line 69: warning: Skipping data file with no valid points
# line 69: x range is invalid
#~ eval print_dataset_column("inline.dat",3)
eval print_dataset_column("inline.dat",1)
eval print_dataset_twocolumn("inline.dat",1,2)
eval print_dataset_row_column("inline.dat",4,1)
eval print_dataset_row_column("inline.dat",4,2)
# will fail - 3 is string column
# line 82: warning: Skipping data file with no valid points
# line 82: x range is invalid
#~ eval print_dataset_row_column("inline.dat",4,3)
#
# do a plot offset by first element position
#
# print and get (in _drcv) first value of first data column:
eval print_dataset_row_column("inline.dat",0,1)
# must "copy" the "return" value manually:
first = _drcv
# ranges
set yrange [0:8]
set xrange [0:11.5]
# plot finally:
plot "inline.dat" using ($1-first):2 with impulses linewidth 2
Cuando este script se llama, el conjunto de datos en el OP se traza trasladó, a partir de 0 - y la siguiente se emite en terminal (las primeras impresiones de la tabla son la salida real de plot
redirigido a través de set table
a stdout
):
gnuplot> load './test.gp'
# Curve 0 of 1, 6 points
# Curve title: "'inline.dat' using 0"
# x y type
0 0 i
1 1 i
2 2 i
3 3 i
4 4 i
5 5 i
# Curve 0 of 1, 6 points
# Curve title: "'inline.dat' using 0:0"
# x y type
0 0 i
1 1 i
2 2 i
3 3 i
4 4 i
5 5 i
# Curve 0 of 1, 6 points
# Curve title: "'inline.dat' using 1"
# x y type
0 10 i
1 10.2 i
2 10.4 i
3 10.6 i
4 10.8 i
5 11 i
# Curve 0 of 1, 6 points
# Curve title: "'inline.dat' using 1:2"
# x y type
10 1 i
10.2 2 i
10.4 3 i
10.6 4 i
10.8 5 i
11 5 i
inline.dat[r:4,c:1] = 10.8
inline.dat[r:4,c:2] = 5.0
inline.dat[r:0,c:1] = 10.0
Impresionante - muchas gracias por la respuesta concisa, @Sunhwan Jo - ¡Salud! – sdaau
sí, PERO, ¿y si está interesado en el * primer * elemento de la serie de datos, que no necesariamente tiene que ser el mínimo? – TMOTTM
@TMOTTM luego tiene que ajustar el script externo para usar solo el primer elemento (usando awk directamente sin la parte de clasificación). – EverythingRightPlace