From 7abab41f2bce04101dc3934841620b2b53a12edc Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 7 Apr 2020 09:52:32 +0200 Subject: [PATCH 1/4] add letter in surface type recipe --- src/series.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/series.jl b/src/series.jl index 7cd0a3f0..ff3ce8a7 100644 --- a/src/series.jl +++ b/src/series.jl @@ -219,13 +219,14 @@ end _apply_type_recipe( plotattributes, v::Surface{<:AMat{<:Union{AbstractFloat, Integer, AbstractString, Missing}}}, + letter, ) = v -function _apply_type_recipe(plotattributes, v::Surface) - ret = _apply_type_recipe(plotattributes, v.surf) +function _apply_type_recipe(plotattributes, v::Surface, letter) + ret = _apply_type_recipe(plotattributes, v.surf, letter) if typeof(ret) <: Formatted Formatted(Surface(ret.data), ret.formatter) else - Surface(ret.data) + Surface(ret) end end From 819e91aa37cdabece6bde6f7e332d36c32e8cde7 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 7 Apr 2020 16:06:12 +0200 Subject: [PATCH 2/4] add zerror recipe --- src/args.jl | 2 ++ src/backends.jl | 2 +- src/pipeline.jl | 2 +- src/recipes.jl | 79 ++++++++++++++++++++++++++++--------------------- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/args.jl b/src/args.jl index baa2a76c..1afd7483 100644 --- a/src/args.jl +++ b/src/args.jl @@ -267,6 +267,7 @@ const _series_defaults = KW( :bar_edges => false, :xerror => nothing, :yerror => nothing, + :zerror => nothing, :ribbon => nothing, :quiver => nothing, :arrow => nothing, # allows for adding arrows to line/path... call `arrow(args...)` @@ -593,6 +594,7 @@ add_aliases(:color_palette, :palette) add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse) add_aliases(:xerror, :xerr, :xerrorbar) add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar) +add_aliases(:zerror, :zerr, :zerrorbar) add_aliases(:quiver, :velocity, :quiver2d, :gradient, :vectorfield) add_aliases(:normalize, :norm, :normed, :normalized) add_aliases(:show_empty_bins, :showemptybins, :showempty, :show_empty) diff --git a/src/backends.jl b/src/backends.jl index abfa98b1..c8d6a2da 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -211,7 +211,7 @@ const _base_supported_args = [ :seriestype, :seriescolor, :seriesalpha, :smooth, - :xerror, :yerror, + :xerror, :yerror, :zerror, :subplot, :x, :y, :z, :show, :size, diff --git a/src/pipeline.jl b/src/pipeline.jl index ccf1bedd..e6256edc 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -159,7 +159,7 @@ end function _add_errorbar_kw(kw_list::Vector{KW}, kw::AKW) # handle error bars by creating new recipedata data... these will have # the same recipedata index as the recipedata they are copied from - for esym in (:xerror, :yerror) + for esym in (:xerror, :yerror, :zerror) if get(kw, esym, nothing) !== nothing # we make a copy of the KW and apply an errorbar recipe errkw = copy(kw) diff --git a/src/recipes.jl b/src/recipes.jl index 79b4176d..5969528d 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -1012,49 +1012,62 @@ function error_zipit(ebar) end end -function error_coords(xorig, yorig, ebar) - # init empty x/y, and zip errors if passed Tuple{Vector,Vector} - x, y = Array{float_extended_type(xorig)}(undef, 0), Array{Float64}(undef, 0) - # for each point, create a line segment from the bottom to the top of the errorbar - for i = 1:max(length(xorig), length(yorig)) - xi = _cycle(xorig, i) - yi = _cycle(yorig, i) - ebi = _cycle(ebar, i) - nanappend!(x, [xi, xi]) - e1, e2 = if istuple(ebi) - first(ebi), last(ebi) - elseif isscalar(ebi) - ebi, ebi - else - error("unexpected ebi type $(typeof(ebi)) for errorbar: $ebi") +error_tuple(x) = x, x +error_tuple(x::Tuple) = x + +function error_coords(errorbar, errordata, otherdata...) + ed = Vector{float_extended_type(errordata)}(undef, 0) + od = [Float64[] for _ in otherdata] + for (i, edi) in enumerate(errordata) + for (j, odj) in enumerate(otherdata) + odi = _cycle(odj, i) + nanappend!(od[j], [odi, odi]) end - nanappend!(y, [yi - e1, yi + e2]) + e1, e2 = error_tuple(_cycle(errorbar, i)) + nanappend!(ed, [edi - e1, edi + e2]) end - x, y + return (ed, od...) end # we will create a series of path segments, where each point represents one # side of an errorbar -@recipe function f(::Type{Val{:yerror}}, x, y, z) - error_style!(plotattributes) - markershape := :hline - plotattributes[:x], plotattributes[:y] = error_coords( - plotattributes[:x], - plotattributes[:y], - error_zipit(plotattributes[:yerror]), - ) - () -end -@deps yerror path @recipe function f(::Type{Val{:xerror}}, x, y, z) error_style!(plotattributes) markershape := :vline - plotattributes[:y], plotattributes[:x] = error_coords( - plotattributes[:y], - plotattributes[:x], - error_zipit(plotattributes[:xerror]), - ) + xerr = error_zipit(plotattributes[:xerror]) + if z === nothing + plotattributes[:x], plotattributes[:y] = error_coords(xerr, x, y) + else + plotattributes[:x], plotattributes[:y], plotattributes[:z] = + error_coords(xerr, x, y, z) + end + () +end +@deps xerror path + +@recipe function f(::Type{Val{:yerror}}, x, y, z) + error_style!(plotattributes) + markershape := :hline + yerr = error_zipit(plotattributes[:yerror]) + if z === nothing + plotattributes[:y], plotattributes[:x] = error_coords(yerr, y, x) + else + plotattributes[:y], plotattributes[:x], plotattributes[:z] = + error_coords(yerr, y, x, z) + end + () +end +@deps yerror path + +@recipe function f(::Type{Val{:zerror}}, x, y, z) + error_style!(plotattributes) + markershape := :hline + if z !== nothing + zerr = error_zipit(plotattributes[:zerror]) + plotattributes[:z], plotattributes[:x], plotattributes[:y] = + error_coords(zerr, z, x, y) + end () end @deps xerror path From c8e6b967e523e2ce7e36e89bd6147dd66b623e79 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 7 Apr 2020 16:27:02 +0200 Subject: [PATCH 3/4] add errorbar test example --- src/examples.jl | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/examples.jl b/src/examples.jl index 37c9e19b..8f4aa316 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -946,6 +946,43 @@ const _examples = PlotExample[ end, ], ), + PlotExample( + "Error bars and array type recipes", + "", + [ + quote + begin + struct Measurement <: Number + val::Float64 + err::Float64 + end + value(m::Measurement) = m.val + uncertainty(m::Measurement) = m.err + + @recipe function f(::Type{T}, m::T) where T <: AbstractArray{<:Measurement} + if !(get(plotattributes, :seriestype, :path) in [:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image]) + error_sym = Symbol(plotattributes[:letter], :error) + plotattributes[error_sym] = uncertainty.(m) + end + value.(m) + end + + x = Measurement.(10sort(rand(10)), rand(10)) + y = Measurement.(10sort(rand(10)), rand(10)) + z = Measurement.(10sort(rand(10)), rand(10)) + surf = Measurement.((1:10) .* (1:10)', rand(10,10)) + + plot( + scatter(x, [x y], msw = 0), + scatter(x, y, z, msw = 0), + heatmap(x, y, surf), + wireframe(x, y, surf), + legend = :topleft + ) + end + end, + ], + ), ] # Some constants for PlotDocs and PlotReferenceImages From aa61d681d9f090981a815bdb3673b249785593e6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 7 Apr 2020 16:27:33 +0200 Subject: [PATCH 4/4] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 30da8343..76f341eb 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Plots" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" author = ["Tom Breloff (@tbreloff)"] -version = "1.0.3" +version = "1.0.4" [deps] Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"