First attempt
This commit is contained in:
parent
622ef39837
commit
3283f54741
728
src/Gnuplot.jl
728
src/Gnuplot.jl
@ -3,26 +3,24 @@ module Gnuplot
|
|||||||
using StructC14N, ColorTypes, Printf, StatsBase, ReusePatterns, DataFrames
|
using StructC14N, ColorTypes, Printf, StatsBase, ReusePatterns, DataFrames
|
||||||
|
|
||||||
import Base.reset
|
import Base.reset
|
||||||
import Base.println
|
import Base.write
|
||||||
import Base.iterate
|
import Base.iterate
|
||||||
import Base.convert
|
import Base.convert
|
||||||
|
|
||||||
export gnuplot, quit, quitall, setverbose,
|
export @gp, @gsp, save, contourlines, hist
|
||||||
@gp, @gsp, exec, save, contourlines, hist
|
|
||||||
|
|
||||||
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
|
# │ TYPE DEFINITIONS │
|
||||||
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
#_____________________________________________________________________
|
# ---------------------------------------------------------------------
|
||||||
# TYPE DEFINITIONS
|
|
||||||
#_____________________________________________________________________
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
mutable struct DataSet
|
mutable struct DataSet
|
||||||
name::String
|
name::String
|
||||||
lines::Vector{String}
|
lines::Vector{String}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
mutable struct SinglePlot
|
mutable struct SinglePlot
|
||||||
cmds::Vector{String}
|
cmds::Vector{String}
|
||||||
elems::Vector{String}
|
elems::Vector{String}
|
||||||
@ -31,7 +29,7 @@ mutable struct SinglePlot
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
@quasiabstract mutable struct DrySession
|
@quasiabstract mutable struct DrySession
|
||||||
sid::Symbol # session ID
|
sid::Symbol # session ID
|
||||||
datas::Vector{DataSet} # data sets
|
datas::Vector{DataSet} # data sets
|
||||||
@ -40,8 +38,8 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
@quasiabstract mutable struct Session <: DrySession
|
@quasiabstract mutable struct GPSession <: DrySession
|
||||||
pin::Base.Pipe;
|
pin::Base.Pipe;
|
||||||
pout::Base.Pipe;
|
pout::Base.Pipe;
|
||||||
perr::Base.Pipe;
|
perr::Base.Pipe;
|
||||||
@ -50,27 +48,25 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
mutable struct State
|
mutable struct State
|
||||||
sessions::Dict{Symbol, DrySession};
|
sessions::Dict{Symbol, DrySession};
|
||||||
dry::Bool
|
dry::Bool
|
||||||
cmd::String
|
cmd::String
|
||||||
default::Symbol; # default session name
|
default::Symbol; # default session name
|
||||||
initcmd::Vector{String} # Commands to initialize the gnuplot session (e.g., to set default terminal)
|
init::Vector{String} # Commands to initialize the gnuplot session (e.g., to set default terminal)
|
||||||
verbose::Bool; # verbosity level (true/false)
|
verbose::Bool; # verbosity level (true/false)
|
||||||
silent::Bool; # Silent flag
|
|
||||||
printlines::Int; # How many data lines are printed in log
|
printlines::Int; # How many data lines are printed in log
|
||||||
State() = new(Dict{Symbol, DrySession}(), true, "gnuplot", :default, Vector{String}(), false, false, 4)
|
State() = new(Dict{Symbol, DrySession}(), true, "gnuplot", :default, Vector{String}(), false, 4)
|
||||||
end
|
end
|
||||||
const state = State()
|
const state = State()
|
||||||
state.dry = false
|
state.dry = false
|
||||||
|
|
||||||
|
|
||||||
#_____________________________________________________________________
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
# "PRIVATE" (NON-EXPORTED) FUNCTIONS
|
# │ LOW LEVEL FUNCTIONS │
|
||||||
#_____________________________________________________________________
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
# --------------------------------------------------------------------
|
|
||||||
"""
|
"""
|
||||||
# CheckGnuplotVersion
|
# CheckGnuplotVersion
|
||||||
|
|
||||||
@ -105,7 +101,7 @@ function CheckGnuplotVersion(cmd::AbstractString)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function parseKeywords(; kwargs...)
|
function parseKeywords(; kwargs...)
|
||||||
template = (xrange=NTuple{2, Real},
|
template = (xrange=NTuple{2, Real},
|
||||||
yrange=NTuple{2, Real},
|
yrange=NTuple{2, Real},
|
||||||
@ -136,176 +132,8 @@ function parseKeywords(; kwargs...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function DrySession(sid::Symbol)
|
function data2string(args...)
|
||||||
global state
|
|
||||||
(sid in keys(state.sessions)) &&
|
|
||||||
error("Gnuplot session $sid is already active")
|
|
||||||
out = DrySession(sid, Vector{DataSet}(), [SinglePlot()], 1)
|
|
||||||
return out
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
function getsession(sid::Symbol)
|
|
||||||
global state
|
|
||||||
if !(sid in keys(state.sessions))
|
|
||||||
#@info "Creating session $sid..."
|
|
||||||
if state.dry
|
|
||||||
gnuplot(sid)
|
|
||||||
else
|
|
||||||
gnuplot(sid, state.cmd)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return state.sessions[sid]
|
|
||||||
end
|
|
||||||
function getsession()
|
|
||||||
global state
|
|
||||||
return getsession(state.default)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
"""
|
|
||||||
# println
|
|
||||||
|
|
||||||
Send a string to gnuplot's STDIN.
|
|
||||||
|
|
||||||
The commands sent through `send` are not stored in the current
|
|
||||||
session (use `newcmd` to save commands in the current session).
|
|
||||||
|
|
||||||
## Arguments:
|
|
||||||
- `gp`: a `Session` object;
|
|
||||||
- `str::String`: command to be sent;
|
|
||||||
- `capture=false`: set to `true` to capture and return the output.
|
|
||||||
"""
|
|
||||||
println(gp::DrySession, str::AbstractString) = nothing
|
|
||||||
function println(gp::Session, str::AbstractString)
|
|
||||||
global state
|
|
||||||
if !state.silent && state.verbose
|
|
||||||
printstyled(color=:yellow, "GNUPLOT ($(gp.sid)) $str\n")
|
|
||||||
end
|
|
||||||
w = write(gp.pin, strip(str) * "\n")
|
|
||||||
w <= 0 && error("Writing on gnuplot STDIN pipe returned $w")
|
|
||||||
#flush(gp.pin)
|
|
||||||
return w
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
println(gp::DrySession, d::DataSet) = nothing
|
|
||||||
|
|
||||||
function println(gp::Session, d::DataSet)
|
|
||||||
if typeof(gp) == concretetype(Session)
|
|
||||||
if !state.silent && 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 nothing
|
|
||||||
end
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
writeread(gp::DrySession, str::AbstractString) = [""]
|
|
||||||
function writeread(gp::Session, str::AbstractString)
|
|
||||||
global state
|
|
||||||
silent = state.silent
|
|
||||||
state.silent = true
|
|
||||||
write(gp.pin, "print 'GNUPLOT_CAPTURE_BEGIN'\n")
|
|
||||||
println(gp, strip(str))
|
|
||||||
write(gp.pin, "print 'GNUPLOT_CAPTURE_END'\n")
|
|
||||||
flush(gp.pin)
|
|
||||||
out = Vector{String}()
|
|
||||||
while true
|
|
||||||
l = take!(gp.channel)
|
|
||||||
l == "GNUPLOT_CAPTURE_END" && break
|
|
||||||
push!(out, l)
|
|
||||||
end
|
|
||||||
state.silent = silent
|
|
||||||
return out
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
setWindowTitle(session::DrySession) = nothing
|
|
||||||
function setWindowTitle(session::Session)
|
|
||||||
term = writeread(session, "print GPVAL_TERM")[1]
|
|
||||||
if term in ("aqua", "x11", "qt", "wxt")
|
|
||||||
opts = writeread(session, "print GPVAL_TERMOPTIONS")[1]
|
|
||||||
if findfirst("title", opts) == nothing
|
|
||||||
writeread(session, "set term $term $opts title 'Gnuplot.jl: $(session.sid)'")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
function reset(gp::DrySession)
|
|
||||||
gp.datas = Vector{DataSet}()
|
|
||||||
gp.plots = [SinglePlot()]
|
|
||||||
gp.curmid = 1
|
|
||||||
println(gp, "reset session")
|
|
||||||
return nothing
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
function setmulti(gp::DrySession, mid::Int)
|
|
||||||
@assert mid >= 0 "Multiplot ID must be a >= 0"
|
|
||||||
for i in length(gp.plots)+1:mid
|
|
||||||
push!(gp.plots, SinglePlot())
|
|
||||||
end
|
|
||||||
(mid > 0) && (gp.curmid = mid)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
function newdatasource(gp::DrySession, v::Vector{T}; name="") where T <: AbstractString
|
|
||||||
(name == "") && (name = string("data", length(gp.datas)))
|
|
||||||
name = "\$$name"
|
|
||||||
|
|
||||||
accum = Vector{String}()
|
|
||||||
push!(accum, "$name << EOD")
|
|
||||||
append!(accum, v)
|
|
||||||
push!(accum, "EOD")
|
|
||||||
d = DataSet(name, accum)
|
|
||||||
push!(gp.datas, d)
|
|
||||||
|
|
||||||
println(gp, d) # Send directly to gnuplot process
|
|
||||||
return name
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
function newdatasource(gp::DrySession, args...; name="")
|
|
||||||
(name == "") && (name = string("data", length(gp.datas)))
|
|
||||||
name = "\$$name"
|
|
||||||
accum = dataset(args...)
|
|
||||||
accum[1] = name * accum[1]
|
|
||||||
d = DataSet(name, accum)
|
|
||||||
push!(gp.datas, d)
|
|
||||||
|
|
||||||
println(gp, d) # Send directly to gnuplot process
|
|
||||||
return name
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
function dataset(args...)
|
|
||||||
@assert length(args) > 0
|
@assert length(args) > 0
|
||||||
|
|
||||||
# Check types of args
|
# Check types of args
|
||||||
@ -339,7 +167,6 @@ function dataset(args...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
accum = Vector{String}()
|
accum = Vector{String}()
|
||||||
push!(accum, " << EOD")
|
|
||||||
|
|
||||||
# All scalars
|
# All scalars
|
||||||
if minimum(dims) == 0
|
if minimum(dims) == 0
|
||||||
@ -351,7 +178,6 @@ function dataset(args...)
|
|||||||
v *= " " * string(d)
|
v *= " " * string(d)
|
||||||
end
|
end
|
||||||
push!(accum, v)
|
push!(accum, v)
|
||||||
push!(accum, "EOD")
|
|
||||||
return accum
|
return accum
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -369,7 +195,6 @@ function dataset(args...)
|
|||||||
end
|
end
|
||||||
push!(accum, v)
|
push!(accum, v)
|
||||||
end
|
end
|
||||||
push!(accum, "EOD")
|
|
||||||
return accum
|
return accum
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -389,7 +214,6 @@ function dataset(args...)
|
|||||||
i += 1
|
i += 1
|
||||||
push!(accum, v)
|
push!(accum, v)
|
||||||
end
|
end
|
||||||
push!(accum, "EOD")
|
|
||||||
return accum
|
return accum
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -421,7 +245,6 @@ function dataset(args...)
|
|||||||
i += 1
|
i += 1
|
||||||
push!(accum, v)
|
push!(accum, v)
|
||||||
end
|
end
|
||||||
push!(accum, "EOD")
|
|
||||||
return accum
|
return accum
|
||||||
else
|
else
|
||||||
#@info "Case 4"
|
#@info "Case 4"
|
||||||
@ -440,7 +263,6 @@ function dataset(args...)
|
|||||||
i += 1
|
i += 1
|
||||||
push!(accum, v)
|
push!(accum, v)
|
||||||
end
|
end
|
||||||
push!(accum, "EOD")
|
|
||||||
return accum
|
return accum
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -449,16 +271,224 @@ function dataset(args...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
"""
|
# │ SESSION CONSTRUCTORS AND getsession() │
|
||||||
# newcmd
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
function DrySession(sid::Symbol)
|
||||||
|
global state
|
||||||
|
(sid in keys(state.sessions)) && error("Gnuplot session $sid is already active")
|
||||||
|
out = DrySession(sid, Vector{DataSet}(), [SinglePlot()], 1)
|
||||||
|
state.sessions[sid] = out
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
Send a command to gnuplot process and store it in the current session.
|
# ---------------------------------------------------------------------
|
||||||
|
function GPSession(sid::Symbol)
|
||||||
|
function readTask(sid, stream, channel)
|
||||||
|
global state
|
||||||
|
saveOutput = false
|
||||||
|
|
||||||
|
while isopen(stream)
|
||||||
|
line = readline(stream)
|
||||||
|
if (length(line) >= 1) && (line[1] == Char(0x1b)) # Escape (xterm -ti vt340)
|
||||||
|
buf = Vector{UInt8}()
|
||||||
|
append!(buf, convert(Vector{UInt8}, [line...]))
|
||||||
|
push!(buf, 0x0a)
|
||||||
|
c = 0x00
|
||||||
|
while c != 0x1b
|
||||||
|
c = read(stream, 1)[1]
|
||||||
|
push!(buf, c)
|
||||||
|
end
|
||||||
|
c = read(stream, 1)[1]
|
||||||
|
push!(buf, c)
|
||||||
|
write(stdout, buf)
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
if line == "GNUPLOT_CAPTURE_BEGIN"
|
||||||
|
saveOutput = true
|
||||||
|
else
|
||||||
|
if (line != "") && (line != "GNUPLOT_CAPTURE_END") && (state.verbose)
|
||||||
|
printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n")
|
||||||
|
end
|
||||||
|
(saveOutput) && (put!(channel, line))
|
||||||
|
(line == "GNUPLOT_CAPTURE_END") && (saveOutput = false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
delete!(state.sessions, sid)
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
global state
|
||||||
|
|
||||||
|
CheckGnuplotVersion(state.cmd)
|
||||||
|
session = DrySession(sid)
|
||||||
|
|
||||||
|
pin = Base.Pipe()
|
||||||
|
pout = Base.Pipe()
|
||||||
|
perr = Base.Pipe()
|
||||||
|
proc = run(pipeline(`$(state.cmd)`, stdin=pin, stdout=pout, stderr=perr), wait=false)
|
||||||
|
chan = Channel{String}(32)
|
||||||
|
|
||||||
|
# Close unused sides of the pipes
|
||||||
|
Base.close(pout.in)
|
||||||
|
Base.close(perr.in)
|
||||||
|
Base.close(pin.out)
|
||||||
|
Base.start_reading(pout.out)
|
||||||
|
Base.start_reading(perr.out)
|
||||||
|
|
||||||
|
# Start reading tasks
|
||||||
|
@async readTask(sid, pout, chan)
|
||||||
|
@async readTask(sid, perr, chan)
|
||||||
|
|
||||||
|
out = GPSession(getfield.(Ref(session), fieldnames(concretetype(DrySession)))...,
|
||||||
|
pin, pout, perr, proc, chan)
|
||||||
|
state.sessions[sid] = out
|
||||||
|
|
||||||
|
# Set window title
|
||||||
|
term = writeread(out, "print GPVAL_TERM")[1]
|
||||||
|
if term in ("aqua", "x11", "qt", "wxt")
|
||||||
|
opts = writeread(out, "print GPVAL_TERMOPTIONS")[1]
|
||||||
|
if findfirst("title", opts) == nothing
|
||||||
|
writeread(out, "set term $term $opts title 'Gnuplot.jl: $(out.sid)'")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for l in state.init
|
||||||
|
writeread(out, l)
|
||||||
|
end
|
||||||
|
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
function getsession(sid::Symbol=state.default)
|
||||||
|
global state
|
||||||
|
if !(sid in keys(state.sessions))
|
||||||
|
if state.dry
|
||||||
|
DrySession(sid)
|
||||||
|
else
|
||||||
|
GPSession(sid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return state.sessions[sid]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
|
# │ write() and writeread() │
|
||||||
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
"""
|
"""
|
||||||
|
# write
|
||||||
|
|
||||||
|
Send a string to gnuplot's STDIN.
|
||||||
|
|
||||||
|
The commands sent through `write` are not stored in the current
|
||||||
|
session (use `newcmd` to save commands in the current session).
|
||||||
|
|
||||||
|
## Arguments:
|
||||||
|
- `gp`: a `DrySession` object;
|
||||||
|
- `str::String`: command to be sent;
|
||||||
|
"""
|
||||||
|
write(gp::DrySession, str::AbstractString) = nothing
|
||||||
|
function write(gp::GPSession, str::AbstractString)
|
||||||
|
global state
|
||||||
|
if state.verbose
|
||||||
|
printstyled(color=:light_yellow, "GNUPLOT ($(gp.sid)) $str\n")
|
||||||
|
end
|
||||||
|
w = write(gp.pin, strip(str) * "\n")
|
||||||
|
w <= 0 && error("Writing on gnuplot STDIN pipe returned $w")
|
||||||
|
flush(gp.pin)
|
||||||
|
return w
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
write(gp::DrySession, d::DataSet) = nothing
|
||||||
|
function write(gp::GPSession, d::DataSet)
|
||||||
|
if state.verbose
|
||||||
|
v = ""
|
||||||
|
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $(d.name) << EOD\n")
|
||||||
|
n = min(state.printlines, length(d.lines))
|
||||||
|
for i in 1:n
|
||||||
|
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $(d.lines[i])\n")
|
||||||
|
end
|
||||||
|
if n < length(d.lines)
|
||||||
|
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) ...\n")
|
||||||
|
end
|
||||||
|
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) EOD\n")
|
||||||
|
end
|
||||||
|
write(gp.pin, "\n")
|
||||||
|
write(gp.pin, "$(d.name) << EOD\n")
|
||||||
|
write(gp.pin, join(d.lines, "\n") * "\n")
|
||||||
|
write(gp.pin, "EOD\n")
|
||||||
|
write(gp.pin, "\n")
|
||||||
|
write(gp.pin, "\n")
|
||||||
|
flush(gp.pin)
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
writeread(gp::DrySession, str::AbstractString) = [""]
|
||||||
|
function writeread(gp::GPSession, str::AbstractString)
|
||||||
|
global state
|
||||||
|
verbose = state.verbose
|
||||||
|
state.verbose = false
|
||||||
|
write(gp, "print 'GNUPLOT_CAPTURE_BEGIN'")
|
||||||
|
write(gp, str)
|
||||||
|
write(gp, "print 'GNUPLOT_CAPTURE_END'")
|
||||||
|
out = Vector{String}()
|
||||||
|
while true
|
||||||
|
l = take!(gp.channel)
|
||||||
|
l == "GNUPLOT_CAPTURE_END" && break
|
||||||
|
push!(out, l)
|
||||||
|
end
|
||||||
|
state.verbose = verbose
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
|
# │ PRIVATE FUNCTIONS TO MANIPULATE SESSIONS │
|
||||||
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
function reset(gp::DrySession)
|
||||||
|
gp.datas = Vector{DataSet}()
|
||||||
|
gp.plots = [SinglePlot()]
|
||||||
|
gp.curmid = 1
|
||||||
|
write(gp, "reset session")
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
function setmulti(gp::DrySession, mid::Int)
|
||||||
|
@assert mid >= 0 "Multiplot ID must be a >= 0"
|
||||||
|
for i in length(gp.plots)+1:mid
|
||||||
|
push!(gp.plots, SinglePlot())
|
||||||
|
end
|
||||||
|
(mid > 0) && (gp.curmid = mid)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
function newdataset(gp::DrySession, accum::Vector{String}; name="")
|
||||||
|
(name == "") && (name = string("data", length(gp.datas)))
|
||||||
|
name = "\$$name"
|
||||||
|
d = DataSet(name, accum)
|
||||||
|
push!(gp.datas, d)
|
||||||
|
write(gp, d) # Send now to gnuplot process
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
newdataset(gp::DrySession, args...; name="") = newdataset(gp, data2string(args...), name=name)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
function newcmd(gp::DrySession, 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) && (println(gp, v))
|
(length(gp.plots) == 1) && (write(gp, v))
|
||||||
return nothing
|
return nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -470,105 +500,80 @@ function newcmd(gp::DrySession; mid::Int=0, args...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function newplotelem(gp::DrySession, name, opt=""; mid=0)
|
function newplot(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::DrySession)
|
function quit(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::Session)
|
function quit(gp::GPSession)
|
||||||
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{DrySession}, gp)
|
invoke(quit, Tuple{DrySession}, gp)
|
||||||
return exitCode
|
return exitCode
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
iterate(gp::DrySession) = ("#ID: $(gp.sid)", (true, 1, 1))
|
# │ dump() and driver() │
|
||||||
function iterate(gp::DrySession, state)
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
(onData, mid, ii) = state
|
# ---------------------------------------------------------------------
|
||||||
if onData
|
dump(gp::DrySession; kw...) = dump(gp, gp; kw...)
|
||||||
if mid <= length(gp.datas)
|
function dump(gp::DrySession, stream; term::AbstractString="", output::AbstractString="")
|
||||||
if ii <= length(gp.datas[mid].lines)
|
write(stream, "reset\n")
|
||||||
return (gp.datas[mid].lines[ii], (true, mid, ii+1))
|
|
||||||
end
|
|
||||||
return iterate(gp, (true, mid+1, 1))
|
|
||||||
end
|
|
||||||
return ("", (false, 1, 1))
|
|
||||||
end
|
|
||||||
|
|
||||||
if mid <= length(gp.plots)
|
|
||||||
if ii <= length(gp.plots[mid].cmds)
|
|
||||||
return (gp.plots[mid].cmds[ii], (false, mid, ii+1))
|
|
||||||
end
|
|
||||||
if length(gp.plots[mid].elems) == 0
|
|
||||||
return ("", (false, mid+1, 1))
|
|
||||||
end
|
|
||||||
s = (gp.plots[mid].flag3d ? "splot " : "plot ") * " \\\n " *
|
|
||||||
join(gp.plots[mid].elems, ", \\\n ")
|
|
||||||
return (s, (false, mid+1, 1))
|
|
||||||
end
|
|
||||||
|
|
||||||
if mid == length(gp.plots)+1
|
|
||||||
s = ""
|
|
||||||
(length(gp.plots) > 1) && (s *= "unset multiplot;")
|
|
||||||
return (s, (false, mid+1, 1))
|
|
||||||
end
|
|
||||||
|
|
||||||
return nothing
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
# function convert(::Type{Vector{String}}, gp::DrySession)
|
|
||||||
# out = Vector{String}()
|
|
||||||
# for l in gp
|
|
||||||
# push!(out, l)
|
|
||||||
# end
|
|
||||||
# return out
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
internal_save(gp::DrySession; kw...) = internal_save(gp, gp; kw...)
|
|
||||||
function internal_save(gp::DrySession, stream; term::AbstractString="", output::AbstractString="")
|
|
||||||
println(stream, "reset")
|
|
||||||
if term != ""
|
if term != ""
|
||||||
former_term = writeread(gp, "print GPVAL_TERM")[1]
|
former_term = writeread(gp, "print GPVAL_TERM")[1]
|
||||||
former_opts = writeread(gp, "print GPVAL_TERMOPTIONS")[1]
|
former_opts = writeread(gp, "print GPVAL_TERMOPTIONS")[1]
|
||||||
println(stream, "set term $term")
|
write(stream, "set term $term\n")
|
||||||
end
|
end
|
||||||
(output != "") && println(stream, "set output '$output'")
|
(output != "") && write(stream, "set output '$output'\n")
|
||||||
i = (!(typeof(stream) <: DrySession), 1, 1) # Skip data sources ?
|
|
||||||
while (next = iterate(gp, i)) != nothing
|
if !(typeof(stream) <: DrySession)
|
||||||
(s, i) = next
|
# Dump datasets
|
||||||
println(stream, s)
|
for i in 1:length(gp.datas)
|
||||||
|
d = gp.datas[i]
|
||||||
|
write(stream, d.name * " << EOD\n")
|
||||||
|
for j in 1:length(d.lines)
|
||||||
|
write(stream, d.lines[j] * "\n")
|
||||||
end
|
end
|
||||||
(output != "") && println(stream, "set output")
|
write(stream, "EOD\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i in 1:length(gp.plots)
|
||||||
|
d = gp.plots[i]
|
||||||
|
for j in 1:length(d.cmds)
|
||||||
|
write(stream, d.cmds[j] * "\n")
|
||||||
|
end
|
||||||
|
s = (d.flag3d ? "splot " : "plot ") * " \\\n " *
|
||||||
|
join(d.elems, ", \\\n ")
|
||||||
|
write(stream, s * "\n")
|
||||||
|
end
|
||||||
|
(length(gp.plots) > 1) && write(stream, "unset multiplot\n")
|
||||||
|
(output != "") && write(stream, "set output\n")
|
||||||
if term != ""
|
if term != ""
|
||||||
println(stream, "set term $former_term $former_opts")
|
write(stream, "set term $former_term $former_opts\n")
|
||||||
end
|
end
|
||||||
output
|
return output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function driver(args...; flag3d=false)
|
function driver(args...; flag3d=false)
|
||||||
if length(args) == 0
|
if length(args) == 0
|
||||||
gp = getsession()
|
gp = getsession()
|
||||||
internal_save(gp)
|
dump(gp)
|
||||||
return nothing
|
return nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -587,8 +592,8 @@ function driver(args...; flag3d=false)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if AllArraysAreNotEmpty
|
if AllArraysAreNotEmpty
|
||||||
last = newdatasource(gp, data...; name=dataname)
|
last = newdataset(gp, data...; name=dataname)
|
||||||
(dataplot != nothing) && (newplotelem(gp, last, dataplot))
|
(dataplot != nothing) && (newplot(gp, last, dataplot))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
data = Vector{Any}()
|
data = Vector{Any}()
|
||||||
@ -660,7 +665,7 @@ function driver(args...; flag3d=false)
|
|||||||
(isPlot, flag3d, cmd) = isPlotCmd(arg)
|
(isPlot, flag3d, cmd) = isPlotCmd(arg)
|
||||||
if isPlot
|
if isPlot
|
||||||
gp.plots[gp.curmid].flag3d = flag3d
|
gp.plots[gp.curmid].flag3d = flag3d
|
||||||
newplotelem(gp, cmd)
|
newplot(gp, cmd)
|
||||||
else
|
else
|
||||||
newcmd(gp, arg)
|
newcmd(gp, arg)
|
||||||
end
|
end
|
||||||
@ -674,7 +679,7 @@ function driver(args...; flag3d=false)
|
|||||||
|
|
||||||
dataplot = ""
|
dataplot = ""
|
||||||
dataCompleted()
|
dataCompleted()
|
||||||
(doDump) && (internal_save(gp))
|
(doDump) && (dump(gp))
|
||||||
|
|
||||||
return nothing
|
return nothing
|
||||||
end
|
end
|
||||||
@ -684,132 +689,6 @@ end
|
|||||||
# EXPORTED FUNCTIONS
|
# EXPORTED FUNCTIONS
|
||||||
#_____________________________________________________________________
|
#_____________________________________________________________________
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
"""
|
|
||||||
`gnuplot(sid::Symbol)`
|
|
||||||
|
|
||||||
`gnuplot(sid::Symbol, cmd::AbstractString)`
|
|
||||||
|
|
||||||
Initialize a new session and (optionally) the associated Gnuplot process
|
|
||||||
|
|
||||||
## Arguments:
|
|
||||||
- `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.
|
|
||||||
"""
|
|
||||||
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)
|
|
||||||
global state
|
|
||||||
saveOutput = false
|
|
||||||
|
|
||||||
while isopen(stream)
|
|
||||||
line = readline(stream)
|
|
||||||
|
|
||||||
if (length(line) >= 1) && (line[1] == Char(0x1b)) # Escape (xterm -ti vt340)
|
|
||||||
buf = Vector{UInt8}()
|
|
||||||
append!(buf, convert(Vector{UInt8}, [line...]))
|
|
||||||
push!(buf, 0x0a)
|
|
||||||
c = 0x00
|
|
||||||
while c != 0x1b
|
|
||||||
c = read(stream, 1)[1]
|
|
||||||
push!(buf, c)
|
|
||||||
end
|
|
||||||
c = read(stream, 1)[1]
|
|
||||||
push!(buf, c)
|
|
||||||
write(stdout, buf)
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
if line == "GNUPLOT_CAPTURE_BEGIN"
|
|
||||||
saveOutput = true
|
|
||||||
else
|
|
||||||
if (line != "") && (line != "GNUPLOT_CAPTURE_END") && (!state.silent)
|
|
||||||
printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n")
|
|
||||||
end
|
|
||||||
(saveOutput) && (put!(channel, line))
|
|
||||||
(line == "GNUPLOT_CAPTURE_END") && (saveOutput = false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
delete!(state.sessions, sid)
|
|
||||||
return nothing
|
|
||||||
end
|
|
||||||
|
|
||||||
global state
|
|
||||||
|
|
||||||
CheckGnuplotVersion(cmd)
|
|
||||||
session = DrySession(sid)
|
|
||||||
|
|
||||||
pin = Base.Pipe()
|
|
||||||
pout = Base.Pipe()
|
|
||||||
perr = Base.Pipe()
|
|
||||||
proc = run(pipeline(`$cmd`, stdin=pin, stdout=pout, stderr=perr), wait=false)
|
|
||||||
chan = Channel{String}(32)
|
|
||||||
|
|
||||||
# Close unused sides of the pipes
|
|
||||||
Base.close(pout.in)
|
|
||||||
Base.close(perr.in)
|
|
||||||
Base.close(pin.out)
|
|
||||||
Base.start_reading(pout.out)
|
|
||||||
Base.start_reading(perr.out)
|
|
||||||
|
|
||||||
# Start reading tasks
|
|
||||||
@async readTask(sid, pout, chan)
|
|
||||||
@async readTask(sid, perr, chan)
|
|
||||||
|
|
||||||
out = Session(getfield.(Ref(session), fieldnames(concretetype(DrySession)))..., pin, pout, perr, proc, chan)
|
|
||||||
state.sessions[sid] = out
|
|
||||||
|
|
||||||
setWindowTitle(out)
|
|
||||||
for l in state.initcmd
|
|
||||||
writeread(out, l)
|
|
||||||
end
|
|
||||||
|
|
||||||
return out
|
|
||||||
end
|
|
||||||
|
|
||||||
function gnuplot()
|
|
||||||
global state
|
|
||||||
return gnuplot(state.default)
|
|
||||||
end
|
|
||||||
function gnuplot(cmd::AbstractString)
|
|
||||||
global state
|
|
||||||
return gnuplot(state.default, cmd)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
"""
|
|
||||||
`quit()`
|
|
||||||
|
|
||||||
Quit the session and the associated gnuplot process (if any).
|
|
||||||
"""
|
|
||||||
function quit(sid::Symbol)
|
|
||||||
global state
|
|
||||||
if !(sid in keys(state.sessions))
|
|
||||||
error("Gnuplot session $sid do not exists")
|
|
||||||
end
|
|
||||||
return quitsession(state.sessions[sid])
|
|
||||||
end
|
|
||||||
|
|
||||||
"""
|
|
||||||
`quitall()`
|
|
||||||
|
|
||||||
Quit all the sessions and the associated gnuplot processes.
|
|
||||||
"""
|
|
||||||
function quitall()
|
|
||||||
global state
|
|
||||||
for sid in keys(state.sessions)
|
|
||||||
quit(sid)
|
|
||||||
end
|
|
||||||
return nothing
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
"""
|
"""
|
||||||
`@gp args...`
|
`@gp args...`
|
||||||
@ -1015,6 +894,38 @@ end
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
|
# │ FUNCTIONS MEANT TO BE INVOKED BY USERS │
|
||||||
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
"""
|
||||||
|
`quit()`
|
||||||
|
|
||||||
|
Quit the session and the associated gnuplot process (if any).
|
||||||
|
"""
|
||||||
|
function quit(sid::Symbol)
|
||||||
|
global state
|
||||||
|
if !(sid in keys(state.sessions))
|
||||||
|
error("Gnuplot session $sid do not exists")
|
||||||
|
end
|
||||||
|
return quit(state.sessions[sid])
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
`quitall()`
|
||||||
|
|
||||||
|
Quit all the sessions and the associated gnuplot processes.
|
||||||
|
"""
|
||||||
|
function quitall()
|
||||||
|
global state
|
||||||
|
for sid in keys(state.sessions)
|
||||||
|
quit(sid)
|
||||||
|
end
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
"""
|
"""
|
||||||
`exec(sid::Symbol, s::Vector{String})`
|
`exec(sid::Symbol, s::Vector{String})`
|
||||||
@ -1055,11 +966,6 @@ function setverbose(b::Bool)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function initcmd()
|
|
||||||
global state
|
|
||||||
return state.initcmd
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
"""
|
"""
|
||||||
@ -1077,12 +983,12 @@ To save the data and command from a specific session pass the ID as first argume
|
|||||||
|
|
||||||
In all cases the `term` keyword allows to specify a gnuplot terminal, and the `output` keyword allows to specify an output file.
|
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( ; kw...) = dump(getsession() ; kw...)
|
||||||
save(sid::Symbol ; kw...) = internal_save(getsession(sid) ; kw...)
|
save(sid::Symbol ; kw...) = dump(getsession(sid) ; kw...)
|
||||||
save( stream::IO ; kw...) = internal_save(getsession() , stream; kw...)
|
save( stream::IO ; kw...) = dump(getsession() , stream; kw...)
|
||||||
save(sid::Symbol, stream::IO ; kw...) = internal_save(getsession(sid), stream; kw...)
|
save(sid::Symbol, stream::IO ; kw...) = dump(getsession(sid), stream; kw...)
|
||||||
save( file::AbstractString; kw...) = open(file, "w") do stream; internal_save(getsession() , stream; kw...); end
|
save( file::AbstractString; kw...) = open(file, "w") do stream; dump(getsession() , stream; kw...); end
|
||||||
save(sid::Symbol, file::AbstractString; kw...) = open(file, "w") do stream; internal_save(getsession(sid), stream; kw...); end
|
save(sid::Symbol, file::AbstractString; kw...) = open(file, "w") do stream; dump(getsession(sid), stream; kw...); end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|||||||
@ -3,41 +3,30 @@ using Test, Gnuplot
|
|||||||
x = [1, 2, 3]
|
x = [1, 2, 3]
|
||||||
y = [4, 5, 6]
|
y = [4, 5, 6]
|
||||||
|
|
||||||
s = Gnuplot.dataset(1)
|
s = Gnuplot.data2string(1)
|
||||||
@test all(s .== [" << EOD",
|
@test all(s .== [" 1"])
|
||||||
" 1" ,
|
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
s = Gnuplot.dataset(1, 2)
|
s = Gnuplot.data2string(1, 2)
|
||||||
@test all(s .== [" << EOD",
|
@test all(s .== [" 1 2"])
|
||||||
" 1 2" ,
|
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
s = Gnuplot.dataset(x)
|
s = Gnuplot.data2string(x)
|
||||||
@test all(s .== [" << EOD",
|
@test all(s .== [" 1" ,
|
||||||
" 1" ,
|
|
||||||
" 2" ,
|
" 2" ,
|
||||||
" 3" ,
|
" 3" ])
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
s = Gnuplot.dataset(x, y)
|
s = Gnuplot.data2string(x, y)
|
||||||
@test all(s .== [ " << EOD",
|
@test all(s .== [" 1 4",
|
||||||
" 1 4",
|
|
||||||
" 2 5",
|
" 2 5",
|
||||||
" 3 6",
|
" 3 6"])
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
s = Gnuplot.dataset(x, y, x.+y)
|
s = Gnuplot.data2string(x, y, x.+y)
|
||||||
@test all(s .== [ " << EOD",
|
@test all(s .== [" 1 4 5",
|
||||||
" 1 4 5",
|
|
||||||
" 2 5 7",
|
" 2 5 7",
|
||||||
" 3 6 9",
|
" 3 6 9"])
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
z = [X+Y for X in x, Y in y];
|
z = [X+Y for X in x, Y in y];
|
||||||
s = Gnuplot.dataset(z)
|
s = Gnuplot.data2string(z)
|
||||||
@test all(s .== [" << EOD",
|
@test all(s .== [" 1 1 5" ,
|
||||||
" 1 1 5" ,
|
|
||||||
" 2 1 6" ,
|
" 2 1 6" ,
|
||||||
" 3 1 7" ,
|
" 3 1 7" ,
|
||||||
"" ,
|
"" ,
|
||||||
@ -47,13 +36,11 @@ s = Gnuplot.dataset(z)
|
|||||||
"" ,
|
"" ,
|
||||||
" 1 3 7" ,
|
" 1 3 7" ,
|
||||||
" 2 3 8" ,
|
" 2 3 8" ,
|
||||||
" 3 3 9" ,
|
" 3 3 9" ])
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
|
|
||||||
s = Gnuplot.dataset(x, y, z)
|
s = Gnuplot.data2string(x, y, z)
|
||||||
@test all(s .== [" << EOD",
|
@test all(s .== [" 1 4 5" ,
|
||||||
" 1 4 5" ,
|
|
||||||
" 2 4 6" ,
|
" 2 4 6" ,
|
||||||
" 3 4 7" ,
|
" 3 4 7" ,
|
||||||
"" ,
|
"" ,
|
||||||
@ -63,8 +50,7 @@ s = Gnuplot.dataset(x, y, z)
|
|||||||
"" ,
|
"" ,
|
||||||
" 1 6 7" ,
|
" 1 6 7" ,
|
||||||
" 2 6 8" ,
|
" 2 6 8" ,
|
||||||
" 3 6 9" ,
|
" 3 6 9" ])
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -72,9 +58,8 @@ c = [[X, Y] for Y in y for X in x]; # First Y (i.e. rows) then X (i.e. columns)
|
|||||||
u = getindex.(c, 1)
|
u = getindex.(c, 1)
|
||||||
v = getindex.(c, 2)
|
v = getindex.(c, 2)
|
||||||
|
|
||||||
s = Gnuplot.dataset(u, v, z)
|
s = Gnuplot.data2string(u, v, z)
|
||||||
@test all(s .== [" << EOD",
|
@test all(s .== [" 1 4 5" ,
|
||||||
" 1 4 5" ,
|
|
||||||
" 2 4 6" ,
|
" 2 4 6" ,
|
||||||
" 3 4 7" ,
|
" 3 4 7" ,
|
||||||
"" ,
|
"" ,
|
||||||
@ -84,8 +69,7 @@ s = Gnuplot.dataset(u, v, z)
|
|||||||
"" ,
|
"" ,
|
||||||
" 1 6 7" ,
|
" 1 6 7" ,
|
||||||
" 2 6 8" ,
|
" 2 6 8" ,
|
||||||
" 3 6 9" ,
|
" 3 6 9" ])
|
||||||
"EOD" ])
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------
|
#-----------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user