From 58be54eca96ddac46b236a4843bb4a88967cf323 Mon Sep 17 00:00:00 2001 From: ivan-boikov Date: Mon, 10 Apr 2023 22:40:41 +0200 Subject: [PATCH 01/10] General annotation improvements, fixed 2D and added 3D annotations --- src/args.jl | 2 +- src/backends/gr.jl | 10 ++- src/backends/inspectdr.jl | 16 +++-- src/backends/pgfplotsx.jl | 19 +++--- src/backends/plotly.jl | 13 ++++ src/backends/pythonplot.jl | 14 +++++ src/components.jl | 122 ++++++++++++------------------------- 7 files changed, 96 insertions(+), 100 deletions(-) diff --git a/src/args.jl b/src/args.jl index 1f7de95dc..3e2511682 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1810,7 +1810,7 @@ function _update_subplot_periphery(sp::Subplot, anns::AVec) # extend annotations, and ensure we always have a (x,y,PlotText) tuple newanns = [] for ann in vcat(anns, sp[:annotations]) - append!(newanns, process_annotation(sp, ann...)) + append!(newanns, process_annotation(sp, ann)) end sp.attr[:annotations] = newanns diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 737a899b6..50e60005b 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -973,8 +973,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, vp_canvas::GRViewport) # add annotations for ann in sp[:annotations] - x, y, val = locate_annotation(sp, ann...) - x, y = gr_is3d(sp) ? gr_w3tondc(x, y, z) : GR.wctondc(x, y) + x, y, val = if is3d(sp) + x, y, z, val = locate_annotation(sp, ann...) + GR.setwindow(-1, 1, -1, 1) + gr_w3tondc(x, y, z)..., val + else + x, y, val = locate_annotation(sp, ann...) + GR.wctondc(x, y)..., val + end gr_set_font(val.font, sp) gr_text(x, y, val.str) end diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index c6ea6c7ac..0ffb81648 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -55,10 +55,10 @@ end # Hack: suggested point size does not seem adequate relative to plot size, for some reason. _inspectdr_mapptsize(v) = 1.5 * v -_inspectdr_add_annotations(plot, x, y, val) = nothing # What kind of annotation is this? +_inspectdr_add_annotations(plot, sp::Subplot, x, y, val) = nothing # What kind of annotation is this? #plot::InspectDR.Plot2D -function _inspectdr_add_annotations(plot, x, y, val::PlotText) +function _inspectdr_add_annotations(plot, sp::Subplot, x, y, val::PlotText) vmap = Dict{Symbol,Symbol}(:top => :t, :bottom => :b) # :vcenter hmap = Dict{Symbol,Symbol}(:left => :l, :right => :r) # :hcenter align = Symbol(get(vmap, val.font.valign, :c), get(hmap, val.font.halign, :c)) @@ -72,13 +72,19 @@ function _inspectdr_add_annotations(plot, x, y, val::PlotText) x = x, y = y, font = fnt, - angle = val.font.rotation, + angle = -val.font.rotation, # minus for consistency with other backends align = align, ) InspectDR.add(plot, ann) nothing end +# placement relative to figure +function _inspectdr_add_annotations(plot, sp::Subplot, pos::Union{Tuple, Symbol}, val::PlotText) + x, y, val = locate_annotation(sp, pos, val) + _inspectdr_add_annotations(plot, sp, x, y, val::PlotText) +end + # --------------------------------------------------------------------------- function _inspectdr_getaxisticks(ticks, gridlines, xfrm) @@ -319,7 +325,7 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) # this is all we need to add the series_annotations text anns = series[:series_annotations] for (xi, yi, str, fnt) in EachAnn(anns, x, y) - _inspectdr_add_annotations(plot, xi, yi, PlotText(str, fnt)) + _inspectdr_add_annotations(plot, sp, xi, yi, PlotText(str, fnt)) end end @@ -426,7 +432,7 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) # add the annotations for ann in sp[:annotations] - _inspectdr_add_annotations(plot, ann...) + _inspectdr_add_annotations(plot, sp, ann...) end end diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index 9cc872661..be13574f2 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -120,8 +120,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend}) y = dy + sp_h / 2 pgfx_add_annotation!( the_plot, - x, - y, + (x, y), PlotText(plt[:plot_title], plottitlefont(plt)), pgfx_thickness_scaling(plt); options = Options("anchor" => "center"), @@ -306,8 +305,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend}) for (xi, yi, str, fnt) in EachAnn(anns, series[:x], series[:y]) pgfx_add_annotation!( axis, - xi, - yi, + (xi, yi), PlotText(str, fnt), pgfx_thickness_scaling(series), ) @@ -315,9 +313,12 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend}) end # for series # add subplot annotations for ann in sp[:annotations] + # [1:end-1] -> coordinates, [end] is string + loc_val = locate_annotation(sp, ann...) pgfx_add_annotation!( axis, - locate_annotation(sp, ann...)..., + loc_val[1:end-1], + loc_val[end], pgfx_thickness_scaling(sp), ) end @@ -1005,8 +1006,7 @@ end function pgfx_add_annotation!( o, - x, - y, + pos, val, thickness_scaling = 1; cs = "axis cs:", @@ -1025,7 +1025,7 @@ function pgfx_add_annotation!( ), options, ) - push!(o, "\\node$(sprint(PGFPlotsX.print_tex, ann_opt)) at ($(cs)$x,$y) {$(val.str)};") + push!(o, "\\node$(sprint(PGFPlotsX.print_tex, ann_opt)) at ($(cs)$(join(pos, ','))) {$(val.str)};") end function pgfx_fillrange_series!(axis, series, series_func, i, fillrange, rng) @@ -1092,8 +1092,9 @@ function pgfx_sanitize_plot!(plt) if key === :annotations && subplot.attr[:annotations] !== nothing old_ann = subplot.attr[key] for i in eachindex(old_ann) + # [1:end-1] is a tuple of coordinates, [end] - text subplot.attr[key][i] = - (old_ann[i][1], old_ann[i][2], pgfx_sanitize_string(old_ann[i][3])) + (old_ann[i][1:end-1]..., pgfx_sanitize_string(old_ann[i][end])) end elseif value isa Union{AbstractString,AVec{<:AbstractString}} subplot.attr[key] = pgfx_sanitize_string.(value) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 1711f0bf9..e8baef598 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -34,6 +34,9 @@ plotly_font(font::Font, color = font.color) = KW( plotly_annotation_dict(x, y, val; xref = "paper", yref = "paper") = KW(:text => val, :xref => xref, :x => x, :yref => yref, :y => y, :showarrow => false) +plotly_annotation_dict(x, y, z, val; xref = "paper", yref = "paper", zref = "paper") = + KW(:text => val, :xref => xref, :x => x, :yref => yref, :y => y, :zref => zref, :z => z, :showarrow => false) + plotly_annotation_dict(x, y, ptxt::PlotText; xref = "paper", yref = "paper") = merge( plotly_annotation_dict(x, y, ptxt.str; xref = xref, yref = yref), KW( @@ -44,6 +47,16 @@ plotly_annotation_dict(x, y, ptxt::PlotText; xref = "paper", yref = "paper") = m ), ) +plotly_annotation_dict(x, y, z, ptxt::PlotText; xref = "paper", yref = "paper", zref = "paper") = merge( + plotly_annotation_dict(x, y, z, ptxt.str; xref = xref, yref = yref, zref = zref), + KW( + :font => plotly_font(ptxt.font), + :xanchor => ptxt.font.halign === :hcenter ? :center : ptxt.font.halign, + :yanchor => ptxt.font.valign === :vcenter ? :middle : ptxt.font.valign, + :rotation => -ptxt.font.rotation, + ), +) + plotly_scale(scale::Symbol) = scale === :log10 ? "log" : "-" function shrink_by(lo, sz, ratio) diff --git a/src/backends/pythonplot.jl b/src/backends/pythonplot.jl index 02fb4e207..f1fc59df1 100644 --- a/src/backends/pythonplot.jl +++ b/src/backends/pythonplot.jl @@ -1307,6 +1307,20 @@ _py_add_annotations(sp::Subplot{PythonPlotBackend}, x, y, val::PlotText) = sp.o. zorder = 999, ) +_py_add_annotations(sp::Subplot{PythonPlotBackend}, x, y, z, val::PlotText) = sp.o.text3D( + x, + y, + z, + val.str; + size = _py_thickness_scale(sp.plt, val.font.pointsize), + horizontalalignment = val.font.halign === :hcenter ? "center" : string(val.font.halign), + verticalalignment = val.font.valign === :vcenter ? "center" : string(val.font.valign), + color = _py_color(val.font.color), + rotation = val.font.rotation, + family = val.font.family, + zorder = 999, +) + # ----------------------------------------------------------------- _py_legend_pos(pos::Tuple{S,T}) where {S<:Real,T<:Real} = "lower left" diff --git a/src/components.jl b/src/components.jl index 0725ca3c9..6bd943561 100644 --- a/src/components.jl +++ b/src/components.jl @@ -603,36 +603,26 @@ _annotation(sp::Subplot, font, lab, pos...; alphabet = "abcdefghijklmnopqrstuvwx assign_annotation_coord!(axis, x) = discrete_value!(axis, x)[1] assign_annotation_coord!(axis, x::TimeType) = assign_annotation_coord!(axis, Dates.value(x)) +assign_annotation_coord!(axis, x::Symbol) = x +assign_annotation_coord!(axis, x::Tuple) = x + +_annotation_coords(pos::Symbol) = get(_positionAliases, pos, pos) +_annotation_coords(pos) = pos # Expand arrays of coordinates, positions and labels into individual annotations # and make sure labels are of type PlotText -function process_annotation(sp::Subplot, xs, ys, labs, font = _annotationfont(sp)) - anns = [] - labs = makevec(labs) - xlength = length(methods(length, (typeof(xs),))) == 0 ? 1 : length(xs) - ylength = length(methods(length, (typeof(ys),))) == 0 ? 1 : length(ys) - for i in 1:max(xlength, ylength, length(labs)) - x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i) - x = assign_annotation_coord!(sp[:xaxis], x) - y = assign_annotation_coord!(sp[:yaxis], y) - push!(anns, _annotation(sp, font, lab, x, y)) - end - anns -end - function process_annotation( sp::Subplot, - positions::Union{AVec{Symbol},Symbol,Tuple}, - labs, + ann, font = _annotationfont(sp), ) - anns = [] - positions, labs = makevec(positions), makevec(labs) - for i in 1:max(length(positions), length(labs)) - pos, lab = _cycle(positions, i), _cycle(labs, i) - push!(anns, _annotation(sp, font, lab, get(_positionAliases, pos, pos))) + map(zip(makevec.(ann)...)) do pos_lab + pos, lab = pos_lab[1:end-1], pos_lab[end] + pos = map([:x, :y, :z], pos) do letter, val + assign_annotation_coord!(sp[get_attr_symbol(letter, :axis)], val) + end + _annotation(sp, font, lab, _annotation_coords(pos)...) end - anns end function _relative_position(xmin, xmax, pos::Length{:pct}, scale::Symbol) @@ -648,75 +638,41 @@ function _relative_position(xmin, xmax, pos::Length{:pct}, scale::Symbol) end end +# annotation coordinates in pct const position_multiplier = Dict( - :N => (0.5pct, 0.9pct), - :NE => (0.9pct, 0.9pct), - :E => (0.9pct, 0.5pct), - :SE => (0.9pct, 0.1pct), - :S => (0.5pct, 0.1pct), - :SW => (0.1pct, 0.1pct), - :W => (0.1pct, 0.5pct), - :NW => (0.1pct, 0.9pct), - :topleft => (0.1pct, 0.9pct), - :topcenter => (0.5pct, 0.9pct), - :topright => (0.9pct, 0.9pct), - :bottomleft => (0.1pct, 0.1pct), - :bottomcenter => (0.5pct, 0.1pct), - :bottomright => (0.9pct, 0.1pct), + :N => (0.5, 0.9), + :NE => (0.9, 0.9), + :E => (0.9, 0.5), + :SE => (0.9, 0.1), + :S => (0.5, 0.1), + :SW => (0.1, 0.1), + :W => (0.1, 0.5), + :NW => (0.1, 0.9), + :topleft => (0.1, 0.9), + :topcenter => (0.5, 0.9), + :topright => (0.9, 0.9), + :bottomleft => (0.1, 0.1), + :bottomcenter => (0.5, 0.1), + :bottomright => (0.9, 0.1), ) # Give each annotation coordinates based on specified position -function locate_annotation(sp::Subplot, pos::Symbol, label::PlotText) - x, y = position_multiplier[pos] - ( +locate_annotation(sp::Subplot, rel::NTuple{N,<:Number}, label::PlotText) where {N} = ( + map(1:N, [:x, :y, :z]) do i, letter _relative_position( - axis_limits(sp, :x)..., - x, - sp[get_attr_symbol(:x, :axis)][:scale], - ), - _relative_position( - axis_limits(sp, :y)..., - y, - sp[get_attr_symbol(:y, :axis)][:scale], - ), - label, - ) -end -locate_annotation(sp::Subplot, x, y, label::PlotText) = (x, y, label) -locate_annotation(sp::Subplot, x, y, z, label::PlotText) = (x, y, z, label) - -locate_annotation(sp::Subplot, rel::NTuple{2,<:Number}, label::PlotText) = ( - _relative_position( - axis_limits(sp, :x)..., - rel[1] * Plots.pct, - sp[get_attr_symbol(:x, :axis)][:scale], - ), - _relative_position( - axis_limits(sp, :y)..., - rel[2] * Plots.pct, - sp[get_attr_symbol(:y, :axis)][:scale], - ), - label, -) -locate_annotation(sp::Subplot, rel::NTuple{3,<:Number}, label::PlotText) = ( - _relative_position( - axis_limits(sp, :x)..., - rel[1] * Plots.pct, - sp[get_attr_symbol(:x, :axis)][:scale], - ), - _relative_position( - axis_limits(sp, :y)..., - rel[2] * Plots.pct, - sp[get_attr_symbol(:y, :axis)][:scale], - ), - _relative_position( - axis_limits(sp, :z)..., - rel[3] * Plots.pct, - sp[get_attr_symbol(:z, :axis)][:scale], - ), + axis_limits(sp, letter)..., + rel[i] * Plots.pct, + sp[get_attr_symbol(letter, :axis)][:scale], + ) + end..., label, ) +locate_annotation(sp::Subplot, x, y, label::PlotText) = (x, y, label) +locate_annotation(sp::Subplot, x, y, z, label::PlotText) = (x, y, z, label) +locate_annotation(sp::Subplot, pos::Symbol, label::PlotText) = + locate_annotation(sp, position_multiplier[pos], label) + # ----------------------------------------------------------------------- function expand_extrema!(a::Axis, surf::Surface) From 34633258e7c670a0e55bd70c5d025a2bc38a7300 Mon Sep 17 00:00:00 2001 From: ivan-boikov Date: Tue, 11 Apr 2023 21:17:15 +0200 Subject: [PATCH 02/10] Generalize locate_annotation --- src/components.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components.jl b/src/components.jl index 6bd943561..b80b1da4e 100644 --- a/src/components.jl +++ b/src/components.jl @@ -657,8 +657,9 @@ const position_multiplier = Dict( ) # Give each annotation coordinates based on specified position -locate_annotation(sp::Subplot, rel::NTuple{N,<:Number}, label::PlotText) where {N} = ( - map(1:N, [:x, :y, :z]) do i, letter +# don't specialize on NTuple to allow mixed types +locate_annotation(sp::Subplot, rel::Tuple, label::PlotText) = ( + map(1:length(rel), [:x, :y, :z]) do i, letter _relative_position( axis_limits(sp, letter)..., rel[i] * Plots.pct, From 8475b79a2eaa5dc10bd56c55b43d03e9c90acb95 Mon Sep 17 00:00:00 2001 From: ivan-boikov Date: Tue, 11 Apr 2023 21:40:37 +0200 Subject: [PATCH 03/10] Thank you, reviewdog, very cool --- src/backends/inspectdr.jl | 7 ++++++- src/backends/pgfplotsx.jl | 9 ++++++--- src/backends/plotly.jl | 22 +++++++++++++++++++--- src/components.jl | 8 ++------ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 0ffb81648..7e2243531 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -80,7 +80,12 @@ function _inspectdr_add_annotations(plot, sp::Subplot, x, y, val::PlotText) end # placement relative to figure -function _inspectdr_add_annotations(plot, sp::Subplot, pos::Union{Tuple, Symbol}, val::PlotText) +function _inspectdr_add_annotations( + plot, + sp::Subplot, + pos::Union{Tuple, Symbol}, + val::PlotText +) x, y, val = locate_annotation(sp, pos, val) _inspectdr_add_annotations(plot, sp, x, y, val::PlotText) end diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index be13574f2..da78e50c3 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -317,7 +317,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend}) loc_val = locate_annotation(sp, ann...) pgfx_add_annotation!( axis, - loc_val[1:end-1], + loc_val[1:(end - 1)], loc_val[end], pgfx_thickness_scaling(sp), ) @@ -1025,7 +1025,10 @@ function pgfx_add_annotation!( ), options, ) - push!(o, "\\node$(sprint(PGFPlotsX.print_tex, ann_opt)) at ($(cs)$(join(pos, ','))) {$(val.str)};") + push!( + o, + "\\node$(sprint(PGFPlotsX.print_tex, ann_opt)) at ($(cs)$(join(pos, ','))) {$(val.str)};" + ) end function pgfx_fillrange_series!(axis, series, series_func, i, fillrange, rng) @@ -1094,7 +1097,7 @@ function pgfx_sanitize_plot!(plt) for i in eachindex(old_ann) # [1:end-1] is a tuple of coordinates, [end] - text subplot.attr[key][i] = - (old_ann[i][1:end-1]..., pgfx_sanitize_string(old_ann[i][end])) + (old_ann[i][1:(end - 1)]..., pgfx_sanitize_string(old_ann[i][end])) end elseif value isa Union{AbstractString,AVec{<:AbstractString}} subplot.attr[key] = pgfx_sanitize_string.(value) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index e8baef598..47c5d49a2 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -34,8 +34,16 @@ plotly_font(font::Font, color = font.color) = KW( plotly_annotation_dict(x, y, val; xref = "paper", yref = "paper") = KW(:text => val, :xref => xref, :x => x, :yref => yref, :y => y, :showarrow => false) -plotly_annotation_dict(x, y, z, val; xref = "paper", yref = "paper", zref = "paper") = - KW(:text => val, :xref => xref, :x => x, :yref => yref, :y => y, :zref => zref, :z => z, :showarrow => false) +plotly_annotation_dict(x, y, z, val; xref = "paper", yref = "paper", zref = "paper") = KW( + :text => val, + :xref => xref, + :x => x, + :yref => yref, + :y => y, + :zref => zref, + :z => z, + :showarrow => false +) plotly_annotation_dict(x, y, ptxt::PlotText; xref = "paper", yref = "paper") = merge( plotly_annotation_dict(x, y, ptxt.str; xref = xref, yref = yref), @@ -47,7 +55,15 @@ plotly_annotation_dict(x, y, ptxt::PlotText; xref = "paper", yref = "paper") = m ), ) -plotly_annotation_dict(x, y, z, ptxt::PlotText; xref = "paper", yref = "paper", zref = "paper") = merge( +plotly_annotation_dict( + x, + y, + z, + ptxt::PlotText; + xref = "paper", + yref = "paper", + zref = "paper" +) = merge( plotly_annotation_dict(x, y, z, ptxt.str; xref = xref, yref = yref, zref = zref), KW( :font => plotly_font(ptxt.font), diff --git a/src/components.jl b/src/components.jl index b80b1da4e..da532020b 100644 --- a/src/components.jl +++ b/src/components.jl @@ -611,13 +611,9 @@ _annotation_coords(pos) = pos # Expand arrays of coordinates, positions and labels into individual annotations # and make sure labels are of type PlotText -function process_annotation( - sp::Subplot, - ann, - font = _annotationfont(sp), -) +function process_annotation(sp::Subplot, ann, font = _annotationfont(sp)) map(zip(makevec.(ann)...)) do pos_lab - pos, lab = pos_lab[1:end-1], pos_lab[end] + pos, lab = pos_lab[1:(end - 1)], pos_lab[end] pos = map([:x, :y, :z], pos) do letter, val assign_annotation_coord!(sp[get_attr_symbol(letter, :axis)], val) end From bc0ecf156ac58fac01ce32263f784aa0dfcb1bf9 Mon Sep 17 00:00:00 2001 From: ivan-boikov Date: Tue, 11 Apr 2023 21:45:58 +0200 Subject: [PATCH 04/10] Formatting --- src/backends/inspectdr.jl | 10 +++++----- src/backends/pgfplotsx.jl | 2 +- src/backends/plotly.jl | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 7e2243531..11f029e5b 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -81,13 +81,13 @@ end # placement relative to figure function _inspectdr_add_annotations( - plot, - sp::Subplot, - pos::Union{Tuple, Symbol}, - val::PlotText + plot, + sp::Subplot, + pos::Union{Tuple, Symbol}, + val::PlotText ) x, y, val = locate_annotation(sp, pos, val) - _inspectdr_add_annotations(plot, sp, x, y, val::PlotText) + _inspectdr_add_annotations(plot, sp, x, y, val) end # --------------------------------------------------------------------------- diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index da78e50c3..1292c07f3 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -1027,7 +1027,7 @@ function pgfx_add_annotation!( ) push!( o, - "\\node$(sprint(PGFPlotsX.print_tex, ann_opt)) at ($(cs)$(join(pos, ','))) {$(val.str)};" + "\\node$(sprint(PGFPlotsX.print_tex, ann_opt)) at ($(cs)$(join(pos, ','))) {$(val.str)};", ) end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 47c5d49a2..1c251c639 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -42,7 +42,7 @@ plotly_annotation_dict(x, y, z, val; xref = "paper", yref = "paper", zref = "pap :y => y, :zref => zref, :z => z, - :showarrow => false + :showarrow => false, ) plotly_annotation_dict(x, y, ptxt::PlotText; xref = "paper", yref = "paper") = merge( @@ -62,7 +62,7 @@ plotly_annotation_dict( ptxt::PlotText; xref = "paper", yref = "paper", - zref = "paper" + zref = "paper", ) = merge( plotly_annotation_dict(x, y, z, ptxt.str; xref = xref, yref = yref, zref = zref), KW( From da286f1d753772b0d68b5aac153500808ce03029 Mon Sep 17 00:00:00 2001 From: ivan-boikov Date: Tue, 11 Apr 2023 21:51:04 +0200 Subject: [PATCH 05/10] Formatting, again --- src/backends/inspectdr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 11f029e5b..07a435fa0 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -83,8 +83,8 @@ end function _inspectdr_add_annotations( plot, sp::Subplot, - pos::Union{Tuple, Symbol}, - val::PlotText + pos::Union{Tuple,Symbol}, + val::PlotText, ) x, y, val = locate_annotation(sp, pos, val) _inspectdr_add_annotations(plot, sp, x, y, val) From 416e83be8ca541dc1fc9e1879bd6ee1192583fb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 14:23:52 +0200 Subject: [PATCH 06/10] Bump peter-evans/create-pull-request from 4 to 5 (#4720) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4 to 5. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v4...v5) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/format_pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/format_pr.yml b/.github/workflows/format_pr.yml index e9172ec1d..7c62327f2 100644 --- a/.github/workflows/format_pr.yml +++ b/.github/workflows/format_pr.yml @@ -19,7 +19,7 @@ jobs: - name: Create Pull Request if: ${{ failure() }} id: cpr - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v5 with: token: ${{ secrets.GITHUB_TOKEN }} commit-message: "Format .jl files [skip ci]" From c522611befe7c5af255f8f451d22930eca8a3ff1 Mon Sep 17 00:00:00 2001 From: Ivan Boikov <66747290+ivan-boikov@users.noreply.github.com> Date: Tue, 11 Apr 2023 12:36:46 +0000 Subject: [PATCH 07/10] Add bounds check in expand_extrema (#4718) * Add bounds check in expand_extrema * Stupid mistake --- src/axes.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/axes.jl b/src/axes.jl index c3c41db14..1ddfaffec 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -456,6 +456,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW) letter !== :z && plotattributes[:seriestype] === :straightline && any(series[:seriestype] !== :straightline for series in series_list(sp)) && + length(data) > 1 && data[1] != data[2] ) data = [NaN] From 1823a781485efcd77c60eb371dc9d526ec740932 Mon Sep 17 00:00:00 2001 From: ivan-boikov Date: Sat, 15 Apr 2023 14:25:56 +0200 Subject: [PATCH 08/10] Annotations in 3D, general annotation improvement --- src/backends/gr.jl | 6 +++--- src/components.jl | 48 +++++++++++++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 50e60005b..a2a1ed831 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -973,13 +973,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, vp_canvas::GRViewport) # add annotations for ann in sp[:annotations] - x, y, val = if is3d(sp) + x, y = if is3d(sp) x, y, z, val = locate_annotation(sp, ann...) GR.setwindow(-1, 1, -1, 1) - gr_w3tondc(x, y, z)..., val + gr_w3tondc(x, y, z) else x, y, val = locate_annotation(sp, ann...) - GR.wctondc(x, y)..., val + GR.wctondc(x, y) end gr_set_font(val.font, sp) gr_text(x, y, val.str) diff --git a/src/components.jl b/src/components.jl index da532020b..9894adc65 100644 --- a/src/components.jl +++ b/src/components.jl @@ -603,23 +603,46 @@ _annotation(sp::Subplot, font, lab, pos...; alphabet = "abcdefghijklmnopqrstuvwx assign_annotation_coord!(axis, x) = discrete_value!(axis, x)[1] assign_annotation_coord!(axis, x::TimeType) = assign_annotation_coord!(axis, Dates.value(x)) -assign_annotation_coord!(axis, x::Symbol) = x -assign_annotation_coord!(axis, x::Tuple) = x _annotation_coords(pos::Symbol) = get(_positionAliases, pos, pos) _annotation_coords(pos) = pos +function _process_annotation_2d(sp::Subplot, x, y, lab, font = _annotationfont(sp)) + x = assign_annotation_coord!(sp[:xaxis], x) + y = assign_annotation_coord!(sp[:yaxis], y) + _annotation(sp, font, lab, x, y) +end + +_process_annotation_2d( + sp::Subplot, + pos::Union{Tuple,Symbol}, + lab, + font = _annotationfont(sp), +) = _annotation(sp, font, lab, _annotation_coords(pos)) + +function _process_annotation_3d(sp::Subplot, x, y, z, lab, font = _annotationfont(sp)) + x = assign_annotation_coord!(sp[:xaxis], x) + y = assign_annotation_coord!(sp[:yaxis], y) + z = assign_annotation_coord!(sp[:zaxis], z) + _annotation(sp, font, lab, x, y, z) +end + +_process_annotation_3d( + sp::Subplot, + pos::Union{Tuple,Symbol}, + lab, + font = _annotationfont(sp), +) = _annotation(sp, font, lab, _annotation_coords(pos)) + +function _process_annotation(sp::Subplot, ann, annotation_processor::Function) + ann = makevec.(ann) + [annotation_processor(sp, _cycle.(ann, i)...) for i = 1:maximum(length.(ann))] +end + # Expand arrays of coordinates, positions and labels into individual annotations # and make sure labels are of type PlotText -function process_annotation(sp::Subplot, ann, font = _annotationfont(sp)) - map(zip(makevec.(ann)...)) do pos_lab - pos, lab = pos_lab[1:(end - 1)], pos_lab[end] - pos = map([:x, :y, :z], pos) do letter, val - assign_annotation_coord!(sp[get_attr_symbol(letter, :axis)], val) - end - _annotation(sp, font, lab, _annotation_coords(pos)...) - end -end +process_annotation(sp::Subplot, ann) = + _process_annotation(sp, ann, is3d(sp) ? _process_annotation_3d : _process_annotation_2d) function _relative_position(xmin, xmax, pos::Length{:pct}, scale::Symbol) # !TODO Add more scales in the future (asinh, sqrt) ? @@ -653,12 +676,11 @@ const position_multiplier = Dict( ) # Give each annotation coordinates based on specified position -# don't specialize on NTuple to allow mixed types locate_annotation(sp::Subplot, rel::Tuple, label::PlotText) = ( map(1:length(rel), [:x, :y, :z]) do i, letter _relative_position( axis_limits(sp, letter)..., - rel[i] * Plots.pct, + rel[i] * pct, sp[get_attr_symbol(letter, :axis)][:scale], ) end..., From 494fc39704455ffc98466c335a68838578cf0964 Mon Sep 17 00:00:00 2001 From: ivan-boikov Date: Sat, 15 Apr 2023 14:41:21 +0200 Subject: [PATCH 09/10] Formatting --- src/components.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components.jl b/src/components.jl index 9894adc65..cf4e66398 100644 --- a/src/components.jl +++ b/src/components.jl @@ -636,7 +636,7 @@ _process_annotation_3d( function _process_annotation(sp::Subplot, ann, annotation_processor::Function) ann = makevec.(ann) - [annotation_processor(sp, _cycle.(ann, i)...) for i = 1:maximum(length.(ann))] + [annotation_processor(sp, _cycle.(ann, i)...) for i in 1:maximum(length.(ann))] end # Expand arrays of coordinates, positions and labels into individual annotations From b8b78009f00a2e03166381d23707b943c053dbb0 Mon Sep 17 00:00:00 2001 From: Ivan Boikov <66747290+ivan-boikov@users.noreply.github.com> Date: Sun, 16 Apr 2023 20:34:03 +0000 Subject: [PATCH 10/10] Tuples for arrays of known length Co-authored-by: t-bltg --- src/components.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components.jl b/src/components.jl index cf4e66398..665b518f3 100644 --- a/src/components.jl +++ b/src/components.jl @@ -677,7 +677,7 @@ const position_multiplier = Dict( # Give each annotation coordinates based on specified position locate_annotation(sp::Subplot, rel::Tuple, label::PlotText) = ( - map(1:length(rel), [:x, :y, :z]) do i, letter + map(1:length(rel), (:x, :y, :z)) do i, letter _relative_position( axis_limits(sp, letter)..., rel[i] * pct,