Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor marker and line attributes #4505

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0985edb
add attributes via `@add_attributes`
BeastyBlacksmith Nov 1, 2022
d12b770
use kwdef in add_attributes
BeastyBlacksmith Nov 2, 2022
5dae3a3
complete marker attributes
BeastyBlacksmith Nov 2, 2022
69e839a
rename yfill -> fill
BeastyBlacksmith Nov 2, 2022
aadc7a4
add alias_dict to add_attributes
BeastyBlacksmith Nov 2, 2022
07aa435
add some tests
BeastyBlacksmith Nov 2, 2022
7925968
make aliases work
BeastyBlacksmith Nov 3, 2022
f931f7a
complete legend aliases
BeastyBlacksmith Nov 3, 2022
dd1f611
add aliases to plotattr
BeastyBlacksmith Nov 3, 2022
65fc04c
move aliases
BeastyBlacksmith Nov 3, 2022
2ddf825
remove fill and errorbar
BeastyBlacksmith Nov 10, 2022
0efda09
Revert "rename yfill -> fill"
BeastyBlacksmith Nov 10, 2022
62fee9b
fix docstrings
BeastyBlacksmith Nov 10, 2022
65fed0a
fix args test
BeastyBlacksmith Nov 10, 2022
f47764d
fix aliases, fill_z and filter compounds
BeastyBlacksmith Nov 10, 2022
719f4b0
cosmetics
BeastyBlacksmith Nov 11, 2022
38806ac
fix marker aliases in shapes
BeastyBlacksmith Nov 11, 2022
5e1bd5e
wrap attributes in Attributes
BeastyBlacksmith Jan 6, 2023
65116fb
move alias detection to DefaultDict
BeastyBlacksmith Jan 15, 2023
867afa0
add test
BeastyBlacksmith Mar 8, 2023
90bc39f
Merge remote-tracking branch 'origin/master' into bbs/marknline
BeastyBlacksmith Mar 9, 2023
bffd24d
make it precompile
BeastyBlacksmith Mar 9, 2023
6dfba96
harmonize funciton
BeastyBlacksmith Mar 9, 2023
f737e0f
fix tests
BeastyBlacksmith Mar 10, 2023
0150ad2
fix recipespipeline tests
BeastyBlacksmith Mar 10, 2023
75db4f3
Merge branch 'master' into bbs/marknline
BeastyBlacksmith Mar 10, 2023
c49da28
adlust benchmarks, revert macro test
BeastyBlacksmith Mar 10, 2023
33bae7f
don't dev Plots twice
BeastyBlacksmith Mar 10, 2023
7705f8a
format
BeastyBlacksmith Mar 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: benchmarks
on:
pull_request:

concurrency:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

Expand All @@ -14,11 +14,14 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@latest

- name: Ubuntu TESTCMD
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
- name: Install Plots dependencies
uses: julia-actions/julia-buildpkg@latest
shell: xvfb-run julia --project=@. --color=yes {0}
run: |
using Pkg
foreach(path -> Pkg.develop(; path), ("RecipesBase", "RecipesPipeline"))
- name: Install Benchmarking dependencies
run: julia -e 'using Pkg; pkg"add PkgBenchmark BenchmarkCI"'

Expand Down
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ Many updates, min julia 1.0
- allow calling `plot!(sp, ...)` to update a target Subplot
- PyPlot: zorder fix
- new DataFrames logic/recipe: more flexible/robust and allow Symbols for:
- `(:fillrange, :line_z, :marker_z, :markersize, :ribbon, :weights, :xerror, :yerror)`
- `(:fillrange, :line_z, :marker_z, :marker_size, :ribbon, :weights, :xerror, :yerror)`
- new `display_type` and `extra_kwargs` plot attributes
- surface fix

Expand Down
4 changes: 2 additions & 2 deletions RecipesBase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ function RecipesBase.apply_recipe(d::Dict{Symbol,Any},::T,n=1)
end
series_list = RecipesBase.RecipeData[]
func_return = begin
get!(d,:markershape,:auto)
d[:markercolor] = customcolor
get!(d,:marker_shape,:auto)
d[:marker_color] = customcolor
get!(d,:xrotation,45)
get!(d,:zrotation,90)
rand(10,n)
Expand Down
38 changes: 21 additions & 17 deletions RecipesBase/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ end
@testset "simple parametric type" begin
@test_throws MethodError RB.apply_recipe(KW(), T1())

RB.@recipe function plot(t::T1, n::N = 1; customcolor = :green) where {N<:Integer}
:markershape --> :auto, :require
:markercolor --> customcolor, :force
RB.@recipe function plot(
t::T1,
n::N = 1;
customcolor = :green,
) where {N<:Integer}
Comment on lines +64 to +68
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
RB.@recipe function plot(
t::T1,
n::N = 1;
customcolor = :green,
) where {N<:Integer}
RB.@recipe function plot(t::T1, n::N = 1; customcolor = :green) where {N<:Integer}

:marker_shape --> :auto, :require
:marker_color --> customcolor, :force
:xrotation --> 5
:zrotation --> 6, :quiet
rand(StableRNG(1), 10, n)
Expand All @@ -73,8 +77,8 @@ end
T1,
KW(
:customcolor => :red,
:markershape => :auto,
:markercolor => :red,
:marker_shape => :auto,
:marker_color => :red,
:xrotation => 5,
:zrotation => 6,
),
Expand All @@ -85,8 +89,8 @@ end
@test_throws MethodError RB.apply_recipe(KW(), T2())

RB.@recipe function plot(t::T2, n::N = 1; customcolor = :green) where {N<:Integer}
:markershape --> :auto, :require
:markercolor --> customcolor, :force
:marker_shape --> :auto, :require
:marker_color --> customcolor, :force
:xrotation --> 5
:zrotation --> 6, :quiet
rand(StableRNG(1), 10, n)
Expand All @@ -96,8 +100,8 @@ end
T2,
KW(
:customcolor => :red,
:markershape => :auto,
:markercolor => :red,
:marker_shape => :auto,
:marker_color => :red,
:xrotation => 5,
:zrotation => 6,
),
Expand All @@ -113,8 +117,8 @@ end
m::M = 0.0;
customcolor = :green,
) where {N<:Integer} where {M<:Float64}
:markershape --> :auto, :require
:markercolor --> customcolor, :force
:marker_shape --> :auto, :require
:marker_color --> customcolor, :force
:xrotation --> 5
:zrotation --> 6, :quiet
rand(StableRNG(1), 10, n)
Expand All @@ -124,8 +128,8 @@ end
T3,
KW(
:customcolor => :red,
:markershape => :auto,
:markercolor => :red,
:marker_shape => :auto,
:marker_color => :red,
:xrotation => 5,
:zrotation => 6,
),
Expand All @@ -136,8 +140,8 @@ end
@test_throws MethodError RB.apply_recipe(KW(), T4())

RB.@recipe function plot(t::T4, n = 1; customcolor = :green)
:markershape --> :auto, :require
:markercolor --> customcolor, :force
:marker_shape --> :auto, :require
:marker_color --> customcolor, :force
:xrotation --> 5
:zrotation --> 6, :quiet
plotattributes[:hello] = "hi"
Expand All @@ -148,8 +152,8 @@ end
T4,
KW(
:customcolor => :red,
:markershape => :auto,
:markercolor => :red,
:marker_shape => :auto,
:marker_color => :red,
:xrotation => 5,
:zrotation => 6,
:hello => "hi",
Expand Down
1 change: 1 addition & 0 deletions RecipesPipeline/src/RecipesPipeline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export warn_on_recipe_aliases,
get_axis_limits,
is_axis_attribute,
type_alias,
key_alias,
plot_setup!,
slice_series_attributes!,
process_sliced_series_attributes!
Expand Down
12 changes: 9 additions & 3 deletions RecipesPipeline/src/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,18 @@ get_axis_limits(plt, letter) = throw(ErrorException("Axis limits not defined."))
# ## Plot recipes

"""
type_alias(plt, st)
type_alias(typeof(plt), st)

Return the seriestype alias for `st`.
Return the canonical seriestype for `st`.
"""
type_alias(plt, st) = st
type_alias(plt::Type{<:Any}, st) = st

"""
key_alias(typeof(plt), key)

Return the canonical key for `key`.
"""
key_alias(plt::Type{<:Any}, key) = key
# ## Plot setup

"""
Expand Down
1 change: 0 additions & 1 deletion RecipesPipeline/src/plot_recipe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ function _process_plotrecipe(plt, kw, kw_list, still_to_process)
return
end
st = kw[:seriestype]
st = kw[:seriestype] = type_alias(plt, st)
datalist = RecipesBase.apply_recipe(kw, Val{st}, plt)
if !isnothing(datalist)
warn_on_recipe_aliases!(plt, datalist, :plot, st)
Expand Down
3 changes: 1 addition & 2 deletions RecipesPipeline/src/series_recipe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function _process_seriesrecipes!(plt, kw_list)
end
process_sliced_series_attributes!(plt, kw_list)
for kw in kw_list
series_attr = DefaultsDict(kw, series_defaults(plt))
series_attr = DefaultsDict(typeof(plt), kw, series_defaults(plt))
# now we have a fully specified series, with colors chosen. we must recursively
# handle series recipes, which dispatch on seriestype. If a backend does not
# natively support a seriestype, we check for a recipe that will convert that
Expand All @@ -33,7 +33,6 @@ end
function _process_seriesrecipe(plt, plotattributes)
# replace seriestype aliases
st = Symbol(plotattributes[:seriestype])
st = plotattributes[:seriestype] = type_alias(plt, st)

# shapes shouldn't have fillrange set
if plotattributes[:seriestype] == :shape
Expand Down
60 changes: 49 additions & 11 deletions RecipesPipeline/src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,54 @@ const AKW = AbstractDict{Symbol,Any}
# ## DefaultsDict
# --------------------------------

struct DefaultsDict <: AbstractDict{Symbol,Any}
struct DefaultsDict{P} <: AbstractDict{Symbol,Any}
plot_type::Type{P}
explicit::KW
defaults::KW
function DefaultsDict{P}(plot_type::Type{P}, explicit::AbstractDict, defaults::AbstractDict) where {P}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
function DefaultsDict{P}(plot_type::Type{P}, explicit::AbstractDict, defaults::AbstractDict) where {P}
function DefaultsDict{P}(
plot_type::Type{P},
explicit::AbstractDict,
defaults::AbstractDict,
) where {P}

e = KW(
key_alias(plot_type, k) => v === :seriestype ? type_alias(plot_type, v) : v
for (k, v) in explicit
)
new{P}(plot_type, e, defaults)
end
end

Base.merge(d1::DefaultsDict, d2::DefaultsDict) =
DefaultsDict(merge(d1.explicit, d2.explicit), merge(d1.defaults, d2.defaults))
Base.getindex(dd::DefaultsDict, k) =
DefaultsDict(pt, e, d) = DefaultsDict{pt}(pt, e, d)
function Base.merge(d1::DefaultsDict, d2::DefaultsDict)
@assert d1.plot_type === d2.plot_type
DefaultsDict(
d1.plot_type,
merge(d1.explicit, d2.explicit),
merge(d1.defaults, d2.defaults),
)
end
function Base.getindex(dd::DefaultsDict, k)
k = key_alias(dd.plot_type, k)
if haskey(dd.explicit, k)
dd.explicit[k]
else
dd.defaults[k]
end
Base.haskey(dd::DefaultsDict, k) = haskey(dd.explicit, k) || haskey(dd.defaults, k)
Base.get(dd::DefaultsDict, k, default) = haskey(dd, k) ? dd[k] : default
Base.get!(dd::DefaultsDict, k, default) =
end
function Base.haskey(dd::DefaultsDict, k)
k = key_alias(dd.plot_type, k)
haskey(dd.explicit, k) || haskey(dd.defaults, k)
end
function Base.get(dd::DefaultsDict, k, default)
k = key_alias(dd.plot_type, k)
haskey(dd, k) ? dd[k] : default
end
function Base.get!(dd::DefaultsDict, k, default)
k = key_alias(dd.plot_type, k)
if haskey(dd, k)
dd[k]
else
dd.defaults[k] = default
end
end
function Base.delete!(dd::DefaultsDict, k)
k = key_alias(dd.plot_type, k)
haskey(dd.explicit, k) && delete!(dd.explicit, k)
haskey(dd.defaults, k) && delete!(dd.defaults, k)
dd
Expand All @@ -46,12 +72,24 @@ function Base.iterate(dd::DefaultsDict, (key_list, i))
(k => dd[k], (key_list, i + 1))
end

Base.copy(dd::DefaultsDict) = DefaultsDict(copy(dd.explicit), dd.defaults)
Base.copy(dd::DefaultsDict) = DefaultsDict(dd.plot_type, copy(dd.explicit), dd.defaults)

RecipesBase.is_explicit(dd::DefaultsDict, k) = haskey(dd.explicit, k)
RecipesBase.is_default(dd::DefaultsDict, k) = !is_explicit(dd, k) && haskey(dd.defaults, k)
function RecipesBase.is_explicit(dd::DefaultsDict, k)
k = key_alias(dd.plot_type, k)
haskey(dd.explicit, k)
end
function RecipesBase.is_default(dd::DefaultsDict, k)
k = key_alias(dd.plot_type, k)
!is_explicit(dd, k) && haskey(dd.defaults, k)
end

Base.setindex!(dd::DefaultsDict, v, k) = dd.explicit[k] = v
function Base.setindex!(dd::DefaultsDict, v, k)
k = key_alias(dd.plot_type, k)
if k === :seriestype
v = type_alias(dd.plot_type, v)
end
dd.explicit[k] = v
end

# Reset to default value and return dict
function reset_kw!(dd::DefaultsDict, k)
Expand Down
7 changes: 5 additions & 2 deletions RecipesPipeline/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ using Test
import RecipesPipeline: _prepare_series_data
import RecipesBase

struct MyPlot end

@testset "DefaultsDict" begin
dd = DefaultsDict(Dict(:foo => 1, :bar => missing), Dict(:foo => nothing, :baz => 'x'))
dd = DefaultsDict(MyPlot, Dict(:foo => 1, :bar => missing), Dict(:foo => nothing, :baz => 'x'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
dd = DefaultsDict(MyPlot, Dict(:foo => 1, :bar => missing), Dict(:foo => nothing, :baz => 'x'))
dd = DefaultsDict(
MyPlot,
Dict(:foo => 1, :bar => missing),
Dict(:foo => nothing, :baz => 'x'),
)


@test all(explicitkeys(dd) .== [:bar, :foo])
@test all(defaultkeys(dd) .== [:baz, :foo])
Expand Down Expand Up @@ -44,7 +46,8 @@ end
@test !is_axis_attribute(plt, :foo)

@test process_userrecipe!(plt, [:foo], :bar) == [:foo, :bar]
@test type_alias(plt, :wireframe) ≡ :wireframe
@test type_alias(typeof(plt), :wireframe) ≡ :wireframe
@test key_alias(typeof(plt), :label) ≡ :label

@test plot_setup!(plt, plotattributes, kw_list) isa Nothing
@test slice_series_attributes!(plt, kw_list, kw) isa Nothing
Expand Down
2 changes: 1 addition & 1 deletion ext/UnitfulExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function fixmarkercolor!(attr)
ustripattribute!(attr, :clims, u)
u == NoUnits || append_unit_if_needed!(attr, :colorbar_title, u)
end
fixmarkersize!(attr) = ustripattribute!(attr, :markersize)
fixmarkersize!(attr) = ustripattribute!(attr, :marker_size)
fixlinecolor!(attr) = ustripattribute!(attr, :line_z)

# strip unit from attribute[key]
Expand Down
1 change: 0 additions & 1 deletion src/Plots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import RecipesPipeline:
timeformatter,
needs_3d_axes,
DefaultsDict,
explicitkeys,
scale_func,
is_surface,
Formatted,
Expand Down
Loading