Updated hist function, added contourlines
This commit is contained in:
parent
e36563990a
commit
5d6169b993
184
src/Gnuplot.jl
184
src/Gnuplot.jl
@ -10,7 +10,7 @@ import Base.iterate
|
|||||||
import Base.convert
|
import Base.convert
|
||||||
|
|
||||||
export gnuplot, quit, quitall, setverbose,
|
export gnuplot, quit, quitall, setverbose,
|
||||||
@gp, @gsp, exec, save, hist
|
@gp, @gsp, exec, save, contourlines, hist
|
||||||
|
|
||||||
|
|
||||||
#_____________________________________________________________________
|
#_____________________________________________________________________
|
||||||
@ -65,15 +65,6 @@ end
|
|||||||
const state = State()
|
const state = State()
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
mutable struct PackedDataAndCmds
|
|
||||||
data::Vector{Any}
|
|
||||||
name::String
|
|
||||||
cmds::Vector{String}
|
|
||||||
plot::Vector{String}
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
#_____________________________________________________________________
|
#_____________________________________________________________________
|
||||||
# "PRIVATE" (NON-EXPORTED) FUNCTIONS
|
# "PRIVATE" (NON-EXPORTED) FUNCTIONS
|
||||||
#_____________________________________________________________________
|
#_____________________________________________________________________
|
||||||
@ -212,6 +203,31 @@ function println(gp::Session, str::AbstractString)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function println(gp::Session, d::DataSource)
|
||||||
|
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 nothing
|
||||||
|
end
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
writeread(gp::DrySession, str::AbstractString) = ""
|
writeread(gp::DrySession, str::AbstractString) = ""
|
||||||
function writeread(gp::Session, str::AbstractString)
|
function writeread(gp::Session, str::AbstractString)
|
||||||
@ -264,6 +280,23 @@ function setmulti(gp::DrySession, mid::Int)
|
|||||||
end
|
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 = DataSource(name, accum)
|
||||||
|
push!(gp.datas, d)
|
||||||
|
|
||||||
|
println(gp, d) # Send directly to gnuplot process
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
function newdatasource(gp::DrySession, args...; name="")
|
function newdatasource(gp::DrySession, args...; name="")
|
||||||
toString(n::Number) = @sprintf("%.4g", n)
|
toString(n::Number) = @sprintf("%.4g", n)
|
||||||
@ -405,29 +438,7 @@ function newdatasource(gp::DrySession, args...; name="")
|
|||||||
d = DataSource(name, accum)
|
d = DataSource(name, accum)
|
||||||
push!(gp.datas, d)
|
push!(gp.datas, d)
|
||||||
|
|
||||||
# Send data immediately to gnuplot process
|
println(gp, d) # Send directly 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
|
||||||
|
|
||||||
@ -637,12 +648,6 @@ function driver(args...; flag3d=false)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif typeof(arg) == PackedDataAndCmds
|
|
||||||
if loop == 2
|
|
||||||
last = newdatasource(gp, arg.data..., name=arg.name)
|
|
||||||
for v in arg.cmds; newcmd(gp, v); end
|
|
||||||
for v in arg.plot; newplotelem(gp, last, v); end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
(loop == 2) && push!(data, arg) # a data set
|
(loop == 2) && push!(data, arg) # a data set
|
||||||
end
|
end
|
||||||
@ -783,7 +788,7 @@ The macros accepts any number of arguments, with the following meaning:
|
|||||||
- a string starting with a `\$` sign: a data set name;
|
- a string starting with a `\$` sign: a data set name;
|
||||||
- an `Int` > 0: the plot destination in a multiplot session;
|
- an `Int` > 0: the plot destination in a multiplot session;
|
||||||
- a keyword/value pair: a keyword value (see below);
|
- a keyword/value pair: a keyword value (see below);
|
||||||
- any other type: a dataset to be passed to Gnuplot. Each dataset must be terminated by either:
|
- any other type: a dataset to be passed to Gnuplot. Each dataset must be terminated by either:
|
||||||
- a string starting with a `\$` sign (i.e. the data set name);
|
- a string starting with a `\$` sign (i.e. the data set name);
|
||||||
- or a string with the plot specifications (e.g. "with lines");
|
- 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.
|
- 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.
|
||||||
@ -1041,13 +1046,102 @@ save(sid::Symbol, file::AbstractString; kw...) = open(file, "w") do stream; inte
|
|||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
function hist(v::Vector{T}; addright=false, closed::Symbol=:left, args...) where T <: AbstractFloat
|
#=
|
||||||
|
Example:
|
||||||
|
v = randn(1000)
|
||||||
|
h = hist(v, bs=0.2)
|
||||||
|
@gp h.loc h.counts "w histep" h.loc h.counts "w l"
|
||||||
|
=#
|
||||||
|
function hist(v::Vector{T}; range=[NaN,NaN], bs=NaN, nbins=0, pad=true) where T <: Number
|
||||||
i = findall(isfinite.(v))
|
i = findall(isfinite.(v))
|
||||||
hh = fit(Histogram, v[i]; closed=closed, args...)
|
isnan(range[1]) && (range[1] = minimum(v[i]))
|
||||||
if addright == 0
|
isnan(range[2]) && (range[2] = maximum(v[i]))
|
||||||
return PackedDataAndCmds([hh.edges[1], [hh.weights;0]], "", [], ["w steps notit"])
|
i = findall(isfinite.(v) .& (v.>= range[1]) .& (v.<= range[2]))
|
||||||
|
isfinite(bs) && (nbins = Int(ceil((range[2] - range[1]) / bs)))
|
||||||
|
if nbins > 0
|
||||||
|
hh = fit(Histogram, v[i]; closed=:left, nbins=nbins)
|
||||||
|
else
|
||||||
|
hh = fit(Histogram, v[i]; closed=:left)
|
||||||
end
|
end
|
||||||
return PackedDataAndCmds([hh.edges[1], [0;hh.weights]], "", [], ["w fsteps notit"])
|
x = collect(hh.edges[1])
|
||||||
|
x = (x[1:end-1] .+ x[2:end]) ./ 2
|
||||||
|
h = hh.weights
|
||||||
|
binsize = x[2] - x[1]
|
||||||
|
if pad
|
||||||
|
x = [x[1]-binsize, x..., x[end]+binsize]
|
||||||
|
h = [0, h..., 0]
|
||||||
|
end
|
||||||
|
return (loc=x, counts=h, binsize=binsize)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function contourlines(args...; cntrparam="level auto 10", lw=0, offset=0, minlen=10)
|
||||||
|
tmpfile = Base.Filesystem.tempname()
|
||||||
|
sid = Symbol("j", Base.Libc.getpid())
|
||||||
|
if !haskey(state.sessions, sid)
|
||||||
|
gp = gnuplot(sid, state.cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
Gnuplot.exec(sid, "set term unknown")
|
||||||
|
@gsp sid "set contour base" "unset surface" :-
|
||||||
|
@gsp :- sid "set cntrparam $cntrparam" :-
|
||||||
|
@gsp :- sid "set table '$tmpfile'" :-
|
||||||
|
@gsp :- sid args...
|
||||||
|
Gnuplot.exec(sid, "unset table")
|
||||||
|
Gnuplot.exec(sid, "reset")
|
||||||
|
|
||||||
|
dump = false
|
||||||
|
outl = Vector{String}()
|
||||||
|
outc = Vector{String}()
|
||||||
|
curx = Vector{Float64}()
|
||||||
|
cury = Vector{Float64}()
|
||||||
|
curl = ""
|
||||||
|
|
||||||
|
for l in readlines(tmpfile)
|
||||||
|
if length(strip(l)) == 0
|
||||||
|
dump = true
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
if !isnothing(findfirst("# Contour ", l))
|
||||||
|
curl = strip(split(l, ':')[2])
|
||||||
|
dump = true
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
(l[1] == '#') && continue
|
||||||
|
|
||||||
|
if dump && (length(curx) > 1) && (curl != "")
|
||||||
|
if offset != 0
|
||||||
|
curx = circshift(curx, offset)
|
||||||
|
cury = circshift(cury, offset)
|
||||||
|
end
|
||||||
|
if (lw > 0) && (length(curx) > (2*lw+2 + minlen))
|
||||||
|
n = lw + 1
|
||||||
|
x = curx[n]
|
||||||
|
y = cury[n]
|
||||||
|
rot = atan(cury[n+1]-cury[n-1], curx[n+1]-curx[n-1]) * 180 / pi
|
||||||
|
rot = round(mod(rot, 360))
|
||||||
|
push!(outl, "set label " * string(length(outl)+1) * " '$curl' at $x, $y centre front rotate by $rot")
|
||||||
|
curx = curx[2*lw+2:end]
|
||||||
|
cury = cury[2*lw+2:end]
|
||||||
|
end
|
||||||
|
append!(outc, string.(curx) .* " " .* string.(cury))
|
||||||
|
push!(outc, "")
|
||||||
|
empty!(curx)
|
||||||
|
empty!(cury)
|
||||||
|
dump = false
|
||||||
|
end
|
||||||
|
n = Meta.parse.(split(l))
|
||||||
|
@assert length(n) == 3
|
||||||
|
|
||||||
|
push!(curx, n[1])
|
||||||
|
push!(cury, n[2])
|
||||||
|
end
|
||||||
|
rm(tmpfile)
|
||||||
|
if lw > 0
|
||||||
|
return (outl, outc)
|
||||||
|
end
|
||||||
|
return outc
|
||||||
end
|
end
|
||||||
|
|
||||||
end #module
|
end #module
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user