Minor changes. Added save() method

This commit is contained in:
Giorgio Calderone 2019-01-14 15:27:55 +01:00
parent d384d9f4e0
commit a1f9f3e0ca
3 changed files with 360 additions and 397 deletions

101
README.md
View File

@ -70,46 +70,53 @@ That's it for the first plots. The syntax should be familiar to most gnuplot use
Note that this simple example already covers the vast majority of use cases, since the remaining details of the plot can be easily tweaked by adding the appropriate gnuplot command. Also note that you would barely recognize the Julia language by just looking at the `@gp` call since **Gnuplot.jl** aims to be mostly transparent: the user is supposed to focus only on the data and on the gnuplot commands, rather than the package details. Note that this simple example already covers the vast majority of use cases, since the remaining details of the plot can be easily tweaked by adding the appropriate gnuplot command. Also note that you would barely recognize the Julia language by just looking at the `@gp` call since **Gnuplot.jl** aims to be mostly transparent: the user is supposed to focus only on the data and on the gnuplot commands, rather than the package details.
Let's have a look to the REPL output of the above command (this may If you set the verbose option (`setverbosity(true)`, which is `false` by default) you'll be able to see all the communication taking place between the **Gnuplot.jl** package and the underlyng Gnuplot process. Repeating the last command:
differ on your computer since we used random numbers):
```Julia ```Julia
GNUPLOT (default) -> reset session julia> @gp("set key horizontal", "set grid", title="My title",
GNUPLOT (default) -> print GPVAL_TERM xrange=(-7,7), ylabel="Y label", xlab="X label",
GNUPLOT (default) qt x, y, "w l t 'Real model' dt 2 lw 2 lc rgb 'red'",
GNUPLOT (default) -> print GPVAL_TERMOPTIONS x, y+noise, e, "w errorbars t 'Data'");
GNUPLOT (default) 0 title "Gnuplot.jl: default" font "Sans,9" GNUPLOT (default) reset session
GNUPLOT (default) -> set key horizontal GNUPLOT (default) print GPVAL_TERM
GNUPLOT (default) -> set grid GNUPLOT (default) -> qt
GNUPLOT (default) -> set title 'My title' GNUPLOT (default) print GPVAL_TERMOPTIONS
GNUPLOT (default) -> set xrange [-7:7] GNUPLOT (default) -> 0 title "Gnuplot.jl: default" font "Sans,9"
GNUPLOT (default) -> set ylabel 'Y label' GNUPLOT (default) set key horizontal
GNUPLOT (default) -> set xlabel 'X label' GNUPLOT (default) set grid
GNUPLOT (default) -> $data0 << EOD GNUPLOT (default) set title 'My title'
GNUPLOT (default) -> -6.283185307179586 1.2258873407968363 GNUPLOT (default) set xrange [-7:7]
GNUPLOT (default) -> -6.156252270670907 1.1443471266509504 GNUPLOT (default) set ylabel 'Y label'
GNUPLOT (default) -> -6.029319234162229 1.05377837392046 GNUPLOT (default) set xlabel 'X label'
GNUPLOT (default) $data0 << EOD
GNUPLOT (default) -6.283185307179586 1.2258873407968363
GNUPLOT (default) -6.156252270670907 1.1443471266509504
GNUPLOT (default) -6.029319234162229 1.05377837392046
GNUPLOT (default) ... GNUPLOT (default) ...
GNUPLOT (default) -> $data102 << EOD GNUPLOT (default) EOD
GNUPLOT (default) -> -6.283185307179586 1.0050125770987044 0.5 GNUPLOT (default) $data1 << EOD
GNUPLOT (default) -> -6.156252270670907 0.45687609191841705 0.5 GNUPLOT (default) -6.283185307179586 1.516291874781302 0.5
GNUPLOT (default) -> -6.029319234162229 1.4782789213307108 0.5 GNUPLOT (default) -6.156252270670907 1.5490769687987143 0.5
GNUPLOT (default) -6.029319234162229 0.30753349072971314 0.5
GNUPLOT (default) ... GNUPLOT (default) ...
GNUPLOT (default) -> plot \ GNUPLOT (default) EOD
GNUPLOT (default) set key horizontal
GNUPLOT (default) set grid
GNUPLOT (default) set title 'My title'
GNUPLOT (default) set xrange [-7:7]
GNUPLOT (default) set ylabel 'Y label'
GNUPLOT (default) set xlabel 'X label'
GNUPLOT (default) plot \
$data0 w l t 'Real model' dt 2 lw 2 lc rgb 'red', \ $data0 w l t 'Real model' dt 2 lw 2 lc rgb 'red', \
$data102 w errorbars t 'Data' $data1 w errorbars t 'Data'
GNUPLOT (default)
``` ```
The **Gnuplot.jl** package (note the leading `GNUPLOT`...) tells us which commands are being sent to the gnuplot process and the name of the current gnuplot session (`default`). The **Gnuplot.jl** package will also print the replies from gnuplot, e.g.: The **Gnuplot.jl** package (note the leading `GNUPLOT`...) tells us which commands are being sent to the gnuplot process and the name of the current gnuplot session (`default`). The **Gnuplot.jl** package will also print the replies from gnuplot, e.g.:
``` Julia ``` Julia
julia> GnuplotGet("GPVAL_TERM"); julia> Gnuplot.exec("print GPVAL_TERM");
GNUPLOT (1) -> print GPVAL_TERM GNUPLOT (default) print GPVAL_TERM
GNUPLOT (1) qt GNUPLOT (default) -> qt
``` ```
Note the lack of ` -> ` and the different color in the reply (if your terminal is able to display colors). You may suppress all logs from **Gnuplot.jl** package by setting the verbosity level to 0, e.g.: Note the different color in the reply (if your terminal is able to display colors).
``` Julia
@gp verb=1
```
The default verbosity level is 1.
So far we have shown how to produce plots with a single command, however such task can also be performed using multiple statements. The syntax is exactly the same, but we should use the `:-` symbol at the beginning of each statement (except the first) and at the end of each statement (except the last), e.g.: So far we have shown how to produce plots with a single command, however such task can also be performed using multiple statements. The syntax is exactly the same, but we should use the `:-` symbol at the beginning of each statement (except the first) and at the end of each statement (except the last), e.g.:
``` Julia ``` Julia
@ -128,26 +135,21 @@ name = "\$MyDataSet1"
@gp :- "plot $name w points tit 'Data'" ylab="Data and model" :- @gp :- "plot $name w points tit 'Data'" ylab="Data and model" :-
@gp :- "plot $name u 1:(f(\$1)) w lines tit 'Best fit'" :- @gp :- "plot $name u 1:(f(\$1)) w lines tit 'Best fit'" :-
# ... and the residuals (the `2` here refer to the second plot in the multiplot. # ... and the residuals (the `2` here refer to the second plot in the multiplot).
@gp :- 2 xlab="X label" ylab="Residuals" :- @gp :- 2 xlab="X label" ylab="Residuals" :-
@gp :- "plot $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars notit" @gp :- "plot $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars notit"
``` ```
The **Gnuplot.jl** package also provide support for 3D plots using the `@gsp` macro in place of `@gp`, e.g.: The **Gnuplot.jl** package also provide support
``` Julia
@gsp randn(Float64, 30, 50)
```
As discussed above, **Gnuplot.jl** allows to trasparently exploit all gnuplot functionalities. E.g., we can show a random image with: As discussed above, **Gnuplot.jl** allows to trasparently exploit all gnuplot functionalities. E.g., we can show a random image with:
```Julia ```Julia
@gp randn(Float64, 30, 50) "w image" @gp randn(Float64, 30, 50) "w image"
``` ```
or show an interactive 3D plots using the `@gsp` macro in place of `@gp`, e.g.:
...or fit some mock data with: ``` Julia
@gsp randn(Float64, 30, 50)
```
Further documentation for the `@gp` and `@gsp` macros is available in the REPL by means of the `@doc` macro or by typing `?` in the REPL followed by the macro name. Further documentation for the `@gp` and `@gsp` macros is available in the REPL by means of the `@doc` macro or by typing `?` in the REPL followed by the macro name.
@ -174,13 +176,14 @@ If needed, a specific session can be started by specifying a complete file path
gp = gnuplot(:CUSTOM1, "/path/to/gnuplot/executable") gp = gnuplot(:CUSTOM1, "/path/to/gnuplot/executable")
``` ```
Also, a session can be started as a *dry* one, i.e. a session with no underlying gnuplot process: Also, a session can be started as a *dry* one, i.e. a session with no underlying gnuplot process, by omitting the path to the Gnuplot executable:
``` Julia ``` Julia
gp = gnuplot(:DRY_SESSION, dry=true) gp = gnuplot(:DRY_SESSION)
``` ```
The prupose is to create gnuplot scripts without running them, e.g: The prupose is to create gnuplot scripts without running them, e.g:
```Julia ```Julia
@gp :DRY_SESSION x x.^2 "w l" file="test.gp" @gp :DRY_SESSION x x.^2 "w l"
save("test.gp")
``` ```
The `test.gp` can then be loaded directly in gnuplot with: The `test.gp` can then be loaded directly in gnuplot with:
``` ```
@ -192,9 +195,9 @@ gnuplot> load 'test.gp'
Both the `@gp` and `@gsp` macros stores data and commands in the package state to allow using multiple statements for a single plot, or to save all data and commands on a script file. However the user may directly execute command on the underlying gnuplot process using the `gpeval` function. E.g., we can retrieve the values of the fitting parameters of the previous example: Both the `@gp` and `@gsp` macros stores data and commands in the package state to allow using multiple statements for a single plot, or to save all data and commands on a script file. However the user may directly execute command on the underlying gnuplot process using the `gpeval` function. E.g., we can retrieve the values of the fitting parameters of the previous example:
```Julia ```Julia
# Retrieve values fr a, b and c # Retrieve values fr a, b and c
a = parse(Float64, gpeval("print a")) a = parse(Float64, exec("print a"))
b = parse(Float64, gpeval("print b")) b = parse(Float64, exec("print b"))
c = parse(Float64, gpeval("print c")) c = parse(Float64, exec("print c"))
``` ```
### Terminating a session ### Terminating a session

View File

@ -2,32 +2,15 @@ __precompile__(true)
module Gnuplot module Gnuplot
using StructC14N, ColorTypes, Printf, StatsBase using StructC14N, ColorTypes, Printf, StatsBase, ReusePatterns
import Base.reset import Base.reset
import Base.write import Base.println
import Base.iterate import Base.iterate
import Base.convert import Base.convert
export gnuplot, quit, quitall, export gnuplot, quit, quitall, setverbose,
hist, @gp, @gsp, gpeval @gp, @gsp, exec, save, hist
#_____________________________________________________________________
# MACRO DEFINITIONS
#_____________________________________________________________________
# --------------------------------------------------------------------
macro inherit_fields(T)
out = Expr(:block)
for name in fieldnames(eval(T))
e = Expr(Symbol("::"))
push!(e.args, name)
push!(e.args, fieldtype(eval(T), name))
push!(out.args, e)
end
return esc(out)
end
#_____________________________________________________________________ #_____________________________________________________________________
@ -35,16 +18,14 @@ end
#_____________________________________________________________________ #_____________________________________________________________________
# -------------------------------------------------------------------- # --------------------------------------------------------------------
abstract type ○DataSource end mutable struct DataSource
mutable struct DataSource <: ○DataSource
name::String name::String
lines::Vector{String} lines::Vector{String}
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
abstract type ○SinglePlot end mutable struct SinglePlot
mutable struct SinglePlot <: ○SinglePlot
cmds::Vector{String} cmds::Vector{String}
elems::Vector{String} elems::Vector{String}
flag3d::Bool flag3d::Bool
@ -53,8 +34,7 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
abstract type ○Session end @quasiabstract mutable struct DrySession
mutable struct Session <: ○Session
sid::Symbol # session ID sid::Symbol # session ID
datas::Vector{DataSource} # data sources datas::Vector{DataSource} # data sources
plots::Vector{SinglePlot} # commands and plot commands (one entry for eahelemec plot of the multiplot) plots::Vector{SinglePlot} # commands and plot commands (one entry for eahelemec plot of the multiplot)
@ -63,9 +43,7 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
abstract type ○Process <: ○Session end @quasiabstract mutable struct Session <: DrySession
mutable struct Process <: ○Process
@inherit_fields(Session)
pin::Base.Pipe; pin::Base.Pipe;
pout::Base.Pipe; pout::Base.Pipe;
perr::Base.Pipe; perr::Base.Pipe;
@ -75,20 +53,20 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
abstract type ○State end mutable struct State
mutable struct State <: ○State sessions::Dict{Symbol, DrySession};
sessions::Dict{Symbol, ○Session}; dry::Bool
cmd::String
default::Symbol; # default session name default::Symbol; # default session name
verbosity::Bool; # verbosity level (0 - 1), default: 1 verbose::Bool; # verbosity level (true/false)
printlines::Int; # How many data lines are printed in log printlines::Int; # How many data lines are printed in log
State() = new(Dict{Symbol, ○Session}(), :default, 1, 4) State() = new(Dict{Symbol, DrySession}(), true, "gnuplot", :default, false, 4)
end end
const state = State() const state = State()
# -------------------------------------------------------------------- # --------------------------------------------------------------------
abstract type ○PackedDataAndCmds end mutable struct PackedDataAndCmds
mutable struct PackedDataAndCmds <: ○PackedDataAndCmds
data::Vector{Any} data::Vector{Any}
name::String name::String
cmds::Vector{String} cmds::Vector{String}
@ -108,7 +86,7 @@ end
Also check that gnuplot version is >= 4.7 (required to use data Also check that gnuplot version is >= 4.7 (required to use data
blocks). blocks).
""" """
function CheckGnuplotVersion(cmd::String) function CheckGnuplotVersion(cmd::AbstractString)
icmd = `$(cmd) --version` icmd = `$(cmd) --version`
proc = open(`$icmd`, read=true) proc = open(`$icmd`, read=true)
@ -129,9 +107,6 @@ function CheckGnuplotVersion(cmd::String)
if ver < v"4.7" if ver < v"4.7"
# Do not raise error in order to pass Travis CI test, since it has v4.6 # Do not raise error in order to pass Travis CI test, since it has v4.6
@warn "gnuplot ver. >= 4.7 is required, but " * string(ver) * " was found."
end
if ver < v"4.6"
error("gnuplot ver. >= 4.7 is required, but " * string(ver) * " was found.") error("gnuplot ver. >= 4.7 is required, but " * string(ver) * " was found.")
end end
@info " Gnuplot version: " * string(ver) @info " Gnuplot version: " * string(ver)
@ -139,16 +114,28 @@ function CheckGnuplotVersion(cmd::String)
end end
# --------------------------------------------------------------------
function __init__()
global state
try
ver = CheckGnuplotVersion(state.cmd)
state.dry = false
catch err
end
end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function parseKeywords(; kwargs...) function parseKeywords(; kwargs...)
template = (xrange=NTuple{2, Number}, template = (xrange=NTuple{2, Real},
yrange=NTuple{2, Number}, yrange=NTuple{2, Real},
zrange=NTuple{2, Number}, zrange=NTuple{2, Real},
cbrange=NTuple{2, Number}, cbrange=NTuple{2, Real},
title=String, title=AbstractString,
xlabel=String, xlabel=AbstractString,
ylabel=String, ylabel=AbstractString,
zlabel=String, zlabel=AbstractString,
xlog=Bool, xlog=Bool,
ylog=Bool, ylog=Bool,
zlog=Bool) zlog=Bool)
@ -171,11 +158,11 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function Session(sid::Symbol) function DrySession(sid::Symbol)
global state global state
(sid in keys(state.sessions)) && (sid in keys(state.sessions)) &&
error("Gnuplot session $sid is already active") error("Gnuplot session $sid is already active")
out = Session(sid, Vector{DataSource}(), [SinglePlot()], 1) out = DrySession(sid, Vector{DataSource}(), [SinglePlot()], 1)
return out return out
end end
@ -185,7 +172,11 @@ function getsession(sid::Symbol)
global state global state
if !(sid in keys(state.sessions)) if !(sid in keys(state.sessions))
@info "Creating session $sid..." @info "Creating session $sid..."
gnuplot(sid) if state.dry
gnuplot(sid)
else
gnuplot(sid, state.cmd)
end
end end
return state.sessions[sid] return state.sessions[sid]
end end
@ -197,7 +188,7 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
""" """
# write # println
Send a string to gnuplot's STDIN. Send a string to gnuplot's STDIN.
@ -209,11 +200,11 @@ end
- `str::String`: command to be sent; - `str::String`: command to be sent;
- `capture=false`: set to `true` to capture and return the output. - `capture=false`: set to `true` to capture and return the output.
""" """
write(gp::Session, str::AbstractString) = nothing println(gp::DrySession, str::AbstractString) = nothing
function write(gp::Process, str::AbstractString) function println(gp::Session, str::AbstractString)
global state global state
if state.verbosity if state.verbose
printstyled(color=:yellow , "GNUPLOT ($(gp.sid)) $str\n") printstyled(color=:yellow, "GNUPLOT ($(gp.sid)) $str\n")
end end
w = write(gp.pin, strip(str) * "\n") w = write(gp.pin, strip(str) * "\n")
w <= 0 && error("Writing on gnuplot STDIN pipe returned $w") w <= 0 && error("Writing on gnuplot STDIN pipe returned $w")
@ -221,13 +212,14 @@ function write(gp::Process, str::AbstractString)
return w return w
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
writeread(gp::Session, str::AbstractString) = nothing writeread(gp::DrySession, str::AbstractString) = nothing
function writeread(gp::Process, str::AbstractString) function writeread(gp::Session, str::AbstractString)
global state global state
write(gp, "print 'GNUPLOT_CAPTURE_BEGIN'") write(gp.pin, "print 'GNUPLOT_CAPTURE_BEGIN'\n")
write(gp, strip(str)) println(gp, strip(str))
write(gp, "print 'GNUPLOT_CAPTURE_END'") write(gp.pin, "print 'GNUPLOT_CAPTURE_END'\n")
flush(gp.pin) flush(gp.pin)
out = Vector{String}() out = Vector{String}()
while true while true
@ -240,31 +232,31 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
setWindowTitle(session::Session) = nothing setWindowTitle(session::DrySession) = nothing
function setWindowTitle(session::Process) function setWindowTitle(session::Session)
term = writeread(session, "print GPVAL_TERM")[1] term = writeread(session, "print GPVAL_TERM")[1]
if term in ("aqua", "x11", "qt", "wxt") if term in ("aqua", "x11", "qt", "wxt")
opts = writeread(session, "print GPVAL_TERMOPTIONS")[1] opts = writeread(session, "print GPVAL_TERMOPTIONS")[1]
if findfirst("title", opts) == nothing if findfirst("title", opts) == nothing
write(session, "set term $term $opts title 'Gnuplot.jl: $(session.sid)'") println(session, "set term $term $opts title 'Gnuplot.jl: $(session.sid)'")
end end
end end
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function reset(gp::Session) function reset(gp::DrySession)
gp.datas = Vector{DataSource}() gp.datas = Vector{DataSource}()
gp.plots = [SinglePlot()] gp.plots = [SinglePlot()]
gp.curmid = 1 gp.curmid = 1
write(gp, "reset session") println(gp, "reset session")
setWindowTitle(gp) setWindowTitle(gp)
return nothing return nothing
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function setmulti(gp::Session, mid::Int) function setmulti(gp::DrySession, mid::Int)
@assert mid >= 0 "Multiplot ID must be a >= 0" @assert mid >= 0 "Multiplot ID must be a >= 0"
for i in length(gp.plots)+1:mid for i in length(gp.plots)+1:mid
push!(gp.plots, SinglePlot()) push!(gp.plots, SinglePlot())
@ -274,7 +266,7 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function newdatasource(gp::Session, args...; name="") function newdatasource(gp::DrySession, args...; name="")
toString(n::Number) = @sprintf("%.4g", n) toString(n::Number) = @sprintf("%.4g", n)
(name == "") && (name = string("data", length(gp.datas))) (name == "") && (name = string("data", length(gp.datas)))
@ -411,9 +403,32 @@ function newdatasource(gp::○Session, args...; name="")
end end
push!(accum, "EOD") push!(accum, "EOD")
tmp = DataSource(name, accum) d = DataSource(name, accum)
push!(gp.datas, tmp) push!(gp.datas, d)
dump(gp, tmp)
# Send data immediately to gnuplot process
if typeof(gp) == concretetype(Session)
if state.verbose
for ii in 1:length(d.lines)
v = d.lines[ii]
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $v\n")
if ii == state.printlines
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) ...\n")
if ii < length(d.lines)
v = d.lines[end]
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $v\n")
end
break
end
end
end
w = write(gp.pin, "\n")
w = write(gp.pin, join(d.lines, "\n"))
w = write(gp.pin, "\n")
w = write(gp.pin, "\n")
flush(gp.pin)
end
return name return name
end end
@ -424,14 +439,14 @@ end
Send a command to gnuplot process and store it in the current session. Send a command to gnuplot process and store it in the current session.
""" """
function newcmd(gp::Session, v::String; mid::Int=0) function newcmd(gp::DrySession, v::String; mid::Int=0)
setmulti(gp, mid) setmulti(gp, mid)
(v != "") && (push!(gp.plots[gp.curmid].cmds, v)) (v != "") && (push!(gp.plots[gp.curmid].cmds, v))
(length(gp.plots) == 1) && (write(gp, v)) (length(gp.plots) == 1) && (println(gp, v))
return nothing return nothing
end end
function newcmd(gp::Session; mid::Int=0, args...) function newcmd(gp::DrySession; mid::Int=0, args...)
for v in parseKeywords(;args...) for v in parseKeywords(;args...)
newcmd(gp, v, mid=mid) newcmd(gp, v, mid=mid)
end end
@ -440,33 +455,33 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function newplotelem(gp::Session, name, opt=""; mid=0) function newplotelem(gp::DrySession, name, opt=""; mid=0)
setmulti(gp, mid) setmulti(gp, mid)
push!(gp.plots[gp.curmid].elems, "$name $opt") push!(gp.plots[gp.curmid].elems, "$name $opt")
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function quitsession(gp::○Session) function quitsession(gp::DrySession)
global state global state
delete!(state.sessions, gp.sid) delete!(state.sessions, gp.sid)
return 0 return 0
end end
function quitsession(gp::○Process) function quitsession(gp::Session)
close(gp.pin) close(gp.pin)
close(gp.pout) close(gp.pout)
close(gp.perr) close(gp.perr)
wait( gp.proc) wait( gp.proc)
exitCode = gp.proc.exitcode exitCode = gp.proc.exitcode
invoke(quitsession, Tuple{Session}, gp) invoke(quitsession, Tuple{DrySession}, gp)
return exitCode return exitCode
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
iterate(gp::Session) = ("#ID: $(gp.sid)", (true, 1, 1)) iterate(gp::DrySession) = ("#ID: $(gp.sid)", (true, 1, 1))
function iterate(gp::Session, state) function iterate(gp::DrySession, state)
(onData, mid, ii) = state (onData, mid, ii) = state
if onData if onData
if mid <= length(gp.datas) if mid <= length(gp.datas)
@ -498,88 +513,27 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# dump # function convert(::Type{Vector{String}}, gp::DrySession)
# # out = Vector{String}()
# Dump all data/commands in a session into one of the selected recipient(s) # for l in gp
# # push!(out, l)
function convert(::Type{Vector{String}}, gp::○Session) # end
out = Vector{String}() # return out
for l in gp # end
push!(out, l)
end
return out
end
dump(gp::○Session, d::○DataSource) = nothing # --------------------------------------------------------------------
function dump(gp::○Process, d::○DataSource) internal_save(gp::DrySession; kw...) = internal_save(gp, gp; kw...)
global state function internal_save(gp::DrySession, stream; term::AbstractString="", output::AbstractString="")
if state.verbosity (term != "") && println(stream, "set term $term")
for ii in 1:length(d.lines) (output != "") && println(stream, "set output '$output'")
v = d.lines[ii] i = (!(typeof(stream) <: DrySession), 1, 1) # Skip data sources ?
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $v\n")
if ii == state.printlines
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) ...\n")
if ii < length(d.lines)
v = d.lines[end]
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $v\n")
end
break
end
end
end
w = write(gp.pin, "\n")
w = write(gp.pin, join(d.lines, "\n"))
w = write(gp.pin, "\n")
w = write(gp.pin, "\n")
flush(gp.pin)
end
dump(gp::○Session; term=("", "")) = nothing
dump(sid::Symbol ; term=("", "")) = dump(getsession(sid), term=term)
dump( ; term=("", "")) = dump(getsession() , term=term)
function dump(gp::○Process; term=("", ""))
if term[1] != ""
write(gp, "set term $(term[1])")
write(gp, "set output '$(term[2])'")
end
i = (false, 1, 1) # Skip data sources
while (next = iterate(gp, i)) != nothing while (next = iterate(gp, i)) != nothing
(s, i) = next (s, i) = next
write(gp, s) println(stream, s)
end end
(output != "") && println(stream, "set output")
if term[1] != "" output
write(gp, "set output")
end
end
dump(sid::Symbol, f::IO; term=("", "")) = dump(getsession(sid), f, term=term)
dump( f::IO; term=("", "")) = dump(getsession() , f, term=term)
function dump(gp::○Session, f::IO; term=("", ""))
if term[1] != ""
println(f, "set term $(term[1])")
println(f, "set output '$(term[2])'")
end
for l in gp
println(f, l)
end
if term[1] != ""
println(f, "set output")
end
end
dump(sid::Symbol, file::AbstractString; term=("", "")) = dump(getsession(sid), file, term=term)
dump( file::AbstractString; term=("", "")) = dump(getsession() , file, term=term)
function dump(gp::○Session, file::AbstractString; term=("", ""))
f = open(file, "w")
dump(gp, f, term=term)
close(f)
end end
@ -587,7 +541,7 @@ end
function driver(args...; flag3d=false) function driver(args...; flag3d=false)
if length(args) == 0 if length(args) == 0
gp = getsession() gp = getsession()
dump(gp) internal_save(gp)
return nothing return nothing
end end
@ -651,7 +605,7 @@ function driver(args...; flag3d=false)
end end
end end
#elseif arg[1] == :verb #elseif arg[1] == :verb
# (loop == 1) && (state.verbosity = arg[2]) # (loop == 1) && (state.verbose = arg[2])
else else
(loop == 2) && newcmd(gp; [arg]...) # A cmd keyword (loop == 2) && newcmd(gp; [arg]...) # A cmd keyword
end end
@ -692,7 +646,7 @@ function driver(args...; flag3d=false)
dataplot = "" dataplot = ""
dataCompleted() dataCompleted()
(doDump) && (dump(gp)) # ; term=term)) (doDump) && (internal_save(gp))
return nothing return nothing
end end
@ -704,19 +658,23 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
""" """
# gnuplot `gnuplot(sid::Symbol)`
`gnuplot(sid::Symbol, cmd::AbstractString)`
Initialize a new session and (optionally) the associated Gnuplot process Initialize a new session and (optionally) the associated Gnuplot process
## Arguments: ## Arguments:
- `sid`: the session name (a Julia symbol); - `sid`: the session name (a Julia symbol);
- `cmd`: a string specifying the complete file path to a gnuplot executable. If not given a *dry* session will be created, i.e. a session without underlying gnuplot process.
## Optional keywords:
- `dry`: a boolean specifying whether the session should be a *dry* one, i.e. with no underlying gnuplot process (`default false`);
- `cmd`: a string specifying the complete file path to a gnuplot executable (default="gnuplot").
""" """
function gnuplot(sid::Symbol; dry=false, cmd="gnuplot") function gnuplot(sid::Symbol)
out = DrySession(sid)
state.sessions[sid] = out
return out
end
function gnuplot(sid::Symbol, cmd::AbstractString)
function readTask(sid, stream, channel) function readTask(sid, stream, channel)
global state global state
saveOutput = false saveOutput = false
@ -731,7 +689,7 @@ function gnuplot(sid::Symbol; dry=false, cmd="gnuplot")
saveOutput = false saveOutput = false
elseif line != "" elseif line != ""
printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n") printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n")
#(state.verbosity >= 1) && (printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n")) #(state.verbose >= 1) && (printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n"))
end end
end end
end end
@ -742,46 +700,46 @@ function gnuplot(sid::Symbol; dry=false, cmd="gnuplot")
global state global state
if !dry CheckGnuplotVersion(cmd)
CheckGnuplotVersion(cmd) session = DrySession(sid)
session = Session(sid)
pin = Base.Pipe() pin = Base.Pipe()
pout = Base.Pipe() pout = Base.Pipe()
perr = Base.Pipe() perr = Base.Pipe()
proc = run(pipeline(`$cmd`, stdin=pin, stdout=pout, stderr=perr), wait=false) proc = run(pipeline(`$cmd`, stdin=pin, stdout=pout, stderr=perr), wait=false)
chan = Channel{String}(32) chan = Channel{String}(32)
# Close unused sides of the pipes # Close unused sides of the pipes
Base.close(pout.in) Base.close(pout.in)
Base.close(perr.in) Base.close(perr.in)
Base.close(pin.out) Base.close(pin.out)
Base.start_reading(pout.out) Base.start_reading(pout.out)
Base.start_reading(perr.out) Base.start_reading(perr.out)
# Start reading tasks # Start reading tasks
@async readTask(sid, pout, chan) @async readTask(sid, pout, chan)
@async readTask(sid, perr, chan) @async readTask(sid, perr, chan)
out = Process(getfield.(Ref(session), fieldnames(Session))..., pin, pout, perr, proc, chan) out = Session(getfield.(Ref(session), fieldnames(concretetype(DrySession)))..., pin, pout, perr, proc, chan)
else
out = Session(sid)
end
state.sessions[sid] = out state.sessions[sid] = out
(!dry) && (setWindowTitle(out)) setWindowTitle(out)
return out return out
end end
function gnuplot(;args...) function gnuplot()
global state global state
return gnuplot(state.default, args...) return gnuplot(state.default)
end
function gnuplot(cmd::AbstractString)
global state
return gnuplot(state.default, cmd)
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
""" """
# quit `quit()`
Quit the session and the associated gnuplot process (if any). Quit the session and the associated gnuplot process (if any).
""" """
@ -794,7 +752,7 @@ function quit(sid::Symbol)
end end
""" """
# quitall `quitall()`
Quit all the sessions and the associated gnuplot processes. Quit all the sessions and the associated gnuplot processes.
""" """
@ -810,37 +768,24 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
""" """
# @gp `@gp args...`
The `@gp` macro, and its companion `@gsp` (for `splot` operations) The `@gp` macro, and its companion `@gsp` (for `splot` operations) allows to exploit all of the **Gnuplot** package functionalities using an extremely efficient and concise syntax. Both macros accept the same syntax, as described below.
allows to exploit all of the **Gnuplot** package functionalities
using an extremely efficient and concise syntax. Both macros accept
the same syntax, described below:
The macros accepts any number of arguments, with the following
meaning:
The macros accepts any number of arguments, with the following meaning:
- a symbol: the name of the session to use; - a symbol: the name of the session to use;
- a string: a command (e.g. "set key left") or plot specification - a string: a command (e.g. "set key left") or plot specification (e.g. "with lines");
(e.g. "with lines"); - a string starting with a `\$` sign: a data set name;
- a string starting with a `\$` sign: specifies a data set name; - an `Int` > 0: the plot destination in a multiplot session;
- an `Int` > 0: set the current plot destination (if multiplot is - a keyword/value pair: a keyword value (see below);
enabled); - any other type: a dataset to be passed to Gnuplot. Each dataset must be terminated by either:
- a keyword: set the keyword value (see below); - a string starting with a `\$` sign (i.e. the data set name);
- any other type: a dataset to be passed to Gnuplot. Each dataset - or a string with the plot specifications (e.g. "with lines");
must be terminated by either: a string starting with a `\$` sign - the `:-` symbol, used as first argument, avoids resetting the Gnuplot session. Used as last argument avoids immediate execution of the plot/splot command. This symbol can be used to split a single call into multiple ones.
(i.e. the data set name) or a string with the plot specifications
(e.g. "with lines");
- the `:-` symbol, used as first argument, avoids resetting the
Gnuplot session. Used as last argument avoids immediate execution
of the plot/splot command. This symbol can be used to split a
single call into multiple ones.
All entries are optional, and there is no mandatory order. The plot All entries are optional, and there is no mandatory order. The plot specification can either be:
specification can either be: a complete plot/splot command (e.g., - a complete plot/splot command (e.g., "plot sin(x)", both "plot" and "splot" can be abbreviated to "p" and "s" respectively);
"plot sin(x)", both "plot" and "splot" can be abbreviated to "p" and - or a partial specification starting with the "with" clause (if it follows a data set).
"s" respectively), or a partial specification starting with the
"with" clause (if it follows a data set).
The list of accepted keyword is as follows: The list of accepted keyword is as follows:
- `title::String`: plot title; - `title::String`: plot title;
@ -855,25 +800,11 @@ The list of accepted keyword is as follows:
- `zrange::NTuple{2, Number}`: Z axis range; - `zrange::NTuple{2, Number}`: Z axis range;
- `cbrange::NTuple{2, Number}`: Color box axis range; - `cbrange::NTuple{2, Number}`: Color box axis range;
The symbol for the above-mentioned keywords may also be used in a The symbol for the above-mentioned keywords may also be used in a shortened form, as long as there is no ambiguity with other keywords. E.g. you can use: `xr=(1,10)` in place of `xrange=(1,10)`.
shortened form, as long as there is no ambiguity with other
keywords. E.g. you can use: `xr=(1,10)` in place of
`xrange=(1,10)`.
Beside the above-mentioned keyword the following can also be used # Examples:
(although with no symbol shortening):
- `verb`: 0 or 1, to set the verbosity level; ## Simple examples with no data:
- `file`: send all the data and command to a file rather than
to a Gnuplot process;
- `stream`: send all the data and command to a stream rather than
to a Gnuplot process;
- `term`: `"a string"`, or `("a string", "a filename")`: to specify
the terminal (and optionally the output file);
## Examples:
### Simple examples with no data:
``` ```
@gp "plot sin(x)" @gp "plot sin(x)"
@gp "plot sin(x)" "pl cos(x)" @gp "plot sin(x)" "pl cos(x)"
@ -965,10 +896,13 @@ name = "\\\$MyDataSet1"
@gp :- 2 xlab="X label" ylab="Residuals" :- @gp :- 2 xlab="X label" ylab="Residuals" :-
@gp :- "plot \$name u 1:((f(\\\$1)-\\\$2) / \\\$3):(1) w errorbars notit" @gp :- "plot \$name u 1:((f(\\\$1)-\\\$2) / \\\$3):(1) w errorbars notit"
# Retrieve values fr a, b and c # Retrieve values for a, b and c
a = parse(Float64, gpeval("print a")) a = parse(Float64, exec("print a"))
b = parse(Float64, gpeval("print b")) b = parse(Float64, exec("print b"))
c = parse(Float64, gpeval("print c")) c = parse(Float64, exec("print c"))
# Save to a PDF file
save(term="pdf", output="gnuplot.pdf")
``` ```
### Display an image ### Display an image
@ -1017,8 +951,8 @@ end
# Read/evaluate/print/loop # Read/evaluate/print/loop
# """ # """
# function repl(sid::Symbol) # function repl(sid::Symbol)
# verb = state.verbosity # verb = state.verbose
# state.verbosity = 0 # state.verbose = 0
# gp = getsession(sid) # gp = getsession(sid)
# while true # while true
# line = readline(stdin) # line = readline(stdin)
@ -1028,7 +962,7 @@ end
# println(line) # println(line)
# end # end
# end # end
# state.verbosity = verb # state.verbose = verb
# return nothing # return nothing
# end # end
# function repl() # function repl()
@ -1039,18 +973,17 @@ end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
""" """
# gpeval `exec(sid::Symbol, s::Vector{String})`
Directly execute commands on the underlying gnuplot process, and return the result(s). Directly execute commands on the underlying Gnuplot process, and return the result(s).
functions.
## Examples: ## Examples:
``` ```julia
gpeval("print GPVAL_TERM") exec("print GPVAL_TERM")
gpeval("plot sin(x)") exec("plot sin(x)")
``` ```
""" """
function gpeval(sid::Symbol, s::Vector{String}) function exec(sid::Symbol, s::Vector{String})
global state global state
gp = getsession(sid) gp = getsession(sid)
answer = Vector{String}() answer = Vector{String}()
@ -1059,19 +992,49 @@ function gpeval(sid::Symbol, s::Vector{String})
end end
return join(answer, "\n") return join(answer, "\n")
end end
function gpeval(s::String) function exec(s::String)
global state global state
gpeval(state.default, [s]) exec(state.default, [s])
end end
gpeval(sid::Symbol, s::String) = gpeval(sid, [s]) exec(sid::Symbol, s::String) = exec(sid, [s])
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function setverb(b::Bool) """
`setverbose(b::Bool)`
Set verbose flag to `true` or `false` (default: `false`).
"""
function setverbose(b::Bool)
global state global state
state.verbosity = b state.verbose = b
end end
# --------------------------------------------------------------------
"""
`save(...)`
Save the data and commands in the current session to either:
- the gnuplot process (i.e. produce a plot): `save(term="", output="")`;
- an IO stream: `save(stream::IO; term="", output="")`;
- a file: `save(file::AbstractStrings; term="", output="")`.
To save the data and command from a specific session pass the ID as first argument, i.e.:
- `save(sid::Symbol, term="", output="")`;
- `save(sid::Symbol, stream::IO; term="", output="")`;
- `save(sid::Symbol, file::AbstractStrings; term="", output="")`.
In all cases the `term` keyword allows to specify a gnuplot terminal, and the `output` keyword allows to specify an output file.
"""
save( ; kw...) = internal_save(getsession() ; kw...)
save(sid::Symbol ; kw...) = internal_save(getsession(sid) ; kw...)
save( stream::IO ; kw...) = internal_save(getsession() , stream; kw...)
save(sid::Symbol, stream::IO ; kw...) = internal_save(getsession(sid), stream; kw...)
save( file::AbstractString; kw...) = open(file, "w") do stream; internal_save(getsession() , stream; kw...); end
save(sid::Symbol, file::AbstractString; kw...) = open(file, "w") do stream; internal_save(getsession(sid), stream; kw...); end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
function hist(v::Vector{T}; addright=false, closed::Symbol=:left, args...) where T <: AbstractFloat function hist(v::Vector{T}; addright=false, closed::Symbol=:left, args...) where T <: AbstractFloat
i = findall(isfinite.(v)) i = findall(isfinite.(v))

View File

@ -1,80 +1,81 @@
using Gnuplot using Gnuplot
function gp_test() x = collect(1.:100);
x = collect(1.:100);
#----------------------------------------------------------------- #-----------------------------------------------------------------
for i in 1:10 for i in 1:10
@gp :gp1 "plot sin($i*x)" @gp :gp1 "plot sin($i*x)"
@gp :gp2 "plot sin($i*x)" @gp :gp2 "plot sin($i*x)"
@gp :gp3 "plot sin($i*x)" @gp :gp3 "plot sin($i*x)"
sleep(0.3) sleep(0.3)
end end
quitall() quitall()
#----------------------------------------------------------------- #-----------------------------------------------------------------
@gp "plot sin(x)" @gp "plot sin(x)"
@gp "plot sin(x)" "pl cos(x)" @gp "plot sin(x)" "pl cos(x)"
@gp "plo sin(x)" "s cos(x)" @gp "plo sin(x)" "s cos(x)"
@gp "plot sin(x)" :- @gp "plot sin(x)" :-
@gp :- "plot cos(x)" @gp :- "plot cos(x)"
@gp "plot sin(x)" 2 xr=(-2pi,2pi) "pause 2" "plot cos(4*x)" @gp "plot sin(x)" 2 xr=(-2pi,2pi) "pause 2" "plot cos(4*x)"
x = range(-2pi, stop=2pi, length=100); x = range(-2pi, stop=2pi, length=100);
y = 1.5 * sin.(0.3 .+ 0.7x) ; y = 1.5 * sin.(0.3 .+ 0.7x) ;
noise = randn(length(x))./2; noise = randn(length(x))./2;
e = 0.5 * fill(1, size(x)); e = 0.5 * fill(1, size(x));
@gp hist(noise, nbins=10) @gp hist(noise, nbins=10)
@gp x y @gp x y
@gp x y "w l" @gp x y "w l"
name = "\$MyDataSet1" name = "\$MyDataSet1"
@gp x y name "plot $name w l" "pl $name u 1:(2*\$2) w l" @gp x y name "plot $name w l" "pl $name u 1:(2*\$2) w l"
@gsp randn(Float64, 30, 50) @gsp randn(Float64, 30, 50)
@gp randn(Float64, 30, 50) "w image" @gp randn(Float64, 30, 50) "w image"
@gsp x y y @gsp x y y
@gp("set key horizontal", "set grid", @gp("set key horizontal", "set grid",
xrange=(-7,7), ylabel="Y label", xrange=(-7,7), ylabel="Y label",
x, y, "w l t 'Real model' dt 2 lw 2 lc rgb 'red'", x, y, "w l t 'Real model' dt 2 lw 2 lc rgb 'red'",
x, y+noise, e, "w errorbars t 'Data'") x, y+noise, e, "w errorbars t 'Data'")
@gp "f(x) = a * sin(b + c*x); a = 1; b = 1; c = 1;" :- @gp "f(x) = a * sin(b + c*x); a = 1; b = 1; c = 1;" :-
@gp :- x y+noise e name :- @gp :- x y+noise e name :-
@gp :- "fit f(x) $name u 1:2:3 via a, b, c;" :- @gp :- "fit f(x) $name u 1:2:3 via a, b, c;" :-
@gp :- "set multiplot layout 2,1" :- @gp :- "set multiplot layout 2,1" :-
@gp :- "plot $name w points" ylab="Data and model" :- @gp :- "plot $name w points" ylab="Data and model" :-
@gp :- "plot $name u 1:(f(\$1)) w lines" :- @gp :- "plot $name u 1:(f(\$1)) w lines" :-
@gp :- 2 xlab="X label" ylab="Residuals" :- @gp :- 2 xlab="X label" ylab="Residuals" :-
@gp :- "plot $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars notit" @gp :- "plot $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars notit"
# Retrieve values fr a, b and c # Retrieve values fr a, b and c
a = parse(Float64, gpeval("print a")) a = parse(Float64, exec("print a"))
b = parse(Float64, gpeval("print b")) b = parse(Float64, exec("print b"))
c = parse(Float64, gpeval("print c")) c = parse(Float64, exec("print c"))
gnuplot(:dry, dry=true) gnuplot(:dry)
@gp :dry "f(x) = a * sin(b + c*x); a = 1; b = 1; c = 1;" :- @gp :dry "f(x) = a * sin(b + c*x); a = 1; b = 1; c = 1;" :-
@gp :- :dry "a = $a; b = $b; c = $c" :- @gp :- :dry "a = $a; b = $b; c = $c" :-
@gp :- :dry "set multiplot layout 2,1" ylab="Data and model" :- @gp :- :dry "set multiplot layout 2,1" ylab="Data and model" :-
name = "\$MyDataSet1" name = "\$MyDataSet1"
@gp :- :dry x y+noise e name :- @gp :- :dry x y+noise e name :-
@gp :- :dry "plot $name w points" :- @gp :- :dry "plot $name w points" :-
@gp :- :dry "plot $name u 1:(f(\$1)) w lines" :- @gp :- :dry "plot $name u 1:(f(\$1)) w lines" :-
@gp :- :dry 2 xlab="X label" ylab="Residuals" :- @gp :- :dry 2 xlab="X label" ylab="Residuals" :-
@gp :- :dry "plot $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars notit" :- @gp :- :dry "plot $name u 1:((f(\$1)-\$2) / \$3):(1) w errorbars notit" :-
@gp :- :dry file="test.gp" # write on file test @gp :- :dry
gpeval("load 'test.gp'") # load file test save("test.gp") # write on file test.gp
quitall()
exec("load 'test.gp'") # load file test.gp
#----------------------------------------------------------------- #-----------------------------------------------------------------
@gp(""" @gp("""
approx_1(x) = x - x**3/6 approx_1(x) = x - x**3/6
approx_2(x) = x - x**3/6 + x**5/120 approx_2(x) = x - x**3/6 + x**5/120
approx_3(x) = x - x**3/6 + x**5/120 - x**7/5040 approx_3(x) = x - x**3/6 + x**5/120 - x**7/5040
@ -93,13 +94,13 @@ function gp_test()
set format y "%.1f" set format y "%.1f"
set samples 500 set samples 500
set style fill solid 0.4 noborder""", set style fill solid 0.4 noborder""",
"plot '+' using 1:(sin(\$1)):(approx_1(\$1)) with filledcurve title label1 lt 3", "plot '+' using 1:(sin(\$1)):(approx_1(\$1)) with filledcurve title label1 lt 3",
"plot '+' using 1:(sin(\$1)):(approx_2(\$1)) with filledcurve title label2 lt 2", "plot '+' using 1:(sin(\$1)):(approx_2(\$1)) with filledcurve title label2 lt 2",
"plot '+' using 1:(sin(\$1)):(approx_3(\$1)) with filledcurve title label3 lt 1", "plot '+' using 1:(sin(\$1)):(approx_3(\$1)) with filledcurve title label3 lt 1",
"plot sin(x) with lines lw 1 lc rgb 'black'") "plot sin(x) with lines lw 1 lc rgb 'black'")
#----------------------------------------------------------------- #-----------------------------------------------------------------
@gp(""" @gp("""
set zrange [-1:1] set zrange [-1:1]
unset label unset label
unset arrow unset arrow
@ -125,19 +126,15 @@ function gp_test()
x7=xx; xx=xx+dx x7=xx; xx=xx+dx
x8=xx; xx=xx+dx x8=xx; xx=xx+dx
x9=xx; xx=xx+dx""", x9=xx; xx=xx+dx""",
"splot [u=0:1][v=-4.99:4.99]x0, v, (u<0.5) ? -1 : sinc(x0,v) notitle", "splot [u=0:1][v=-4.99:4.99]x0, v, (u<0.5) ? -1 : sinc(x0,v) notitle",
"splot x1, v, (u<0.5) ? -1 : sinc(x1,v) notitle", "splot x1, v, (u<0.5) ? -1 : sinc(x1,v) notitle",
"splot x2, v, (u<0.5) ? -1 : sinc(x2,v) notitle", "splot x2, v, (u<0.5) ? -1 : sinc(x2,v) notitle",
"splot x3, v, (u<0.5) ? -1 : sinc(x3,v) notitle", "splot x3, v, (u<0.5) ? -1 : sinc(x3,v) notitle",
"splot x4, v, (u<0.5) ? -1 : sinc(x4,v) notitle", "splot x4, v, (u<0.5) ? -1 : sinc(x4,v) notitle",
"splot x5, v, (u<0.5) ? -1 : sinc(x5,v) notitle", "splot x5, v, (u<0.5) ? -1 : sinc(x5,v) notitle",
"splot x6, v, (u<0.5) ? -1 : sinc(x6,v) notitle", "splot x6, v, (u<0.5) ? -1 : sinc(x6,v) notitle",
"splot x7, v, (u<0.5) ? -1 : sinc(x7,v) notitle", "splot x7, v, (u<0.5) ? -1 : sinc(x7,v) notitle",
"splot x8, v, (u<0.5) ? -1 : sinc(x8,v) notitle", "splot x8, v, (u<0.5) ? -1 : sinc(x8,v) notitle",
"splot x9, v, (u<0.5) ? -1 : sinc(x9,v) notitle") "splot x9, v, (u<0.5) ? -1 : sinc(x9,v) notitle")
quitall() quitall()
return true
end
gp_test()