Added recipe for IsoContourLines; contourlines now accepts a Histogram2D object

This commit is contained in:
Giorgio Calderone 2020-04-18 13:24:12 +02:00
parent 3e053c440f
commit 79ebe5d8ee
2 changed files with 32 additions and 13 deletions

View File

@ -544,6 +544,7 @@ end
function gp_write_table(args...; kw...) function gp_write_table(args...; kw...)
@assert !Gnuplot.options.dry "Feature not available in *dry* mode."
tmpfile = Base.Filesystem.tempname() tmpfile = Base.Filesystem.tempname()
sid = Symbol("j", Base.Libc.getpid()) sid = Symbol("j", Base.Libc.getpid())
gp = getsession(sid) gp = getsession(sid)
@ -1906,7 +1907,7 @@ A path in 2D.
- `x::Vector{Float64}` - `x::Vector{Float64}`
- `y::Vector{Float64}` - `y::Vector{Float64}`
""" """
mutable struct Path2d struct Path2d
x::Vector{Float64} x::Vector{Float64}
y::Vector{Float64} y::Vector{Float64}
Path2d() = new(Vector{Float64}(), Vector{Float64}()) Path2d() = new(Vector{Float64}(), Vector{Float64}())
@ -1923,31 +1924,36 @@ Coordinates of all contour lines of a given level.
- `data::Vector{String}`: vector with string representation of all paths (ready to be sent to gnuplot); - `data::Vector{String}`: vector with string representation of all paths (ready to be sent to gnuplot);
- `z::Float64`: level of the contour lines. - `z::Float64`: level of the contour lines.
""" """
mutable struct IsoContourLines struct IsoContourLines
paths::Vector{Path2d} paths::Vector{Path2d}
data::Vector{String} data::Dataset
z::Float64 z::Float64
function IsoContourLines(paths::Vector{Path2d}, z) function IsoContourLines(paths::Vector{Path2d}, z)
@assert length(z) == 1 @assert length(z) == 1
# Prepare Dataset object
data = Vector{String}() data = Vector{String}()
for i in 1:length(paths) for i in 1:length(paths)
append!(data, arrays2datablock(paths[i].x, paths[i].y, z .* fill(1., length(paths[i].x)))) append!(data, arrays2datablock(paths[i].x, paths[i].y, z .* fill(1., length(paths[i].x))))
push!(data, "") push!(data, "")
push!(data, "") push!(data, "")
end end
return new(paths, data, z) return new(paths, DatasetText(data), z)
end end
end end
""" """
contourlines(x::Vector{Float64}, y::Vector{Float64}, h::Matrix{Float64}; cntrparam="level auto 10") contourlines(x::Vector{Float64}, y::Vector{Float64}, z::Matrix{Float64}, cntrparam="level auto 10")
contourlines(h::Histogram2D, cntrparam="level auto 10")
Compute paths of contour lines for 2D data, and return a vector of [`IsoContourLines`](@ref) object. Compute paths of contour lines for 2D data, and return a vector of [`IsoContourLines`](@ref) object.
!!! note
This feature is not available in *dry* mode and will raise an error if used.
# Arguments: # Arguments:
- `x`, `y`: Coordinates; - `x`, `y`: Coordinates;
- `h`: the levels on which iso contour lines are to be calculated - `z`: the levels on which iso contour lines are to be calculated
- `cntrparam`: settings to compute contour line paths (see gnuplot documentation for `cntrparam`). - `cntrparam`: settings to compute contour line paths (see gnuplot documentation for `cntrparam`).
# Example # Example
@ -1955,16 +1961,23 @@ Compute paths of contour lines for 2D data, and return a vector of [`IsoContourL
x = randn(5000); x = randn(5000);
y = randn(5000); y = randn(5000);
h = hist(x, y, nbins1=20, nbins2=20); h = hist(x, y, nbins1=20, nbins2=20);
clines = contourlines(h.bins1, h.bins2, h.counts, cntrparam="levels discrete 15, 30, 45"); clines = contourlines(h, "levels discrete 15, 30, 45");
# Use implicit recipe
@gp clines
# ...or use IsoContourLines fields:
@gp "set size ratio -1" @gp "set size ratio -1"
for i in 1:length(clines) for i in 1:length(clines)
@gp :- clines[i].data "w l t '\$(clines[i].z)' dt \$i" @gp :- clines[i].data "w l t '\$(clines[i].z)' lw \$i dt \$i"
end end
``` ```
""" """
function contourlines(args...; cntrparam="level auto 10") contourlines(h::Histogram2D, args...) = contourlines(h.bins1, h.bins2, h.counts, args...)
function contourlines(x::Vector{Float64}, y::Vector{Float64}, z::Matrix{Float64},
cntrparam="level auto 10")
lines = gp_write_table("set contour base", "unset surface", lines = gp_write_table("set contour base", "unset surface",
"set cntrparam $cntrparam", args..., is3d=true) "set cntrparam $cntrparam", x, y, z, is3d=true)
level = NaN level = NaN
path = Path2d() path = Path2d()
@ -2003,9 +2016,9 @@ function contourlines(args...; cntrparam="level auto 10")
# Join paths with the same level # Join paths with the same level
out = Vector{IsoContourLines}() out = Vector{IsoContourLines}()
for z in unique(levels) for zlevel in unique(levels)
i = findall(levels .== z) i = findall(levels .== zlevel)
push!(out, IsoContourLines(paths[i], z)) push!(out, IsoContourLines(paths[i], zlevel))
end end
return out return out
end end

View File

@ -21,6 +21,12 @@ recipe(h::Histogram2D) =
plot="w image notit") plot="w image notit")
# --------------------------------------------------------------------
# Contour lines
recipe(c::IsoContourLines) = PlotElement(data=c.data, plot="w l t '$(c.z)'")
recipe(v::Vector{IsoContourLines}) = recipe.(v)
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Images # Images
""" """