Fixed recipe interface; DatasetBin methods for images are now implemented as recipes
This commit is contained in:
parent
7a647f08e1
commit
f8d239d9c2
202
src/Gnuplot.jl
202
src/Gnuplot.jl
@ -15,39 +15,39 @@ export session_names, dataset_names, palette_names, linetypes, palette,
|
|||||||
# │ TYPE DEFINITIONS │
|
# │ TYPE DEFINITIONS │
|
||||||
# ╰───────────────────────────────────────────────────────────────────╯
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
abstract type DataSet end
|
abstract type Dataset end
|
||||||
|
|
||||||
mutable struct DataSetText <: DataSet
|
mutable struct DatasetText <: Dataset
|
||||||
preview::Vector{String}
|
preview::Vector{String}
|
||||||
data::String
|
data::String
|
||||||
DataSetText(::Val{:inner}, preview, data) = new(preview, data)
|
DatasetText(::Val{:inner}, preview, data) = new(preview, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
mutable struct DataSetBin <: DataSet
|
mutable struct DatasetBin <: Dataset
|
||||||
file::String
|
file::String
|
||||||
source::String
|
source::String
|
||||||
DataSetBin(::Val{:inner}, file, source) = new(file, source)
|
DatasetBin(::Val{:inner}, file, source) = new(file, source)
|
||||||
end
|
end
|
||||||
|
|
||||||
struct PlotRecipe
|
struct PlotElements
|
||||||
mid::Int
|
mid::Int
|
||||||
cmds::Vector{String}
|
cmds::Vector{String}
|
||||||
data::Vector{DataSet}
|
data::Vector{Dataset}
|
||||||
plot::Vector{String}
|
plot::Vector{String}
|
||||||
|
|
||||||
function PlotRecipe(;mid::Int=0,
|
function PlotElements(;mid::Int=0,
|
||||||
cmds::Union{String, Vector{String}}=Vector{String}(),
|
cmds::Union{String, Vector{String}}=Vector{String}(),
|
||||||
data::Union{DataSet, Vector{DataSet}}=Vector{DataSet}(),
|
data::Union{Dataset, Vector{Dataset}}=Vector{Dataset}(),
|
||||||
plot::Union{String, Vector{String}}="",
|
plot::Union{String, Vector{String}}="",
|
||||||
kwargs...)
|
kwargs...)
|
||||||
c = isa(cmds, String) ? [cmds] : cmds
|
c = isa(cmds, String) ? [cmds] : cmds
|
||||||
append!(c, parseKeywords(; kwargs...))
|
append!(c, parseKeywords(; kwargs...))
|
||||||
new(mid, c,
|
new(mid, c,
|
||||||
isa(data, DataSet) ? [data] : data,
|
isa(data, Dataset) ? [data] : data,
|
||||||
isa(plot, String) ? [plot] : plot)
|
isa(plot, String) ? [plot] : plot)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
plotrecipe() = nothing
|
recipe() = nothing
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
@ -64,7 +64,7 @@ abstract type Session end
|
|||||||
|
|
||||||
mutable struct DrySession <: Session
|
mutable struct DrySession <: Session
|
||||||
sid::Symbol # session ID
|
sid::Symbol # session ID
|
||||||
datas::OrderedDict{String, DataSet} # data sets
|
datas::OrderedDict{String, Dataset} # data sets
|
||||||
plots::Vector{SinglePlot} # commands and plot commands (one entry for each plot of the multiplot)
|
plots::Vector{SinglePlot} # commands and plot commands (one entry for each plot of the multiplot)
|
||||||
curmid::Int # current multiplot ID
|
curmid::Int # current multiplot ID
|
||||||
end
|
end
|
||||||
@ -73,7 +73,7 @@ end
|
|||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
mutable struct GPSession <: Session
|
mutable struct GPSession <: Session
|
||||||
sid::Symbol # session ID
|
sid::Symbol # session ID
|
||||||
datas::OrderedDict{String, DataSet} # data sets
|
datas::OrderedDict{String, Dataset} # data sets
|
||||||
plots::Vector{SinglePlot} # commands and plot commands (one entry for each plot of the multiplot)
|
plots::Vector{SinglePlot} # commands and plot commands (one entry for each plot of the multiplot)
|
||||||
curmid::Int # current multiplot ID
|
curmid::Int # current multiplot ID
|
||||||
pin::Base.Pipe;
|
pin::Base.Pipe;
|
||||||
@ -307,7 +307,7 @@ end
|
|||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function DrySession(sid::Symbol)
|
function DrySession(sid::Symbol)
|
||||||
(sid in keys(sessions)) && error("Gnuplot session $sid is already active")
|
(sid in keys(sessions)) && error("Gnuplot session $sid is already active")
|
||||||
out = DrySession(sid, OrderedDict{String, DataSet}(), [SinglePlot()], 1)
|
out = DrySession(sid, OrderedDict{String, Dataset}(), [SinglePlot()], 1)
|
||||||
sessions[sid] = out
|
sessions[sid] = out
|
||||||
return out
|
return out
|
||||||
end
|
end
|
||||||
@ -470,9 +470,9 @@ function write(gp::GPSession, str::AbstractString)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
write(gp::DrySession, name::String, d::DataSet) = nothing
|
write(gp::DrySession, name::String, d::Dataset) = nothing
|
||||||
write(gp::GPSession, name::String, d::DataSetBin) = nothing
|
write(gp::GPSession, name::String, d::DatasetBin) = nothing
|
||||||
function write(gp::GPSession, name::String, d::DataSetText)
|
function write(gp::GPSession, name::String, d::DatasetText)
|
||||||
if options.verbose
|
if options.verbose
|
||||||
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) ", name, " << EOD\n")
|
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) ", name, " << EOD\n")
|
||||||
printstyled(color=:light_black, join("GNUPLOT ($(gp.sid)) " .* d.preview, "\n") * "\n")
|
printstyled(color=:light_black, join("GNUPLOT ($(gp.sid)) " .* d.preview, "\n") * "\n")
|
||||||
@ -530,7 +530,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
# ╭───────────────────────────────────────────────────────────────────╮
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
# │ DataSet CONSTRUCTORS │
|
# │ Dataset CONSTRUCTORS │
|
||||||
# ╰───────────────────────────────────────────────────────────────────╯
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
#=
|
#=
|
||||||
@ -555,80 +555,27 @@ end
|
|||||||
=#
|
=#
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function DataSetBin(M::Matrix{T}) where T <: Number
|
function DatasetBin(VM::Vararg{AbstractMatrix{T}, N}) where {T <: Number, N}
|
||||||
|
for i in 2:N
|
||||||
|
@assert size(VM[i]) == size(VM[1])
|
||||||
|
end
|
||||||
|
s = size(VM[1])
|
||||||
(path, io) = mktemp()
|
(path, io) = mktemp()
|
||||||
for j in 1:size(M)[2]
|
for j in 1:s[2]
|
||||||
for i in 1:size(M)[1]
|
for i in 1:s[1]
|
||||||
write(io, Float32(M[i,j]))
|
for k in 1:N
|
||||||
|
write(io, Float32(VM[k][i,j]))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
close(io)
|
close(io)
|
||||||
source = " '$path' binary array=(" * join(string.(size(M)), ", ") * ")"
|
source = " '$path' binary array=(" * join(string.(s), ", ") * ")"
|
||||||
return DataSetBin(Val(:inner), path, source)
|
return DatasetBin(Val(:inner), path, source)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function DataSetBin(M::Matrix{ColorTypes.RGB{T}}) where T
|
function DatasetBin(cols::Vararg{AbstractVector, N}) where N
|
||||||
(path, io) = mktemp()
|
|
||||||
for j in 1:size(M)[2]
|
|
||||||
for i in 1:size(M)[1]
|
|
||||||
write(io, Float32(256 * M[i,j].r))
|
|
||||||
write(io, Float32(256 * M[i,j].g))
|
|
||||||
write(io, Float32(256 * M[i,j].b))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
close(io)
|
|
||||||
source = " '$path' binary array=(" * join(string.(size(M)), ", ") * ")"
|
|
||||||
return DataSetBin(Val(:inner), path, source)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
function DataSetBin(M::Matrix{ColorTypes.RGBA{T}}) where T
|
|
||||||
(path, io) = mktemp()
|
|
||||||
for j in 1:size(M)[2]
|
|
||||||
for i in 1:size(M)[1]
|
|
||||||
write(io, Float32(256 * M[i,j].r))
|
|
||||||
write(io, Float32(256 * M[i,j].g))
|
|
||||||
write(io, Float32(256 * M[i,j].b))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
close(io)
|
|
||||||
source = " '$path' binary array=(" * join(string.(size(M)), ", ") * ")"
|
|
||||||
return DataSetBin(Val(:inner), path, source)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
function DataSetBin(M::Matrix{ColorTypes.Gray{T}}) where T
|
|
||||||
(path, io) = mktemp()
|
|
||||||
for j in 1:size(M)[2]
|
|
||||||
for i in 1:size(M)[1]
|
|
||||||
write(io, Float32(256 * M[i,j].val))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
close(io)
|
|
||||||
source = " '$path' binary array=(" * join(string.(size(M)), ", ") * ")"
|
|
||||||
return DataSetBin(Val(:inner), path, source, "")
|
|
||||||
end
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
function DataSetBin(M::Matrix{ColorTypes.GrayA{T}}) where T
|
|
||||||
(path, io) = mktemp()
|
|
||||||
for j in 1:size(M)[2]
|
|
||||||
for i in 1:size(M)[1]
|
|
||||||
write(io, Float32(256 * M[i,j].val))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
close(io)
|
|
||||||
source = " '$path' binary array=(" * join(string.(size(M)), ", ") * ")"
|
|
||||||
return DataSetBin(Val(:inner), path, source)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
function DataSetBin(cols::Vararg{AbstractVector, N}) where N
|
|
||||||
source = "binary record=$(length(cols[1])) format='"
|
source = "binary record=$(length(cols[1])) format='"
|
||||||
types = Vector{DataType}()
|
types = Vector{DataType}()
|
||||||
(length(cols) == 1) && (source *= "%int")
|
(length(cols) == 1) && (source *= "%int")
|
||||||
@ -654,15 +601,15 @@ function DataSetBin(cols::Vararg{AbstractVector, N}) where N
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
close(io)
|
close(io)
|
||||||
return DataSetBin(Val(:inner), path, source)
|
return DatasetBin(Val(:inner), path, source)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
DataSetText(args...) = DataSetText(arrays2datablock(args...))
|
DatasetText(args...) = DatasetText(arrays2datablock(args...))
|
||||||
function DataSetText(data::Vector{String})
|
function DatasetText(data::Vector{String})
|
||||||
preview = (length(data) <= 4 ? deepcopy(data) : [data[1:4]..., "..."])
|
preview = (length(data) <= 4 ? deepcopy(data) : [data[1:4]..., "..."])
|
||||||
d = DataSetText(Val(:inner), preview, join(data, "\n"))
|
d = DatasetText(Val(:inner), preview, join(data, "\n"))
|
||||||
return d
|
return d
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -673,7 +620,7 @@ end
|
|||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function reset(gp::Session)
|
function reset(gp::Session)
|
||||||
delete_binaries(gp)
|
delete_binaries(gp)
|
||||||
gp.datas = OrderedDict{String, DataSet}()
|
gp.datas = OrderedDict{String, Dataset}()
|
||||||
gp.plots = [SinglePlot()]
|
gp.plots = [SinglePlot()]
|
||||||
gp.curmid = 1
|
gp.curmid = 1
|
||||||
gpexec(gp, "set output")
|
gpexec(gp, "set output")
|
||||||
@ -695,7 +642,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
newDataSetName(gp::Session) = string("\$data", length(gp.datas)+1)
|
newDatasetName(gp::Session) = string("\$data", length(gp.datas)+1)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
@ -737,7 +684,7 @@ end
|
|||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
function delete_binaries(gp::Session)
|
function delete_binaries(gp::Session)
|
||||||
for (name, d) in gp.datas
|
for (name, d) in gp.datas
|
||||||
if isa(d, DataSetBin) && (d.file != "")
|
if isa(d, DatasetBin) && (d.file != "")
|
||||||
rm(d.file, force=true)
|
rm(d.file, force=true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -850,7 +797,7 @@ function savescript(gp::Session, filename; term::AbstractString="", output::Abst
|
|||||||
path_to = Vector{String}()
|
path_to = Vector{String}()
|
||||||
datapath = data_dirname(filename)
|
datapath = data_dirname(filename)
|
||||||
for (name, d) in gp.datas
|
for (name, d) in gp.datas
|
||||||
if isa(d, DataSetBin) && (d.file != "")
|
if isa(d, DatasetBin) && (d.file != "")
|
||||||
if (length(path_from) == 0)
|
if (length(path_from) == 0)
|
||||||
isdir(datapath) && rm(datapath, recursive=true)
|
isdir(datapath) && rm(datapath, recursive=true)
|
||||||
mkdir(datapath)
|
mkdir(datapath)
|
||||||
@ -886,7 +833,7 @@ function savescript(gp::Session, filename; term::AbstractString="", output::Abst
|
|||||||
|
|
||||||
paths = copy_binary_files(gp, filename)
|
paths = copy_binary_files(gp, filename)
|
||||||
for (name, d) in gp.datas
|
for (name, d) in gp.datas
|
||||||
if isa(d, DataSetText)
|
if isa(d, DatasetText)
|
||||||
println(stream, name * " << EOD")
|
println(stream, name * " << EOD")
|
||||||
println(stream, d.data)
|
println(stream, d.data)
|
||||||
println(stream, "EOD")
|
println(stream, "EOD")
|
||||||
@ -929,7 +876,7 @@ function driver(args...; flag3d=false)
|
|||||||
|
|
||||||
if cmd != ""
|
if cmd != ""
|
||||||
for (name, d) in gp.datas
|
for (name, d) in gp.datas
|
||||||
if isa(d, DataSetBin) && (d.file != "")
|
if isa(d, DatasetBin) && (d.file != "")
|
||||||
cmd = replace(cmd, name => d.source)
|
cmd = replace(cmd, name => d.source)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -973,35 +920,35 @@ function driver(args...; flag3d=false)
|
|||||||
plotspec = nothing
|
plotspec = nothing
|
||||||
function dataset_ready()
|
function dataset_ready()
|
||||||
if length(dataAccum) > 0
|
if length(dataAccum) > 0
|
||||||
# Ensure DataSet objects are processed one at a time
|
# Ensure Dataset objects are processed one at a time
|
||||||
for i in 1:length(dataAccum)
|
for i in 1:length(dataAccum)
|
||||||
@assert !isa(dataAccum[i], DataSet) || (length(dataAccum) == 1)
|
@assert !isa(dataAccum[i], Dataset) || (length(dataAccum) == 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if dataset is empty
|
# Check if dataset is empty
|
||||||
emptyset = false
|
emptyset = false
|
||||||
if !isa(dataAccum[1], DataSet)
|
if !isa(dataAccum[1], Dataset)
|
||||||
mm = extrema(length.(dataAccum))
|
mm = extrema(length.(dataAccum))
|
||||||
(mm[1] == 0) && (@assert mm[1] == mm[2] "At least one input array is empty, while other(s) are not")
|
(mm[1] == 0) && (@assert mm[1] == mm[2] "At least one input array is empty, while other(s) are not")
|
||||||
emptyset = (mm[2] == 0)
|
emptyset = (mm[2] == 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
if !emptyset
|
if !emptyset
|
||||||
if isa(dataAccum[1], DataSet)
|
if isa(dataAccum[1], Dataset)
|
||||||
d = dataAccum[1]
|
d = dataAccum[1]
|
||||||
else
|
else
|
||||||
if sendAsBinary(dataAccum...)
|
if sendAsBinary(dataAccum...)
|
||||||
d = DataSetBin(dataAccum...)
|
d = DatasetBin(dataAccum...)
|
||||||
else
|
else
|
||||||
d = DataSetText(dataAccum...)
|
d = DatasetText(dataAccum...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
isnothing(dsetname) && (dsetname = newDataSetName(gp))
|
isnothing(dsetname) && (dsetname = newDatasetName(gp))
|
||||||
gp.datas[dsetname] = d
|
gp.datas[dsetname] = d
|
||||||
write(gp, dsetname, d) # send now to gnuplot process
|
write(gp, dsetname, d) # send now to gnuplot process
|
||||||
if !isnothing(plotspec)
|
if !isnothing(plotspec)
|
||||||
if isa(d, DataSetBin)
|
if isa(d, DatasetBin)
|
||||||
add_plot(gp, d.source * " " * plotspec)
|
add_plot(gp, d.source * " " * plotspec)
|
||||||
else
|
else
|
||||||
add_plot(gp, dsetname * " " * plotspec)
|
add_plot(gp, dsetname * " " * plotspec)
|
||||||
@ -1054,7 +1001,7 @@ function driver(args...; flag3d=false)
|
|||||||
push!(dataAccum, arg)
|
push!(dataAccum, arg)
|
||||||
elseif isa(arg, Real) # ==> a dataset column with only one row
|
elseif isa(arg, Real) # ==> a dataset column with only one row
|
||||||
push!(dataAccum, arg)
|
push!(dataAccum, arg)
|
||||||
elseif isa(arg, DataSet)
|
elseif isa(arg, Dataset)
|
||||||
push!(dataAccum, arg)
|
push!(dataAccum, arg)
|
||||||
else
|
else
|
||||||
error("Unexpected argument at position $iarg with type " * string(typeof(arg)))
|
error("Unexpected argument at position $iarg with type " * string(typeof(arg)))
|
||||||
@ -1070,7 +1017,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function expandrecipes(args...; flag3d=false)
|
function expandrecipes(args...; flag3d=false)
|
||||||
function push_recipe!(out::Vector{Any}, pr::PlotRecipe)
|
function push_elements!(out::Vector{Any}, pr::PlotElements)
|
||||||
@assert length(pr.data) <= length(pr.plot)
|
@assert length(pr.data) <= length(pr.plot)
|
||||||
(pr.mid > 0) && push!(out, pr.mid)
|
(pr.mid > 0) && push!(out, pr.mid)
|
||||||
append!(out, pr.cmds)
|
append!(out, pr.cmds)
|
||||||
@ -1079,19 +1026,22 @@ function expandrecipes(args...; flag3d=false)
|
|||||||
push!(out, pr.plot[i])
|
push!(out, pr.plot[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function push_elements!(out::Vector{Any}, v::Vector{PlotElements})
|
||||||
|
for pr in v
|
||||||
|
push_elements!(out, pr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
out = Vector{Any}()
|
out = Vector{Any}()
|
||||||
for arg in args
|
for arg in args
|
||||||
if hasmethod(plotrecipe, tuple(typeof(arg)))
|
if hasmethod(recipe, tuple(typeof(arg))) # implicit recipe
|
||||||
push_recipe!(out, plotrecipe(arg))
|
push_elements!(out, recipe(arg))
|
||||||
elseif isa(arg, PlotRecipe)
|
elseif isa(arg, PlotElements) # explicit recipe (scalar)
|
||||||
push_recipe!(out, arg)
|
push_elements!(out, arg)
|
||||||
elseif isa(arg, Vector{PlotRecipe})
|
elseif isa(arg, Vector{PlotElements}) # explicit recipe (vector)
|
||||||
for pr in arg
|
push_elements!(out, pr)
|
||||||
push_recipe!(out, pr)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
push!(out, arg)
|
push!(out, arg) # simple argument
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
driver(out...; flag3d=flag3d)
|
driver(out...; flag3d=flag3d)
|
||||||
@ -1756,29 +1706,18 @@ function contourlines(args...; cntrparam="level auto 10")
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ╭───────────────────────────────────────────────────────────────────╮
|
|
||||||
# │ RECIPES │
|
|
||||||
# ╰───────────────────────────────────────────────────────────────────╯
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
plotrecipe(h::Histogram1D) = PlotRecipe(cmds="set grid", data=DataSetText(h.bins, h.counts), plot="w histep notit lw 2 lc rgb 'black'")
|
|
||||||
plotrecipe(h::Histogram2D) = PlotRecipe(cmds="set autoscale fix", data=DataSetText(h.bins1, h.bins2, h.counts), plot="w image notit 'black'")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ╭───────────────────────────────────────────────────────────────────╮
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
# │ GNUPLOT REPL │
|
# │ GNUPLOT REPL │
|
||||||
# ╰───────────────────────────────────────────────────────────────────╯
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
"""
|
"""
|
||||||
Gnuplot.init_repl(start_key='>')
|
Gnuplot.init_repl(; start_key='>')
|
||||||
|
|
||||||
Install a hook to replace the common Julia REPL with a gnuplot one. The key to start the REPL is the one provided in `start_key` (default: `>`).
|
Install a hook to replace the common Julia REPL with a gnuplot one. The key to start the REPL is the one provided in `start_key` (default: `>`).
|
||||||
|
|
||||||
Note: the gnuplot REPL operates only on the default session.
|
Note: the gnuplot REPL operates only on the default session.
|
||||||
"""
|
"""
|
||||||
function repl_init(start_key='>')
|
function repl_init(; start_key='>')
|
||||||
function repl_exec(s)
|
function repl_exec(s)
|
||||||
for s in writeread(getsession(), s)
|
for s in writeread(getsession(), s)
|
||||||
println(s)
|
println(s)
|
||||||
@ -1800,4 +1739,9 @@ function repl_init(start_key='>')
|
|||||||
valid_input_checker=repl_isvalid)
|
valid_input_checker=repl_isvalid)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
include("recipes.jl")
|
||||||
|
|
||||||
|
|
||||||
end #module
|
end #module
|
||||||
|
|||||||
71
src/recipes.jl
Normal file
71
src/recipes.jl
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
|
# │ IMPLICIT RECIPES │
|
||||||
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# Histograms
|
||||||
|
recipe(h::Histogram1D) =
|
||||||
|
PlotElements(cmds="set grid",
|
||||||
|
data=DatasetText(h.bins, h.counts),
|
||||||
|
plot="w histep notit lw 2 lc rgb 'black'")
|
||||||
|
|
||||||
|
recipe(h::Histogram2D) =
|
||||||
|
PlotElements(cmds=["set autoscale fix", "set size ratio -1"],
|
||||||
|
data=DatasetText(h.bins1, h.bins2, h.counts),
|
||||||
|
plot="w image notit")
|
||||||
|
|
||||||
|
# Images
|
||||||
|
recipe(M::Matrix{ColorTypes.RGB{T}}) where T =
|
||||||
|
PlotElements(cmds=["set autoscale fix", "set size square"],
|
||||||
|
data=DatasetBin(256 .* getfield.(M, :r),
|
||||||
|
256 .* getfield.(M, :g),
|
||||||
|
256 .* getfield.(M, :b)),
|
||||||
|
plot="rotate=-90deg with rgbimage notit")
|
||||||
|
|
||||||
|
recipe(M::Matrix{ColorTypes.RGBA{T}}) where T =
|
||||||
|
PlotElements(cmds=["set autoscale fix", "set size square"],
|
||||||
|
data=DatasetBin(256 .* getfield.(M, :r),
|
||||||
|
256 .* getfield.(M, :g),
|
||||||
|
256 .* getfield.(M, :b)),
|
||||||
|
plot="rotate=-90deg with rgbimage notit")
|
||||||
|
|
||||||
|
recipe(M::Matrix{ColorTypes.Gray{T}}) where T =
|
||||||
|
PlotElements(cmds=["set autoscale fix", "set size square"],
|
||||||
|
data=DatasetBin(256 .* getfield.(M, :val)),
|
||||||
|
plot="rotate=-90deg with image notit")
|
||||||
|
|
||||||
|
recipe(M::Matrix{ColorTypes.GrayA{T}}) where T =
|
||||||
|
PlotElements(cmds=["set autoscale fix", "set size square"],
|
||||||
|
data=DatasetBin(256 .* getfield.(M, :val)),
|
||||||
|
plot="rotate=-90deg with image notit")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ╭───────────────────────────────────────────────────────────────────╮
|
||||||
|
# │ EXPLICIT RECIPES │
|
||||||
|
# ╰───────────────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
macro recipes_DataFrames()
|
||||||
|
return esc(:(
|
||||||
|
function plotdf(df::DataFrame, colx::Symbol, coly::Symbol; group=nothing);
|
||||||
|
if isnothing(group);
|
||||||
|
return Gnuplot.PlotElements(data=Gnuplot.DatasetText(df[:, colx], df[:, coly]),
|
||||||
|
plot="w p notit",
|
||||||
|
xlab=string(colx), ylab=string(coly));
|
||||||
|
end;
|
||||||
|
|
||||||
|
data = Vector{Gnuplot.Dataset}();
|
||||||
|
plot = Vector{String}();
|
||||||
|
for g in sort(unique(df[:, group]));
|
||||||
|
i = findall(df[:, group] .== g);
|
||||||
|
if length(i) > 0;
|
||||||
|
push!(data, Gnuplot.DatasetText(df[i, colx], df[i, coly]));
|
||||||
|
push!(plot, "w p t '$g'");
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
return Gnuplot.PlotElements(data=data, plot=plot,
|
||||||
|
xlab=string(colx), ylab=string(coly));
|
||||||
|
end
|
||||||
|
))
|
||||||
|
end
|
||||||
@ -97,7 +97,7 @@ s = Gnuplot.arrays2datablock(1:3, 1:3, ["One", "Two", "Three"])
|
|||||||
pal = palette(:deepsea)
|
pal = palette(:deepsea)
|
||||||
@test pal == "set palette defined (0.0 '#2B004D', 0.25 '#4E0F99', 0.5 '#3C54D4', 0.75 '#48A9F8', 1.0 '#C5ECFF')\nset palette maxcol 5\n"
|
@test pal == "set palette defined (0.0 '#2B004D', 0.25 '#4E0F99', 0.5 '#3C54D4', 0.75 '#48A9F8', 1.0 '#C5ECFF')\nset palette maxcol 5\n"
|
||||||
ls = linetypes(:deepsea)
|
ls = linetypes(:deepsea)
|
||||||
@test ls == "set linetype 1 lc rgb '#2B004D\nset linetype 2 lc rgb '#4E0F99\nset linetype 3 lc rgb '#3C54D4\nset linetype 4 lc rgb '#48A9F8\nset linetype 5 lc rgb '#C5ECFF\nset linetype cycle 5\n"
|
@test ls == "unset for [i=1:256] linetype i\nset linetype 1 lc rgb '#2B004D' lw 1 dt solid pt 1 ps default\nset linetype 2 lc rgb '#4E0F99' lw 1 dt solid pt 2 ps default\nset linetype 3 lc rgb '#3C54D4' lw 1 dt solid pt 3 ps default\nset linetype 4 lc rgb '#48A9F8' lw 1 dt solid pt 4 ps default\nset linetype 5 lc rgb '#C5ECFF' lw 1 dt solid pt 5 ps default\nset linetype cycle 5\n"
|
||||||
|
|
||||||
#-----------------------------------------------------------------
|
#-----------------------------------------------------------------
|
||||||
# Test wth empty dataset
|
# Test wth empty dataset
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user