diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index e46a09f92..3341cc75c 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -3,7 +3,7 @@ name: benchmarks on: pull_request: -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true @@ -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"' diff --git a/NEWS.md b/NEWS.md index fcb363c42..8e8d79d40 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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 diff --git a/RecipesBase/README.md b/RecipesBase/README.md index c4674cb66..1256725a8 100644 --- a/RecipesBase/README.md +++ b/RecipesBase/README.md @@ -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) diff --git a/RecipesBase/test/runtests.jl b/RecipesBase/test/runtests.jl index 2dae4af67..9f4945ad3 100644 --- a/RecipesBase/test/runtests.jl +++ b/RecipesBase/test/runtests.jl @@ -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} + :marker_shape --> :auto, :require + :marker_color --> customcolor, :force :xrotation --> 5 :zrotation --> 6, :quiet rand(StableRNG(1), 10, n) @@ -73,8 +77,8 @@ end T1, KW( :customcolor => :red, - :markershape => :auto, - :markercolor => :red, + :marker_shape => :auto, + :marker_color => :red, :xrotation => 5, :zrotation => 6, ), @@ -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) @@ -96,8 +100,8 @@ end T2, KW( :customcolor => :red, - :markershape => :auto, - :markercolor => :red, + :marker_shape => :auto, + :marker_color => :red, :xrotation => 5, :zrotation => 6, ), @@ -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) @@ -124,8 +128,8 @@ end T3, KW( :customcolor => :red, - :markershape => :auto, - :markercolor => :red, + :marker_shape => :auto, + :marker_color => :red, :xrotation => 5, :zrotation => 6, ), @@ -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" @@ -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", diff --git a/RecipesPipeline/src/RecipesPipeline.jl b/RecipesPipeline/src/RecipesPipeline.jl index fe76d59ac..c9cd63cc8 100644 --- a/RecipesPipeline/src/RecipesPipeline.jl +++ b/RecipesPipeline/src/RecipesPipeline.jl @@ -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! diff --git a/RecipesPipeline/src/api.jl b/RecipesPipeline/src/api.jl index ff0e1897b..e14a25515 100644 --- a/RecipesPipeline/src/api.jl +++ b/RecipesPipeline/src/api.jl @@ -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 """ diff --git a/RecipesPipeline/src/plot_recipe.jl b/RecipesPipeline/src/plot_recipe.jl index 8cddfbd70..e5372677c 100644 --- a/RecipesPipeline/src/plot_recipe.jl +++ b/RecipesPipeline/src/plot_recipe.jl @@ -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) diff --git a/RecipesPipeline/src/series_recipe.jl b/RecipesPipeline/src/series_recipe.jl index bb4275803..d5a38ece3 100644 --- a/RecipesPipeline/src/series_recipe.jl +++ b/RecipesPipeline/src/series_recipe.jl @@ -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 @@ -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 diff --git a/RecipesPipeline/src/utils.jl b/RecipesPipeline/src/utils.jl index 682b91d01..89a5e4ff4 100644 --- a/RecipesPipeline/src/utils.jl +++ b/RecipesPipeline/src/utils.jl @@ -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} + 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 @@ -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) diff --git a/RecipesPipeline/test/runtests.jl b/RecipesPipeline/test/runtests.jl index fcdff96f7..88111c3bd 100644 --- a/RecipesPipeline/test/runtests.jl +++ b/RecipesPipeline/test/runtests.jl @@ -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')) @test all(explicitkeys(dd) .== [:bar, :foo]) @test all(defaultkeys(dd) .== [:baz, :foo]) @@ -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 diff --git a/ext/UnitfulExt.jl b/ext/UnitfulExt.jl index a709bd878..29b62fe2d 100644 --- a/ext/UnitfulExt.jl +++ b/ext/UnitfulExt.jl @@ -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] diff --git a/src/Plots.jl b/src/Plots.jl index aadd9a26d..719ecf78c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -26,7 +26,6 @@ import RecipesPipeline: timeformatter, needs_3d_axes, DefaultsDict, - explicitkeys, scale_func, is_surface, Formatted, diff --git a/src/arg_desc.jl b/src/arg_desc.jl index bb9172286..406f6bf8c 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -5,60 +5,60 @@ const TicksType = Union{AVec{Real},Tuple{AVec{Real},AVec{AStr}},Symbol,Bool,Noth # NOTE: when updating `arg_desc`, don't forget to modify `PlotDocs.make_attr_df` accordingly. const _arg_desc = KW( # series args - :label => (AStr, "The label for a series, which appears in a legend. If empty, no legend entry is added."), - :seriescolor => (ColorType, "The base color for this series. `:auto` (the default) will select a color from the subplot's `color_palette`, based on the order it was added to the subplot. Also describes the colormap for surfaces."), - :seriesalpha => (Real, "The alpha/opacity override for the series. `nothing` (the default) means it will take the alpha value of the color."), - :seriestype => (Symbol, "This is the identifier of the type of visualization for this series. Choose from $(_allTypes) or any series recipes which are defined."), - :linestyle => (Symbol, "Style of the line (for path and bar stroke). Choose from $(_allStyles)"), - :linewidth => (Real, "Width of the line (in pixels)."), - :linecolor => (ColorType, "Color of the line (for path and bar stroke). `:match` will take the value from `:seriescolor`, (though histogram/bar types use `:black` as a default)."), - :linealpha => (Real, "The alpha/opacity override for the line. `nothing` (the default) means it will take the alpha value of linecolor."), - :fillrange => (Union{Real,AVec}, "Fills area between fillrange and `y` for line-types, sets the base for `bar`, `sticks` types, and similar for other types."), - :fillcolor => (ColorType, "Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`."), - :fillalpha => (Real, "The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor."), - :markershape => (Union{Symbol,Shape,AVec}, "Choose from $(_allMarkers)."), - :fillstyle => (Symbol, "Style of the fill area. `nothing` (the default) means solid fill. Choose from :/, :\\, :|, :-, :+, :x."), - :markercolor => (ColorType, "Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`."), - :markeralpha => (Real, "The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor."), - :markersize => (Union{Real,AVec}, "Size (radius pixels) of the markers."), - :markerstrokestyle => (Symbol, "Style of the marker stroke (border). Choose from $(_allStyles)."), - :markerstrokewidth => (Real, "Width of the marker stroke (border) in pixels."), - :markerstrokecolor => (ColorType, "Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`."), - :markerstrokealpha => (Real, "The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor."), - :bins => (Union{Integer,NTuple{2,Integer},AVec,Symbol}, """ - Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). - For fine-grained control pass a Vector of break values, e.g. `range(minimum(x), stop = maximum(x), length = 25)`."""), - :smooth => (Bool, "Add a regression line ?"), - :group => (AVec, "Data is split into a separate series, one for each unique value in `group`."), - :x => (Any, "Input data (first dimension)."), - :y => (Any, "Input data (second dimension)."), - :z => (Any, "Input data (third dimension). May be wrapped by a `Surface` for surface and heatmap types."), - :marker_z => (Union{AVec,Function}, "z-values for each series data point, which correspond to the color to be used from a markercolor gradient (`f(x,y,z) -> z_value` or `f(x,y) -> z_value`)."), - :line_z => (Union{AVec,Function}, "z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment)."), - :fill_z => (AMat, "Matrix of the same size as z matrix, which specifies the color of the 3D surface."), - :levels => (Union{AVec,Integer}, "Singleton for number of contours or iterable for contour values. Determines contour levels for a contour type."), - :permute => (NTuple{2,Symbol}, "Permutes data and axis properties of the axes given in the tuple, e.g. (:x, :y)."), - :orientation => (Symbol, "(deprecated) Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default)."), - :bar_position => (Symbol, "Choose from `:overlay` (default), `:stack`. (warning: may only be partially implemented)."), - :bar_width => (Real, " Width of bars in data coordinates. When `nothing`, chooses based on `x` (or `y` when `orientation = :h`)."), - :bar_edges => (Bool, "Align bars to edges (true), or centers (the default) ?"), - :xerror => (Union{AVec,NTuple{2,AVec}}, "`x` (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)."), - :yerror => (Union{AVec,NTuple{2,AVec}}, "`y` (vertical) error relative to y-value. If 2-tuple of vectors, the first vector corresponds to the bottom error (and the second to the top)."), - :ribbon => (Union{Real,AVec}, "Creates a fillrange around the data points."), - :quiver => (Union{AVec,NTuple{2,AVec}}, "The directional vectors U,V which specify velocity/gradient vectors for a quiver plot."), - :arrow => (Union{Bool,Arrow}, "Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar."), - :normalize => (Union{Bool,Symbol}, "Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete PDF, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes)."), - :weights => (AVec, "Used in histogram types for weighted counts."), - :show_empty_bins => (Bool, "Whether empty bins in a 2D histogram are colored as 0 (true), or transparent (the default)."), - :contours => (Bool, "Add contours to the side-grids of 3D plots? Used in surface/wireframe."), - :contour_labels => (Bool, "Show labels at the contour lines ?"), - :match_dimensions => (Bool, "For heatmap types: should the first dimension of a matrix (rows) correspond to the first dimension of the plot (`x`-axis) ? Defaults to `false`, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for `z`, the function should still map `(x,y) -> z`."), - :subplot => (Union{Integer,Subplot}, "The subplot that this series belongs to."), - :series_annotations => (Union{AVec,AStr,PlotText}, "These are annotations which are mapped to data points/positions."), - :primary => (Bool, "Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as two separate series, maybe with different data (see `sticks` recipe for an example). The secondary series will get the same color, etc as the primary."), - :hover => (AVec{AStr}, "Text to display when hovering over each data point."), - :colorbar_entry => (Bool, "Include this series in the color bar? Set to `false` to exclude."), - :z_order => (Union{Symbol,Integer}, ":front (default), :back or index of position where 1 is furthest in the background."), + :label => (AStr, "The label for a series, which appears in a legend. If empty, no legend entry is added."), + :seriescolor => (ColorType, "The base color for this series. `:auto` (the default) will select a color from the subplot's `color_palette`, based on the order it was added to the subplot. Also describes the colormap for surfaces."), + :seriesalpha => (Real, "The alpha/opacity override for the series. `nothing` (the default) means it will take the alpha value of the color."), + :seriestype => (Symbol, "This is the identifier of the type of visualization for this series. Choose from $(_allTypes) or any series recipes which are defined."), + :line_style => (Symbol, "Style of the line (for path and bar stroke). Choose from $(_allStyles)"), + :line_width => (Real, "Width of the line (in pixels)."), + :line_color => (ColorType, "Color of the line (for path and bar stroke). `:match` will take the value from `:seriescolor`, (though histogram/bar types use `:black` as a default)."), + :line_alpha => (Real, "The alpha/opacity override for the line. `nothing` (the default) means it will take the alpha value of linecolor."), + :fillrange => (Union{Real,AVec}, "Fills area between fillrange and `y` for line-types, sets the base for `bar`, `sticks` types, and similar for other types."), + :fillcolor => (ColorType, "Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`."), + :fillalpha => (Real, "The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor."), + :marker_shape => (Union{Symbol,Shape,AVec}, "Choose from $(_allMarkers)."), + :fillstyle => (Symbol, "Style of the fill area. `nothing` (the default) means solid fill. Choose from :/, :\\, :|, :-, :+, :x."), + :marker_color => (ColorType, "Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`."), + :marker_alpha => (Real, "The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor."), + :marker_size => (Union{Real,AVec}, "Size (radius pixels) of the markers."), + :marker_stroke_style => (Symbol, "Style of the marker stroke (border). Choose from $(_allStyles)."), + :marker_stroke_width => (Real, "Width of the marker stroke (border) in pixels."), + :marker_stroke_color => (ColorType, "Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`."), + :marker_stroke_alpha => (Real, "The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor."), + :bins => (Union{Integer,NTuple{2,Integer},AVec,Symbol}, """ + Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). + For fine-grained control pass a Vector of break values, e.g. `range(minimum(x), stop = maximum(x), length = 25)`."""), + :smooth => (Bool, "Add a regression line ?"), + :group => (AVec, "Data is split into a separate series, one for each unique value in `group`."), + :x => (Any, "Input data (first dimension)."), + :y => (Any, "Input data (second dimension)."), + :z => (Any, "Input data (third dimension). May be wrapped by a `Surface` for surface and heatmap types."), + :marker_z => (Union{AVec,Function}, "z-values for each series data point, which correspond to the color to be used from a markercolor gradient (`f(x,y,z) -> z_value` or `f(x,y) -> z_value`)."), + :line_z => (Union{AVec,Function}, "z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment)."), + :fill_z => (AMat, "Matrix of the same size as z matrix, which specifies the color of the 3D surface."), + :levels => (Union{AVec,Integer}, "Singleton for number of contours or iterable for contour values. Determines contour levels for a contour type."), + :permute => (NTuple{2,Symbol}, "Permutes data and axis properties of the axes given in the tuple, e.g. (:x, :y)."), + :orientation => (Symbol, "(deprecated) Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default)."), + :bar_position => (Symbol, "Choose from `:overlay` (default), `:stack`. (warning: may only be partially implemented)."), + :bar_width => (Real, " Width of bars in data coordinates. When `nothing`, chooses based on `x` (or `y` when `orientation = :h`)."), + :bar_edges => (Bool, "Align bars to edges (true), or centers (the default) ?"), + :xerror => (Union{AVec,NTuple{2,AVec}}, "`x` (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)."), + :yerror => (Union{AVec,NTuple{2,AVec}}, "`y` (vertical) error relative to y-value. If 2-tuple of vectors, the first vector corresponds to the bottom error (and the second to the top)."), + :ribbon => (Union{Real,AVec}, "Creates a fillrange around the data points."), + :quiver => (Union{AVec,NTuple{2,AVec}}, "The directional vectors U,V which specify velocity/gradient vectors for a quiver plot."), + :arrow => (Union{Bool,Arrow}, "Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar."), + :normalize => (Union{Bool,Symbol}, "Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete PDF, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes)."), + :weights => (AVec, "Used in histogram types for weighted counts."), + :show_empty_bins => (Bool, "Whether empty bins in a 2D histogram are colored as 0 (true), or transparent (the default)."), + :contours => (Bool, "Add contours to the side-grids of 3D plots? Used in surface/wireframe."), + :contour_labels => (Bool, "Show labels at the contour lines ?"), + :match_dimensions => (Bool, "For heatmap types: should the first dimension of a matrix (rows) correspond to the first dimension of the plot (`x`-axis) ? Defaults to `false`, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for `z`, the function should still map `(x,y) -> z`."), + :subplot => (Union{Integer,Subplot}, "The subplot that this series belongs to."), + :series_annotations => (Union{AVec,AStr,PlotText}, "These are annotations which are mapped to data points/positions."), + :primary => (Bool, "Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as two separate series, maybe with different data (see `sticks` recipe for an example). The secondary series will get the same color, etc as the primary."), + :hover => (AVec{AStr}, "Text to display when hovering over each data point."), + :colorbar_entry => (Bool, "Include this series in the color bar? Set to `false` to exclude."), + :z_order => (Union{Symbol,Integer}, ":front (default), :back or index of position where 1 is furthest in the background."), # plot args :plot_title => (AStr, "Whole plot title (not to be confused with the title for individual subplots)."), @@ -195,7 +195,7 @@ const _arg_desc = KW( :showaxis => (Union{Bool,Symbol,AStr}, "Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`."), :widen => (Union{Bool,Real,Symbol}, """ Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. - If set to `true`, scale the axis limits by the default factor of $(default_widen_factor). + If set to `true`, scale the axis limits by the default factor of $(default_widen_factor). A different factor may be specified by setting `widen` to a number. Defaults to `:auto`, which widens by the default factor unless limits were manually set. See also the `scale_limits!` function for scaling axis limits in an existing plot."""), diff --git a/src/args.jl b/src/args.jl index 7628c4934..65af59b05 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1,11 +1,30 @@ makeplural(s::Symbol) = last(string(s)) == 's' ? s : Symbol(string(s, "s")) -make_non_underscore(s::Symbol) = Symbol(replace(string(s), "_" => "")) +function make_non_underscore(s::Symbol) + str = string(s) + n = count("_", str) + Tuple(Symbol(replace(str, "_" => "", count = c)) for c in 1:n) +end const _keyAliases = Dict{Symbol,Symbol}() +const _generalAliases = ( + "background" => "bg", + "foreground" => "fg", + "pointsize" => "size", + "yfill" => "fill", + "alpha" => "a", + "alpha" => "opacity", + "alpha" => "α", +) function add_aliases(sym::Symbol, aliases::Symbol...) for alias in aliases - (haskey(_keyAliases, alias) || alias === sym) && return + str = string(alias) + for ga in _generalAliases + contains(str, ga.first) || continue + str2 = replace(str, ga) + _keyAliases[Symbol(str2)] = sym + end + (haskey(_keyAliases, alias) || alias === sym) && continue _keyAliases[alias] = sym end nothing @@ -22,7 +41,9 @@ end function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol}) for (k, v) in aliases if '_' in string(k) - aliases[make_non_underscore(k)] = v + for nu in make_non_underscore(k) + aliases[nu] = v + end end end end @@ -330,22 +351,10 @@ const _series_defaults = KW( :seriescolor => :auto, :seriesalpha => nothing, :seriestype => :path, - :linestyle => :solid, - :linewidth => :auto, - :linecolor => :auto, - :linealpha => nothing, :fillrange => nothing, # ribbons, areas, etc :fillcolor => :match, :fillalpha => nothing, :fillstyle => nothing, - :markershape => :none, - :markercolor => :match, - :markeralpha => nothing, - :markersize => 4, - :markerstrokestyle => :solid, - :markerstrokewidth => 1, - :markerstrokecolor => :match, - :markerstrokealpha => nothing, :bins => :auto, # number of bins for hists :smooth => false, # regression line? :group => nothing, # groupby vector @@ -571,43 +580,6 @@ aliases(aliasMap::Dict{Symbol,Symbol}, val) = filter(x -> x.second == val, aliasMap) |> keys |> collect |> sort # ----------------------------------------------------------------------------- -# legend -add_aliases(:legend_position, :legend, :leg, :key, :legends) -add_aliases( - :legend_background_color, - :bg_legend, - :bglegend, - :bgcolor_legend, - :bg_color_legend, - :background_legend, - :background_colour_legend, - :bgcolour_legend, - :bg_colour_legend, - :background_color_legend, -) -add_aliases( - :legend_foreground_color, - :fg_legend, - :fglegend, - :fgcolor_legend, - :fg_color_legend, - :foreground_legend, - :foreground_colour_legend, - :fgcolour_legend, - :fg_colour_legend, - :foreground_color_legend, -) -add_aliases(:legend_font_pointsize, :legendfontsize) -add_aliases( - :legend_title, - :key_title, - :keytitle, - :label_title, - :labeltitle, - :leg_title, - :legtitle, -) -add_aliases(:legend_title_font_pointsize, :legendtitlefontsize) # margin add_aliases(:left_margin, :leftmargin) @@ -617,10 +589,6 @@ add_aliases(:right_margin, :rightmargin) # colors add_aliases(:seriescolor, :c, :color, :colour, :colormap, :cmap) -add_aliases(:linecolor, :lc, :lcolor, :lcolour, :linecolour) -add_aliases(:markercolor, :mc, :mcolor, :mcolour, :markercolour) -add_aliases(:markerstrokecolor, :msc, :mscolor, :mscolour, :markerstrokecolour) -add_aliases(:markerstrokewidth, :msw, :mswidth) add_aliases(:fillcolor, :fc, :fcolor, :fcolour, :fillcolour) add_aliases( @@ -775,9 +743,6 @@ add_aliases( # alphas add_aliases(:seriesalpha, :alpha, :α, :opacity) -add_aliases(:linealpha, :la, :lalpha, :lα, :lineopacity, :lopacity) -add_aliases(:markeralpha, :ma, :malpha, :mα, :markeropacity, :mopacity) -add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :msopacity) add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity) # axes attributes @@ -858,11 +823,7 @@ add_axes_aliases( add_aliases(:seriestype, :st, :t, :typ, :linetype, :lt) add_aliases(:label, :lab) add_aliases(:line, :l) -add_aliases(:linewidth, :w, :width, :lw) -add_aliases(:linestyle, :style, :s, :ls) add_aliases(:marker, :m, :mark) -add_aliases(:markershape, :shape) -add_aliases(:markersize, :ms, :msize) add_aliases(:marker_z, :markerz, :zcolor, :mz) add_aliases(:line_z, :linez, :zline, :lz) add_aliases(:fill, :f, :area) @@ -1067,16 +1028,16 @@ function processLineArg(plotattributes::AKW, arg) # linestyle elseif allStyles(arg) - plotattributes[:linestyle] = arg + plotattributes[:line_style] = arg elseif typeof(arg) <: Stroke - arg.width === nothing || (plotattributes[:linewidth] = arg.width) + arg.width === nothing || (plotattributes[:line_width] = arg.width) arg.color === nothing || ( - plotattributes[:linecolor] = + plotattributes[:line_color] = arg.color === :auto ? :auto : plot_color(arg.color) ) - arg.alpha === nothing || (plotattributes[:linealpha] = arg.alpha) - arg.style === nothing || (plotattributes[:linestyle] = arg.style) + arg.alpha === nothing || (plotattributes[:line_alpha] = arg.alpha) + arg.style === nothing || (plotattributes[:line_style] = arg.style) elseif typeof(arg) <: Brush arg.size === nothing || (plotattributes[:fillrange] = arg.size) @@ -1092,58 +1053,58 @@ function processLineArg(plotattributes::AKW, arg) # linealpha elseif allAlphas(arg) - plotattributes[:linealpha] = arg + plotattributes[:line_alpha] = arg # linewidth elseif allReals(arg) - plotattributes[:linewidth] = arg + plotattributes[:line_width] = arg # color - elseif !handleColors!(plotattributes, arg, :linecolor) + elseif !handleColors!(plotattributes, arg, :line_color) @warn "Skipped line arg $arg." end end function processMarkerArg(plotattributes::AKW, arg) # markershape - if allShapes(arg) && !haskey(plotattributes, :markershape) - plotattributes[:markershape] = arg + if allShapes(arg) && !haskey(plotattributes, :marker_shape) + plotattributes[:marker_shape] = arg # stroke style elseif allStyles(arg) - plotattributes[:markerstrokestyle] = arg + plotattributes[:marker_stroke_style] = arg elseif typeof(arg) <: Stroke - arg.width === nothing || (plotattributes[:markerstrokewidth] = arg.width) + arg.width === nothing || (plotattributes[:marker_stroke_width] = arg.width) arg.color === nothing || ( - plotattributes[:markerstrokecolor] = + plotattributes[:marker_stroke_color] = arg.color === :auto ? :auto : plot_color(arg.color) ) - arg.alpha === nothing || (plotattributes[:markerstrokealpha] = arg.alpha) - arg.style === nothing || (plotattributes[:markerstrokestyle] = arg.style) + arg.alpha === nothing || (plotattributes[:marker_stroke_alpha] = arg.alpha) + arg.style === nothing || (plotattributes[:marker_stroke_style] = arg.style) elseif typeof(arg) <: Brush - arg.size === nothing || (plotattributes[:markersize] = arg.size) + arg.size === nothing || (plotattributes[:marker_size] = arg.size) arg.color === nothing || ( - plotattributes[:markercolor] = + plotattributes[:marker_color] = arg.color === :auto ? :auto : plot_color(arg.color) ) - arg.alpha === nothing || (plotattributes[:markeralpha] = arg.alpha) + arg.alpha === nothing || (plotattributes[:marker_alpha] = arg.alpha) # linealpha elseif allAlphas(arg) - plotattributes[:markeralpha] = arg + plotattributes[:marker_alpha] = arg # bool elseif typeof(arg) <: Bool - plotattributes[:markershape] = arg ? :circle : :none + plotattributes[:marker_shape] = arg ? :circle : :none # markersize elseif allReals(arg) - plotattributes[:markersize] = arg + plotattributes[:marker_size] = arg # markercolor - elseif !handleColors!(plotattributes, arg, :markercolor) + elseif !handleColors!(plotattributes, arg, :marker_color) @warn "Skipped marker arg $arg." end end @@ -1315,9 +1276,9 @@ _replace_markershape(shape) = shape function _add_markershape(plotattributes::AKW) # add the markershape if it needs to be added... hack to allow "m=10" to add a shape, # and still allow overriding in _apply_recipe - ms = pop!(plotattributes, :markershape_to_add, :none) - if !haskey(plotattributes, :markershape) && ms !== :none - plotattributes[:markershape] = ms + ms = pop!(plotattributes, :marker_shape_to_add, :none) + if !haskey(plotattributes, :marker_shape) && ms !== :none + plotattributes[:marker_shape] = ms end end @@ -1444,15 +1405,15 @@ function preprocess_attributes!(plotattributes::AKW) anymarker = true end RecipesPipeline.reset_kw!(plotattributes, :marker) - if haskey(plotattributes, :markershape) - plotattributes[:markershape] = _replace_markershape(plotattributes[:markershape]) - if plotattributes[:markershape] === :none && + if haskey(plotattributes, :marker_shape) + plotattributes[:marker_shape] = _replace_markershape(plotattributes[:marker_shape]) + if plotattributes[:marker_shape] === :none && get(plotattributes, :seriestype, :path) in (:scatter, :scatterbins, :scatterhist, :scatter3d) #the default should be :auto, not :none, so that :none can be set explicitly and would be respected - plotattributes[:markershape] = :circle + plotattributes[:marker_shape] = :circle end elseif anymarker - plotattributes[:markershape_to_add] = :circle # add it after _apply_recipe + plotattributes[:marker_shape_to_add] = :circle # add it after _apply_recipe end # handle fill @@ -1530,7 +1491,7 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes) Set{Symbol}() end extra_kwargs = Dict{Symbol,Any}() - for k in explicitkeys(plotattributes) + for k in RecipesPipeline.explicitkeys(plotattributes) (is_attr_supported(pkg, k) && k ∉ keys(_deprecated_attributes)) && continue k in _suppress_warnings && continue if ismissing(default(k)) @@ -1565,10 +1526,10 @@ function warn_on_unsupported(pkg::AbstractBackend, plotattributes) get(plotattributes, :warn_on_unsupported, should_warn_on_unsupported(pkg)) || return is_seriestype_supported(pkg, plotattributes[:seriestype]) || @warn "seriestype $(plotattributes[:seriestype]) is unsupported with $pkg. Choose from: $(supported_seriestypes(pkg))" - is_style_supported(pkg, plotattributes[:linestyle]) || - @warn "linestyle $(plotattributes[:linestyle]) is unsupported with $pkg. Choose from: $(supported_styles(pkg))" - is_marker_supported(pkg, plotattributes[:markershape]) || - @warn "markershape $(plotattributes[:markershape]) is unsupported with $pkg. Choose from: $(supported_markers(pkg))" + is_style_supported(pkg, plotattributes[:line_style]) || + @warn "linestyle $(plotattributes[:line_style]) is unsupported with $pkg. Choose from: $(supported_styles(pkg))" + is_marker_supported(pkg, plotattributes[:marker_shape]) || + @warn "markershape $(plotattributes[:marker_shape]) is unsupported with $pkg. Choose from: $(supported_markers(pkg))" end function warn_on_unsupported_scales(pkg::AbstractBackend, plotattributes::AKW) @@ -1996,8 +1957,8 @@ const DEFAULT_LINEWIDTH = Ref(1) # get a good default linewidth... 0 for surface and heatmaps _replace_linewidth(plotattributes::AKW) = - if plotattributes[:linewidth] === :auto - plotattributes[:linewidth] = + if plotattributes[:line_width] === :auto + plotattributes[:line_width] = (get(plotattributes, :seriestype, :path) ∉ (:surface, :heatmap, :image)) * DEFAULT_LINEWIDTH[] end @@ -2031,27 +1992,27 @@ function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot) aliasesAndAutopick( plotattributes, - :linestyle, + :line_style, _styleAliases, supported_styles(pkg), plotIndex, ) aliasesAndAutopick( plotattributes, - :markershape, + :marker_shape, _markerAliases, supported_markers(pkg), plotIndex, ) # update alphas - for asym in (:linealpha, :markeralpha, :fillalpha) + for asym in (:line_alpha, :marker_alpha, :fillalpha) if plotattributes[asym] === nothing plotattributes[asym] = plotattributes[:seriesalpha] end end - if plotattributes[:markerstrokealpha] === nothing - plotattributes[:markerstrokealpha] = plotattributes[:markeralpha] + if plotattributes[:marker_stroke_alpha] === nothing + plotattributes[:marker_stroke_alpha] = plotattributes[:marker_alpha] end # update series color @@ -2059,11 +2020,11 @@ function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot) stype = plotattributes[:seriestype] plotattributes[:seriescolor] = scolor = get_series_color(scolor, sp, plotIndex, stype) - # update other colors (`linecolor`, `markercolor`, `fillcolor`) <- for grep - for s in (:line, :marker, :fill) + # update other colors + for s in (:line_, :marker_, :fill) csym, asym = Symbol(s, :color), Symbol(s, :alpha) plotattributes[csym] = if plotattributes[csym] === :auto - plot_color(if has_black_border_for_default(stype) && s === :line + plot_color(if has_black_border_for_default(stype) && s === :line_ sp[:foreground_color_subplot] else scolor @@ -2076,20 +2037,21 @@ function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot) end # update markerstrokecolor - plotattributes[:markerstrokecolor] = if plotattributes[:markerstrokecolor] === :match - plot_color(sp[:foreground_color_subplot]) - elseif plotattributes[:markerstrokecolor] === :auto - get_series_color(plotattributes[:markercolor], sp, plotIndex, stype) - else - get_series_color(plotattributes[:markerstrokecolor], sp, plotIndex, stype) - end + plotattributes[:marker_stroke_color] = + if plotattributes[:marker_stroke_color] === :match + plot_color(sp[:foreground_color_subplot]) + elseif plotattributes[:marker_stroke_color] === :auto + get_series_color(plotattributes[:marker_color], sp, plotIndex, stype) + else + get_series_color(plotattributes[:marker_stroke_color], sp, plotIndex, stype) + end # if marker_z, fill_z or line_z are set, ensure we have a gradient if plotattributes[:marker_z] !== nothing - ensure_gradient!(plotattributes, :markercolor, :markeralpha) + ensure_gradient!(plotattributes, :marker_color, :marker_alpha) end if plotattributes[:line_z] !== nothing - ensure_gradient!(plotattributes, :linecolor, :linealpha) + ensure_gradient!(plotattributes, :line_color, :line_alpha) end if plotattributes[:fill_z] !== nothing ensure_gradient!(plotattributes, :fillcolor, :fillalpha) @@ -2097,9 +2059,9 @@ function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot) # scatter plots don't have a line, but must have a shape if plotattributes[:seriestype] in (:scatter, :scatterbins, :scatterhist, :scatter3d) - plotattributes[:linewidth] = 0 - if plotattributes[:markershape] === :none - plotattributes[:markershape] = :circle + plotattributes[:line_width] = 0 + if plotattributes[:marker_shape] === :none + plotattributes[:marker_shape] = :circle end end @@ -2122,15 +2084,28 @@ _series_index(plotattributes, sp) = #-------------------------------------------------- ## inspired by Base.@kwdef """ - add_attributes(level, expr, match_table) + add_attributes(level, expr, args...) Takes a `struct` definition and recurses into its fields to create keywords by chaining the field names with the structs' name with underscore. Also creates pluralized and non-underscore aliases for these keywords. - `level` indicates which group of `plot`, `subplot`, `series`, etc. the keywords belong to. - `expr` is the struct definition with default values like `Base.@kwdef` -- `match_table` is an expression of the form `:match = (symbols)`, with symbols whose default value should be `:match` +- `args` can be any of the following + - `match_table`: an expression of the form `:match = (symbols)`, with symbols whose default value should be `:match` + - `alias_dict`: an expression of the form `:aliases = Dict(symbol1 => symbol2)`, which will create aliases such that `symbol1` is an alias for `symbol2` """ -macro add_attributes(level, expr, match_table) +macro add_attributes(level, expr, args...) + match_table = :(:match = ()) + alias_dict = KW() + for arg in args + if arg.head == :(=) && arg.args[1] == QuoteNode(:match) + match_table = arg + elseif arg.head == :(=) && arg.args[1] == QuoteNode(:aliases) + alias_dict = eval(arg.args[2]) + else + @warn "Unsupported extra argument $arg will be ignored" + end + end expr = macroexpand(__module__, expr) # to expand @static expr isa Expr && expr.head === :struct || error("Invalid usage of @add_attributes") if (T = expr.args[2]) isa Expr && T.head === :<: @@ -2138,17 +2113,19 @@ macro add_attributes(level, expr, match_table) end key_dict = KW() + original = copy(expr) _splitdef!(expr.args[3], key_dict) insert_block = Expr(:block) for (key, value) in key_dict - # e.g. _series_defualts[key] = value + # e.g. _series_defaults[key] = value exp_key = Symbol(lowercase(string(T)), "_", key) pl_key = makeplural(exp_key) if QuoteNode(exp_key) in match_table.args[2].args value = QuoteNode(:match) end field = QuoteNode(Symbol("_", level, "_defaults")) + aliases = get(alias_dict, exp_key, nothing) push!( insert_block.args, Expr( @@ -2159,16 +2136,29 @@ macro add_attributes(level, expr, match_table) :(Plots.add_aliases($(QuoteNode(exp_key)), $(QuoteNode(pl_key)))), :(Plots.add_aliases( $(QuoteNode(exp_key)), - $(QuoteNode(Plots.make_non_underscore(exp_key))), + $(QuoteNode(Plots.make_non_underscore(exp_key)))..., )), :(Plots.add_aliases( $(QuoteNode(exp_key)), - $(QuoteNode(Plots.make_non_underscore(pl_key))), + $(QuoteNode(Plots.make_non_underscore(pl_key)))..., )), ) + if aliases !== nothing + pl_aliases = Plots.makeplural.(aliases) + push!( + insert_block.args, + :(Plots.add_aliases( + $(QuoteNode(exp_key)), + $(aliases)..., + $(pl_aliases)..., + $(Iterators.flatten(Plots.make_non_underscore.(aliases)))..., + $(Iterators.flatten(Plots.make_non_underscore.(pl_aliases)))..., + )), + ) + end end quote - $expr + Base.@kwdef $original $insert_block end |> esc end @@ -2200,7 +2190,14 @@ function _splitdef!(blk, key_dict) continue end defexpr = ei.args[2] # defexpr - key_dict[var] = defexpr + # filter e.g. marker::Marker = Marker(...) + if !( + defexpr isa Expr && + defexpr.head == :call && + defexpr.args[1] == ei.args[1].args[2] + ) + key_dict[var] = defexpr + end blk.args[i] = lhs elseif ei.head === :(::) && ei.args[1] isa Symbol # var::Typ diff --git a/src/axes.jl b/src/axes.jl index c3c41db14..0c70b2889 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -16,7 +16,7 @@ function Axis(sp::Subplot, letter::Symbol, args...; kw...) :show => true, # show or hide the axis? (useful for linked subplots) ) - attr = DefaultsDict(explicit, _axis_defaults_byletter[letter]) + attr = DefaultsDict(Plots.Plot, explicit, _axis_defaults_byletter[letter]) # update the defaults attr!(Axis([sp], attr), args...; kw...) @@ -555,7 +555,7 @@ end scale_lims!([plt], [letter], factor) Scale the limits of the axis specified by `letter` (one of `:x`, `:y`, `:z`) by the -given `factor` around the limits' middle point. +given `factor` around the limits' middle point. If `letter` is omitted, all axes are affected. """ function scale_lims!(sp::Subplot, letter, factor) diff --git a/src/backends.jl b/src/backends.jl index f9df14fc2..3629a0e93 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -425,17 +425,17 @@ const _gr_attr = merge_with_base_supported([ :label, :seriescolor, :seriesalpha, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - :markerstrokewidth, - :markerstrokecolor, - :markerstrokealpha, + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + :marker_stroke_width, + :marker_stroke_color, + :marker_stroke_alpha, :fillrange, :fillcolor, :fillalpha, @@ -572,18 +572,18 @@ const _plotly_attr = merge_with_base_supported([ :label, :seriescolor, :seriesalpha, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - :markerstrokewidth, - :markerstrokecolor, - :markerstrokealpha, - :markerstrokestyle, + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + :marker_stroke_width, + :marker_stroke_color, + :marker_stroke_alpha, + :marker_stroke_style, :fillrange, :fillcolor, :fillalpha, @@ -699,18 +699,18 @@ const _pgfplots_attr = merge_with_base_supported([ :label, :seriescolor, :seriesalpha, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - :markerstrokewidth, - :markerstrokecolor, - :markerstrokealpha, - :markerstrokestyle, + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + :marker_stroke_width, + :marker_stroke_color, + :marker_stroke_alpha, + :marker_stroke_style, :fillrange, :fillcolor, :fillalpha, @@ -835,17 +835,17 @@ const _pyplot_attr = merge_with_base_supported([ :foreground_color_guide, :foreground_color_text, :label, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - :markerstrokewidth, - :markerstrokecolor, - :markerstrokealpha, + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + :marker_stroke_width, + :marker_stroke_color, + :marker_stroke_alpha, :fillrange, :fillcolor, :fillalpha, @@ -991,15 +991,15 @@ const _gaston_attr = merge_with_base_supported([ :label, :seriescolor, :seriesalpha, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - # :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :markerstrokestyle, + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + # :marker_stroke_width, :marker_stroke_color, :marker_stroke_alpha, :marker_stroke_style, # :fillrange, :fillcolor, :fillalpha, # :bins, # :bar_width, :bar_edges, @@ -1091,10 +1091,10 @@ const _unicodeplots_attr = merge_with_base_supported([ :layout, :legend, :lims, - :linealpha, - :linecolor, - :linestyle, - :markershape, + :line_alpha, + :line_color, + :line_style, + :marker_shape, :quiver, :arrow, :seriesalpha, @@ -1171,17 +1171,17 @@ const _hdf5_attr = merge_with_base_supported([ :foreground_color_guide, :foreground_color_text, :label, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - :markerstrokewidth, - :markerstrokecolor, - :markerstrokealpha, + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + :marker_stroke_width, + :marker_stroke_color, + :marker_stroke_alpha, :fillrange, :fillcolor, :fillalpha, @@ -1276,18 +1276,18 @@ const _inspectdr_attr = merge_with_base_supported([ :label, :seriescolor, :seriesalpha, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - :markerstrokewidth, - :markerstrokecolor, - :markerstrokealpha, - :markerstrokestyle, #Causes warning not to have it... what is this? + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + :marker_stroke_width, + :marker_stroke_color, + :marker_stroke_alpha, + :marker_stroke_style, #Causes warning not to have it... what is this? :fillcolor, :fillalpha, #:fillrange, # :bins, :bar_width, :bar_edges, :bar_position, @@ -1397,17 +1397,17 @@ const _pgfplotsx_attr = merge_with_base_supported([ :label, :seriescolor, :seriesalpha, - :linecolor, - :linestyle, - :linewidth, - :linealpha, - :markershape, - :markercolor, - :markersize, - :markeralpha, - :markerstrokewidth, - :markerstrokecolor, - :markerstrokealpha, + :line_color, + :line_style, + :line_width, + :line_alpha, + :marker_shape, + :marker_color, + :marker_size, + :marker_alpha, + :marker_stroke_width, + :marker_stroke_color, + :marker_stroke_alpha, :fillrange, :fillcolor, :fillalpha, diff --git a/src/backends/deprecated/pgfplots.jl b/src/backends/deprecated/pgfplots.jl index 3e992dba8..2731b72fb 100644 --- a/src/backends/deprecated/pgfplots.jl +++ b/src/backends/deprecated/pgfplots.jl @@ -106,10 +106,10 @@ function pgf_linestyle(linewidth::Real, color, α = 1, linestyle = "solid") end function pgf_linestyle(plotattributes, i = 1) - lw = pgf_thickness_scaling(plotattributes) * get_linewidth(plotattributes, i) - lc = get_linecolor(plotattributes, i) - la = get_linealpha(plotattributes, i) - ls = get_linestyle(plotattributes, i) + lw = pgf_thickness_scaling(plotattributes) * get_line_width(plotattributes, i) + lc = get_line_color(plotattributes, i) + la = get_line_alpha(plotattributes, i) + ls = get_line_style(plotattributes, i) return pgf_linestyle(lw, lc, la, ls) end @@ -119,26 +119,29 @@ function pgf_font(fontsize, thickness_scaling = 1, font = "\\selectfont") end function pgf_marker(plotattributes, i = 1) - shape = _cycle(plotattributes[:markershape], i) + shape = _cycle(plotattributes[:marker_shape], i) cstr, a = pgf_color( - plot_color(get_markercolor(plotattributes, i), get_markeralpha(plotattributes, i)), + plot_color( + get_marker_color(plotattributes, i), + get_marker_alpha(plotattributes, i), + ), ) cstr_stroke, a_stroke = pgf_color( plot_color( - get_markerstrokecolor(plotattributes, i), - get_markerstrokealpha(plotattributes, i), + get_marker_stroke_color(plotattributes, i), + get_marker_stroke_alpha(plotattributes, i), ), ) return string( "mark = $(get(_pgfplots_markers, shape, "*")),\n", - "mark size = $(pgf_thickness_scaling(plotattributes) * 0.5 * _cycle(plotattributes[:markersize], i)),\n", + "mark size = $(pgf_thickness_scaling(plotattributes) * 0.5 * _cycle(plotattributes[:marker_size], i)),\n", plotattributes[:seriestype] === :scatter ? "only marks,\n" : "", "mark options = { color = $cstr_stroke, draw opacity = $a_stroke, fill = $cstr, fill opacity = $a, - line width = $(pgf_thickness_scaling(plotattributes) * _cycle(plotattributes[:markerstrokewidth], i)), + line width = $(pgf_thickness_scaling(plotattributes) * _cycle(plotattributes[:marker_stroke_width], i)), rotate = $(shape === :dtriangle ? 180 : 0), - $(get(_pgfplots_linestyles, _cycle(plotattributes[:markerstrokestyle], i), "solid")) + $(get(_pgfplots_linestyles, _cycle(plotattributes[:marker_stroke_style], i), "solid")) }", ) end @@ -641,7 +644,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) # As it is likely that all series within the same axis use the same # colormap this should not cause any problem. for series in series_list(sp) - for col in (:markercolor, :fillcolor, :linecolor) + for col in (:marker_color, :fillcolor, :line_color) if typeof(series.plotattributes[col]) == ColorGradient push!( style, diff --git a/src/backends/deprecated/pyplot.jl b/src/backends/deprecated/pyplot.jl index 4fc33cfd2..e925599d8 100644 --- a/src/backends/deprecated/pyplot.jl +++ b/src/backends/deprecated/pyplot.jl @@ -221,9 +221,9 @@ function fix_xy_lengths!(plt::Plot{PyPlotBackend}, series::Series) end py_linecolormap(series::Series) = - py_colormap(cgrad(series[:linecolor], alpha = get_linealpha(series))) + py_colormap(cgrad(series[:line_color], alpha = get_line_alpha(series))) py_markercolormap(series::Series) = - py_colormap(cgrad(series[:markercolor], alpha = get_markeralpha(series))) + py_colormap(cgrad(series[:marker_color], alpha = get_marker_alpha(series))) py_fillcolormap(series::Series) = py_colormap(cgrad(series[:fillcolor], alpha = get_fillalpha(series))) @@ -419,7 +419,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # line plot if st in (:path, :path3d, :steppre, :stepmid, :steppost, :straightline) - if maximum(series[:linewidth]) > 0 + if maximum(series[:line_width]) > 0 for (k, segment) in enumerate(series_segments(series, st; check = true)) i, rng = segment.attr_index, segment.range handle = ax."plot"( @@ -427,11 +427,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = k == 1 ? series[:label] : "", zorder = series[:series_plotindex], color = py_color( - single_color(get_linecolor(series, clims, i)), - get_linealpha(series, i), + single_color(get_line_color(series, clims, i)), + get_line_alpha(series, i), ), - linewidth = py_thickness_scale(plt, get_linewidth(series, i)), - linestyle = py_linestyle(st, get_linestyle(series, i)), + linewidth = py_thickness_scale(plt, get_line_width(series, i)), + linestyle = py_linestyle(st, get_line_style(series, i)), solid_capstyle = "butt", dash_capstyle = "butt", drawstyle = py_stepstyle(st), @@ -448,10 +448,10 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :arrowstyle => "simple,head_length=$(a.headlength),head_width=$(a.headwidth)", :shrinkA => 0, :shrinkB => 0, - :edgecolor => py_color(get_linecolor(series)), - :facecolor => py_color(get_linecolor(series)), - :linewidth => py_thickness_scale(plt, get_linewidth(series)), - :linestyle => py_linestyle(st, get_linestyle(series)), + :edgecolor => py_color(get_line_color(series)), + :facecolor => py_color(get_line_color(series)), + :line_width => py_thickness_scale(plt, get_line_width(series)), + :line_style => py_linestyle(st, get_line_style(series)), ) add_arrows(x, y) do xyprev, xy ax."annotate"( @@ -471,7 +471,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end # add markers? - if series[:markershape] !== :none && + if series[:marker_shape] !== :none && st in (:path, :scatter, :path3d, :scatter3d, :steppre, :stepmid, :steppost, :bar) for segment in series_segments(series, :scatter) i, rng = segment.attr_index, segment.range @@ -488,17 +488,17 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) args...; label = series[:label], zorder = series[:series_plotindex] + 0.5, - marker = py_marker(_cycle(series[:markershape], i)), - s = py_thickness_scale(plt, _cycle(series[:markersize], i)) .^ 2, + marker = py_marker(_cycle(series[:marker_shape], i)), + s = py_thickness_scale(plt, _cycle(series[:marker_size], i)) .^ 2, facecolors = py_color( - get_markercolor(series, i), - get_markeralpha(series, i), + get_marker_color(series, i), + get_marker_alpha(series, i), ), edgecolors = py_color( - get_markerstrokecolor(series, i), - get_markerstrokealpha(series, i), + get_marker_stroke_color(series, i), + get_marker_stroke_alpha(series, i), ), - linewidths = py_thickness_scale(plt, get_markerstrokewidth(series, i)), + linewidths = py_thickness_scale(plt, get_marker_stroke_width(series, i)), extrakw..., ) push!(handles, handle) @@ -508,14 +508,14 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st === :hexbin sekw = series[:extra_kwargs] extrakw[:mincnt] = get(sekw, :mincnt, nothing) - extrakw[:edgecolors] = get(sekw, :edgecolors, py_color(get_linecolor(series))) + extrakw[:edgecolors] = get(sekw, :edgecolors, py_color(get_line_color(series))) handle = ax."hexbin"( x, y; label = series[:label], C = series[:weights], gridsize = series[:bins] === :auto ? 100 : series[:bins], # 100 is the default value - linewidths = py_thickness_scale(plt, series[:linewidth]), + linewidths = py_thickness_scale(plt, series[:line_width]), alpha = series[:fillalpha], cmap = py_fillcolormap(series), # applies to the pcolorfast object zorder = series[:series_plotindex], @@ -532,8 +532,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end end - if typeof(series[:linecolor]) <: AbstractArray - extrakw[:colors] = py_color.(series[:linecolor]) + if typeof(series[:line_color]) <: AbstractArray + extrakw[:colors] = py_color.(series[:line_color]) else extrakw[:cmap] = py_linecolormap(series) end @@ -546,8 +546,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) levelargs...; label = series[:label], zorder = series[:series_plotindex], - linewidths = py_thickness_scale(plt, series[:linewidth]), - linestyles = py_linestyle(st, series[:linestyle]), + linewidths = py_thickness_scale(plt, series[:line_width]), + linestyles = py_linestyle(st, series[:line_style]), extrakw..., ) if series[:contour_labels] == true @@ -594,8 +594,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) zorder = series[:series_plotindex], rstride = series[:stride][1], cstride = series[:stride][2], - linewidth = py_thickness_scale(plt, series[:linewidth]), - edgecolor = py_color(get_linecolor(series)), + linewidth = py_thickness_scale(plt, series[:line_width]), + edgecolor = py_color(get_line_color(series)), extrakw..., ) push!(handles, handle) @@ -626,8 +626,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = series[:label], zorder = series[:series_plotindex], cmap = py_fillcolormap(series), - linewidth = py_thickness_scale(plt, series[:linewidth]), - edgecolor = py_color(get_linecolor(series)), + linewidth = py_thickness_scale(plt, series[:line_width]), + edgecolor = py_color(get_line_color(series)), extrakw..., ) push!(handles, handle) @@ -662,8 +662,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end col = mplot3d.art3d.Poly3DCollection( polygons, - linewidths = py_thickness_scale(plt, series[:linewidth]), - edgecolor = py_color(get_linecolor(series)), + linewidths = py_thickness_scale(plt, series[:line_width]), + edgecolor = py_color(get_line_color(series)), facecolor = py_color(series[:fillcolor]), alpha = get_fillalpha(series), zorder = series[:series_plotindex], @@ -672,7 +672,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # Fix for handle: https://stackoverflow.com/questions/54994600/pyplot-legend-poly3dcollection-object-has-no-attribute-edgecolors2d # It seems there aren't two different alpha values for edge and face handle._facecolors2d = py_color(series[:fillcolor]) - handle._edgecolors2d = py_color(get_linecolor(series)) + handle._edgecolors2d = py_color(get_line_color(series)) push!(handles, handle) end @@ -720,7 +720,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) zorder = series[:series_plotindex], cmap = py_fillcolormap(series), alpha = series[:fillalpha], - # edgecolors = (series[:linewidth] > 0 ? py_linecolor(series) : "face"), + # edgecolors = (series[:line_width] > 0 ? py_linecolor(series) : "face"), extrakw..., ) push!(handles, handle) @@ -731,11 +731,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) for segment in series_segments(series) i, rng = segment.attr_index, segment.range if length(rng) > 1 - lc = get_linecolor(series, clims, i) + lc = get_line_color(series, clims, i) fc = get_fillcolor(series, clims, i) - la = get_linealpha(series, i) + la = get_line_alpha(series, i) fa = get_fillalpha(series, i) - ls = get_linestyle(series, i) + ls = get_line_style(series, i) fs = get_fillstyle(series, i) has_fs = !isnothing(fs) @@ -748,7 +748,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) zorder = series[:series_plotindex], edgecolor = py_color(lc, la), facecolor = py_color(fc, has_fs ? 0 : fa), - linewidth = py_thickness_scale(plt, get_linewidth(series, i)), + linewidth = py_thickness_scale(plt, get_line_width(series, i)), linestyle = py_linestyle(st, ls), fill = !has_fs, ) @@ -797,7 +797,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng) end - la = get_linealpha(series, i) + la = get_line_alpha(series, i) fc = get_fillcolor(series, clims, i) fa = get_fillalpha(series, i) fs = get_fillstyle(series, i) @@ -1448,11 +1448,11 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) clims = get_clims(sp, series) # add a line/marker and a label if series[:seriestype] === :shape || series[:fillrange] !== nothing - lc = get_linecolor(series, clims) + lc = get_line_color(series, clims) fc = get_fillcolor(series, clims) - la = get_linealpha(series) + la = get_line_alpha(series) fa = get_fillalpha(series) - ls = get_linestyle(series) + ls = get_line_style(series) fs = get_fillstyle(series) has_fs = !isnothing(fs) @@ -1460,7 +1460,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) line_handle = pypatches."Patch"( edgecolor = py_color(single_color(lc), la), facecolor = py_color(single_color(fc), has_fs ? 0 : fa), - linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)), + linewidth = py_thickness_scale(plt, clamp(get_line_width(series), 0, 5)), linestyle = py_linestyle(series[:seriestype], ls), capstyle = "butt", ) @@ -1484,37 +1484,37 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) end elseif series[:seriestype] in (:path, :straightline, :scatter, :steppre, :stepmid, :steppost) - has_line = get_linewidth(series) > 0 + has_line = get_line_width(series) > 0 handle = PyPlot.plt."Line2D"( (0, 1), (0, 0), color = py_color( - single_color(get_linecolor(series, clims)), - get_linealpha(series), + single_color(get_line_color(series, clims)), + get_line_alpha(series), ), linewidth = py_thickness_scale( plt, has_line * sp[:legend_font_pointsize] / 8, ), - linestyle = py_linestyle(:path, get_linestyle(series)), + linestyle = py_linestyle(:path, get_line_style(series)), solid_capstyle = "butt", solid_joinstyle = "miter", dash_capstyle = "butt", dash_joinstyle = "miter", - marker = py_marker(_cycle(series[:markershape], 1)), + marker = py_marker(_cycle(series[:marker_shape], 1)), markersize = py_thickness_scale(plt, 0.8sp[:legend_font_pointsize]), markeredgecolor = py_color( - single_color(get_markerstrokecolor(series)), - get_markerstrokealpha(series), + single_color(get_marker_stroke_color(series)), + get_marker_stroke_alpha(series), ), markerfacecolor = py_color( - single_color(get_markercolor(series, clims)), - get_markeralpha(series), + single_color(get_marker_color(series, clims)), + get_marker_alpha(series), ), markeredgewidth = py_thickness_scale( plt, - 0.8get_markerstrokewidth(series) * sp[:legend_font_pointsize] / - first(series[:markersize]), + 0.8get_marker_stroke_width(series) * sp[:legend_font_pointsize] / + first(series[:marker_size]), ), # retain the markersize/markerstroke ratio from the markers on the plot ) push!(handles, handle) diff --git a/src/backends/gaston.jl b/src/backends/gaston.jl index 10b055ca7..e56fde6c5 100644 --- a/src/backends/gaston.jl +++ b/src/backends/gaston.jl @@ -305,7 +305,7 @@ function gaston_seriesconf!( lc, dt, lw = gaston_lc_ls_lw(series, clims, i) curveconf *= if fr !== nothing # filled curves, but not filled curves with markers "w filledcurves fc $fc fs $fs border lc $lc lw $lw dt $dt,'' w lines lc $lc lw $lw dt $dt" - elseif series[:markershape] === :none # simplepath + elseif series[:marker_shape] === :none # simplepath "w lines lc $lc dt $dt lw $lw" else pt, ps, mc = gaston_mk_ms_mc(series, clims, i) @@ -659,15 +659,15 @@ gaston_valign(k) = (top = :top, vcenter = :center, bottom = :bottom)[k] gaston_alpha(alpha) = alpha === nothing ? 0 : alpha gaston_lc_ls_lw(series::Series, clims, i::Int) = ( - gaston_color(get_linecolor(series, clims, i), get_linealpha(series, i)), - gaston_linestyle(get_linestyle(series, i)), - get_linewidth(series, i), + gaston_color(get_line_color(series, clims, i), get_line_alpha(series, i)), + gaston_linestyle(get_line_style(series, i)), + get_line_width(series, i), ) gaston_mk_ms_mc(series::Series, clims, i::Int) = ( - gaston_marker(_cycle(series[:markershape], i), get_markeralpha(series, i)), - 0.2_cycle(series[:markersize], i), - gaston_color(get_markercolor(series, clims, i), get_markeralpha(series, i)), + gaston_marker(_cycle(series[:marker_shape], i), get_marker_alpha(series, i)), + _cycle(series[:marker_size], i) * 1.3 / 5, + gaston_color(get_marker_color(series, clims, i), get_marker_alpha(series, i)), ) function gaston_font(f; rot = true, align = true, color = true, scale = 1) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b7ccf0695..a9bb9a374 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -371,15 +371,15 @@ function gr_draw_marker(series, xi, yi, zi, clims, i, msize, strokewidth, shape: xs, ys = getindex.(xs_ys, 1), getindex.(xs_ys, 2) # draw the interior - mc = get_markercolor(series, clims, i) + mc = get_marker_color(series, clims, i) gr_set_fill(mc) - gr_set_transparency(mc, get_markeralpha(series, i)) + gr_set_transparency(mc, get_marker_alpha(series, i)) GR.fillarea(xs, ys) # draw the shapes - msc = get_markerstrokecolor(series, i) + msc = get_marker_stroke_color(series, i) gr_set_line(strokewidth, :solid, msc, series) - gr_set_transparency(msc, get_markerstrokealpha(series, i)) + gr_set_transparency(msc, get_marker_stroke_alpha(series, i)) GR.polyline(xs, ys) nothing end @@ -387,9 +387,9 @@ end # draw ONE symbol marker function gr_draw_marker(series, xi, yi, zi, clims, i, msize, strokewidth, shape::Symbol) GR.setborderwidth(strokewidth) - gr_set_bordercolor(get_markerstrokecolor(series, i)) - gr_set_markercolor(get_markercolor(series, clims, i)) - gr_set_transparency(get_markeralpha(series, i)) + gr_set_bordercolor(get_marker_stroke_color(series, i)) + gr_set_markercolor(get_marker_color(series, clims, i)) + gr_set_transparency(get_marker_alpha(series, i)) GR.setmarkertype(gr_markertypes[shape]) GR.setmarkersize(0.3msize / gr_nominal_size(series)) if zi === nothing @@ -588,12 +588,12 @@ function gr_draw_colorbar(cbar::GRColorbar, sp::Subplot, vp::GRViewport) series = cbar.lines gr_set_gradient(_cbar_unique(get_colorgradient.(series), "color")) gr_set_line( - _cbar_unique(get_linewidth.(series), "line width"), - _cbar_unique(get_linestyle.(series), "line style"), - _cbar_unique(get_linecolor.(series, Ref(clims)), "line color"), + _cbar_unique(get_line_width.(series), "line width"), + _cbar_unique(get_line_style.(series), "line style"), + _cbar_unique(get_line_color.(series, Ref(clims)), "line color"), sp, ) - gr_set_transparency(_cbar_unique(get_linealpha.(series), "line alpha")) + gr_set_transparency(_cbar_unique(get_line_alpha.(series), "line alpha")) levels = _cbar_unique(contour_levels.(series, Ref(clims)), "levels") colors = gr_colorbar_colors(last(series), clims) for (line, color) in zip(levels, colors) @@ -1034,10 +1034,10 @@ function gr_add_legend(sp, leg, viewport_area) should_add_to_legend(series) || continue st = series[:seriestype] clims = gr_clims(sp, series) - lc = get_linecolor(series, clims) - lw = get_linewidth(series) - ls = get_linestyle(series) - la = get_linealpha(series) + lc = get_line_color(series, clims) + lw = get_line_width(series) + ls = get_line_style(series) + la = get_line_alpha(series) clamped_lw = (lfps / 8) * clamp(lw, min_lw, max_lw) gr_set_line(clamped_lw, ls, lc, sp) # see github.com/JuliaPlots/Plots.jl/issues/3003 _debug[] && gr_legend_bbox(xpos, ypos, leg) @@ -1059,6 +1059,9 @@ function gr_add_legend(sp, leg, viewport_area) x, y = [l, r, r, l, l], [b, b, t, t, b] gr_set_transparency(fc, get_fillalpha(series)) gr_polyline(x, y, GR.fillarea) + lc = get_line_color(series, clims) + gr_set_transparency(lc, get_line_alpha(series)) + gr_set_line(get_line_width(series), get_line_style(series), lc, sp) gr_set_transparency(lc, la) gr_set_line(clamped_lw, ls, lc, sp) st === :shape && gr_polyline(x, y) @@ -1067,14 +1070,14 @@ function gr_add_legend(sp, leg, viewport_area) max_markersize = Inf if st in (:path, :straightline, :path3d) max_markersize = leg.base_markersize - gr_set_transparency(lc, la) + gr_set_transparency(lc, get_line_alpha(series)) filled = series[:fillrange] !== nothing && series[:ribbon] === nothing GR.polyline(xpos .+ [lft, rgt], ypos .+ (filled ? [top, top] : [0, 0])) end - if (msh = series[:markershape]) !== :none - msz = first(series[:markersize]) - msw = first(series[:markerstrokewidth]) + if (msh = series[:marker_shape]) !== :none + msz = first(series[:marker_size]) + msw = first(series[:marker_stroke_width]) gr_draw_marker( series, xpos - 2leg.base_factor, @@ -1250,8 +1253,8 @@ function gr_get_legend_geometry(vp, sp) span_hspace = span + pad # part of the horizontal increment dx = (textw + (vertical ? 0 : span_hspace)) * get(ekw, :legend_wfactor, 1) - # This is to prevent that linestyle is obscured by large markers. - # We are trying to get markers to not be larger than half the line length. + # This is to prevent that linestyle is obscured by large markers. + # We are trying to get markers to not be larger than half the line length. # 1 / leg.dy translates base_factor to line length units (important in the context of size kwarg) # gr_legend_marker_to_line_factor is an empirical constant to translate between line length unit and marker size unit base_markersize = gr_legend_marker_to_line_factor[] * span / dy # NOTE: arbitrarily based on horizontal measures ! @@ -1727,14 +1730,14 @@ function gr_add_series(sp, series) x, y = straightline_data(series) end gr_draw_segments(series, x, y, nothing, frng, clims) - if series[:markershape] !== :none + if series[:marker_shape] !== :none gr_draw_markers(series, x, y, nothing, clims) end elseif st === :shape gr_draw_shapes(series, clims) elseif st in (:path3d, :scatter3d) gr_draw_segments(series, x, y, z, nothing, clims) - if st === :scatter3d || series[:markershape] !== :none + if st === :scatter3d || series[:marker_shape] !== :none gr_draw_markers(series, x, y, z, clims) end elseif st === :contour @@ -1798,9 +1801,9 @@ function gr_draw_segments(series, x, y, z, fillrange, clims) gr_set_transparency(fc, get_fillalpha(series, i)) GR.fillarea(fx, fy) end - (lc = get_linecolor(series, clims, i)) |> gr_set_fillcolor - gr_set_line(get_linewidth(series, i), get_linestyle(series, i), lc, series) - gr_set_transparency(lc, get_linealpha(series, i)) + (lc = get_line_color(series, clims, i)) |> gr_set_fillcolor + gr_set_line(get_line_width(series, i), get_line_style(series, i), lc, series) + gr_set_transparency(lc, get_line_alpha(series, i)) if is3d GR.polyline3d(x[rng], y[rng], z[rng]) elseif is2d @@ -1820,12 +1823,12 @@ function gr_draw_markers( y, z, clims, - msize = series[:markersize], - strokewidth = series[:markerstrokewidth], + msize = series[:marker_size], + strokewidth = series[:marker_stroke_width], ) isempty(x) && return GR.setfillintstyle(GR.INTSTYLE_SOLID) - (shapes = series[:markershape]) === :none && return + (shapes = series[:marker_shape]) === :none && return for segment in series_segments(series, :scatter) rng = intersect(eachindex(IndexLinear(), x), segment.range) isempty(rng) && continue @@ -1869,9 +1872,9 @@ function gr_draw_shapes(series, clims) GR.fillarea(xseg, yseg) # draw the shapes - lc = get_linecolor(series, clims, i) - gr_set_line(get_linewidth(series, i), get_linestyle(series, i), lc, series) - gr_set_transparency(lc, get_linealpha(series, i)) + lc = get_line_color(series, clims, i) + gr_set_line(get_line_width(series, i), get_line_style(series, i), lc, series) + gr_set_transparency(lc, get_line_alpha(series, i)) GR.polyline(xseg, yseg) end end @@ -1880,14 +1883,19 @@ end function gr_draw_contour(series, x, y, z, clims) GR.setprojectiontype(0) GR.setspace(clims[1], clims[2], 0, 90) - gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series), series) + gr_set_line( + get_line_width(series), + get_line_style(series), + get_line_color(series), + series, + ) gr_set_transparency(get_fillalpha(series)) h = gr_contour_levels(series, clims) if series[:fillrange] !== nothing GR.contourf(x, y, h, z, Int(series[:contour_labels] == true)) else black = plot_color(:black) - coff = plot_color(series[:linecolor]) in (black, [black]) ? 0 : 1_000 + coff = plot_color(series[:line_color]) in (black, [black]) ? 0 : 1_000 GR.contour(x, y, h, z, coff + Int(series[:contour_labels] == true)) end nothing @@ -1946,8 +1954,8 @@ function gr_draw_surface(series, x, y, z, clims) end fillalpha = get_fillalpha(series) facecolor = map(fc -> set_RGBA_alpha(fillalpha, fc), facecolor) - GR.setborderwidth(get_linewidth(series)) - GR.setbordercolorind(gr_getcolorind(get_linecolor(series))) + GR.setborderwidth(get_line_width(series)) + GR.setbordercolorind(gr_getcolorind(get_line_color(series))) GR.polygonmesh3d(x, y, z, vcat(cns...), signed.(gr_color.(facecolor))) else throw(ArgumentError("Not handled !")) diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl index c81c5690b..2091ce071 100644 --- a/src/backends/hdf5.jl +++ b/src/backends/hdf5.jl @@ -426,7 +426,7 @@ end # 1st arg appears to be ref to subplots. Seems to work without it. _read(::Type{Axis}, grp::Group) = - Axis([], DefaultsDict(_read(KW, grp["plotattributes"]), _axis_defaults)) + Axis([], DefaultsDict(Plot, _read(KW, grp["plotattributes"]), _axis_defaults)) # Not for use in main "Plot.subplots[]" hierarchy. Just establishes reference with subplot_index. _read(::Type{Subplot}, grp::Group) = diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index c6ea6c7ac..8660ab6f9 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -253,8 +253,8 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) for (i, rng) in enumerate(iter_segments(x, y)) nmax = i if length(rng) > 1 - linewidth = series[:linewidth] - c = plot_color(get_linecolor(series), get_linealpha(series)) + linewidth = series[:line_width] + c = plot_color(get_line_color(series), get_line_alpha(series)) linecolor = _inspectdr_mapcolor(_cycle(c, i)) c = plot_color(get_fillcolor(series), get_fillalpha(series)) fillcolor = _inspectdr_mapcolor(_cycle(c, i)) @@ -271,8 +271,8 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) i = (nmax >= 2 ? div(nmax, 2) : nmax) #Must pick one set of colors for legend if i > 1 #Add dummy waveform for legend entry: - linewidth = series[:linewidth] - c = plot_color(get_linecolor(series), get_linealpha(series)) + linewidth = series[:line_width] + c = plot_color(get_line_color(series), get_line_alpha(series)) linecolor = _inspectdr_mapcolor(_cycle(c, i)) c = plot_color(get_fillcolor(series), get_fillalpha(series)) fillcolor = _inspectdr_mapcolor(_cycle(c, i)) @@ -290,28 +290,31 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) end elseif st in (:path, :scatter, :straightline) #, :steppre, :stepmid, :steppost) # NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think). - linewidth = series[:linewidth] + linewidth = series[:line_width] # More efficient & allows some support for markerstrokewidth: - _style = (0 == linewidth ? :none : series[:linestyle]) + _style = (0 == linewidth ? :none : series[:line_style]) wfrm = InspectDR.add(plot, x, y, id = series[:label]) wfrm.line = InspectDR.line( style = _style, - width = series[:linewidth], - color = plot_color(get_linecolor(series), get_linealpha(series)), + width = series[:line_width], + color = plot_color(get_line_color(series), get_line_alpha(series)), ) # InspectDR does not control markerstrokewidth independently. if _style === :none # Use this property only if no line is displayed: - wfrm.line.width = series[:markerstrokewidth] + wfrm.line.width = series[:marker_stroke_width] end wfrm.glyph = InspectDR.glyph( - shape = _inspectdr_mapglyph(series[:markershape]), - size = _inspectdr_mapglyphsize(series[:markersize]), + shape = _inspectdr_mapglyph(series[:marker_shape]), + size = _inspectdr_mapglyphsize(series[:marker_size]), color = _inspectdr_mapcolor( - plot_color(get_markerstrokecolor(series), get_markerstrokealpha(series)), + plot_color( + get_marker_stroke_color(series), + get_marker_stroke_alpha(series), + ), ), fillcolor = _inspectdr_mapcolor( - plot_color(get_markercolor(series, clims), get_markeralpha(series)), + plot_color(get_marker_color(series, clims), get_marker_alpha(series)), ), ) end diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index 435cbf527..ae5a97ff3 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -266,7 +266,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend}) extra_series, extra_series_opt = pgfx_split_extra_kw(series[:extra_kwargs]) series_opt = merge( Options( - "color" => single_color(opt[:linecolor]), + "color" => single_color(opt[:line_color]), "name path" => string(series_id), ), Options(extra_series_opt...), @@ -337,10 +337,10 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o for (k, segment) in enumerate(segments) i, rng = segment.attr_index, segment.range segment_opt = merge(Options(), pgfx_linestyle(opt, i)) - if opt[:markershape] !== :none - if (marker = _cycle(opt[:markershape], i)) isa Shape + if opt[:marker_shape] !== :none + if (marker = _cycle(opt[:marker_shape], i)) isa Shape scale_factor = 0.00125 - msize = opt[:markersize] * scale_factor + msize = opt[:marker_size] * scale_factor path = join( map((x, y) -> "($(x * msize), $(y * msize))", marker.x, marker.y), " -- ", @@ -436,7 +436,7 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o end # for segments # get that last marker - if !isnothing(opt[:y]) && !any(isnan, opt[:y]) && opt[:markershape] isa AVec + if !isnothing(opt[:y]) && !any(isnan, opt[:y]) && opt[:marker_shape] isa AVec push!( axis, PGFPlotsX.PlotInc( # additional plot @@ -646,8 +646,8 @@ pgfx_series_arguments(series, opt) = opt[:x], opt[:y] end -pgfx_get_linestyle(k::AbstractString) = pgfx_get_linestyle(Symbol(k)) -pgfx_get_linestyle(k::Symbol) = get( +pgfx_get_line_style(k::AbstractString) = pgfx_get_line_style(Symbol(k)) +pgfx_get_line_style(k::Symbol) = get( ( solid = "solid", dash = "dashed", @@ -883,7 +883,7 @@ function pgfx_linestyle(linewidth::Real, color, α = 1, linestyle = :solid) "color" => cstr, "draw opacity" => alpha(cstr), "line width" => linewidth, - pgfx_get_linestyle(linestyle) => nothing, + pgfx_get_line_style(linestyle) => nothing, ) end @@ -891,10 +891,10 @@ pgfx_legend_col(s::Symbol) = s === :horizontal ? -1 : 1 pgfx_legend_col(n) = n function pgfx_linestyle(plotattributes, i = 1) - lw = pgfx_thickness_scaling(plotattributes) * get_linewidth(plotattributes, i) - lc = single_color(get_linecolor(plotattributes, i)) - la = get_linealpha(plotattributes, i) - ls = get_linestyle(plotattributes, i) + lw = pgfx_thickness_scaling(plotattributes) * get_line_width(plotattributes, i) + lc = single_color(get_line_color(plotattributes, i)) + la = get_line_alpha(plotattributes, i) + ls = get_line_style(plotattributes, i) return pgfx_linestyle(lw, lc, la, ls) end @@ -924,19 +924,19 @@ pgfx_should_add_to_legend(series::Series) = ) function pgfx_marker(plotattributes, i = 1) - shape = _cycle(plotattributes[:markershape], i) + shape = _cycle(plotattributes[:marker_shape], i) cstr = - plot_color(get_markercolor(plotattributes, i), get_markeralpha(plotattributes, i)) + plot_color(get_marker_color(plotattributes, i), get_marker_alpha(plotattributes, i)) cstr_stroke = plot_color( - get_markerstrokecolor(plotattributes, i), - get_markerstrokealpha(plotattributes, i), + get_marker_stroke_color(plotattributes, i), + get_marker_stroke_alpha(plotattributes, i), ) mark_size = pgfx_thickness_scaling(plotattributes) * 0.75 * - _cycle(plotattributes[:markersize], i) - mark_freq = if !any(isnan, plotattributes[:y]) && plotattributes[:markershape] isa AVec - length(plotattributes[:markershape]) + _cycle(plotattributes[:marker_size], i) + mark_freq = if !any(isnan, plotattributes[:y]) && plotattributes[:marker_shape] isa AVec + length(plotattributes[:marker_shape]) else 1 end @@ -952,7 +952,7 @@ function pgfx_marker(plotattributes, i = 1) "line width" => pgfx_thickness_scaling(plotattributes) * 0.75 * - _cycle(plotattributes[:markerstrokewidth], i), + _cycle(plotattributes[:marker_stroke_width], i), "rotate" => if shape === :dtriangle 180 elseif shape === :rtriangle @@ -962,7 +962,7 @@ function pgfx_marker(plotattributes, i = 1) else 0 end, - pgfx_get_linestyle(_cycle(plotattributes[:markerstrokestyle], i)) => + pgfx_get_line_style(_cycle(plotattributes[:marker_stroke_style], i)) => nothing, ), ) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 1711f0bf9..a715b12a6 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -101,7 +101,7 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing) :zeroline => framestyle === :zerolines, :zerolinecolor => rgba_string(axis[:foreground_color_axis]), :showline => framestyle in (:box, :axes) && axis[:showaxis], - :linecolor => rgba_string(plot_color(axis[:foreground_color_axis])), + :line_color => rgba_string(plot_color(axis[:foreground_color_axis])), :ticks => axis[:tick_direction] === :out ? "outside" : axis[:tick_direction] === :in ? "inside" : "", @@ -125,7 +125,7 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing) ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) - ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) + ax[:line_color] = rgba_string(axis[:foreground_color_axis]) # ticks if axis[:ticks] !== :native @@ -547,7 +547,7 @@ function plotly_series(plt::Plot, series::Series) plotattributes_out[:name] = series[:label] isscatter = st in (:scatter, :scatter3d, :scattergl) - hasmarker = isscatter || series[:markershape] !== :none + hasmarker = isscatter || series[:marker_shape] !== :none hasline = st in (:path, :path3d, :straightline) hasfillrange = st in (:path, :scatter, :scattergl, :straightline) && @@ -605,7 +605,7 @@ function plotly_series(plt::Plot, series::Series) end end plotattributes_out[:colorscale] = - plotly_colorscale(series[:linecolor], series[:linealpha]) + plotly_colorscale(series[:line_color], series[:line_alpha]) plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series) elseif st in (:surface, :wireframe) @@ -616,8 +616,8 @@ function plotly_series(plt::Plot, series::Series) wirelines = KW( :show => true, :color => - rgba_string(plot_color(series[:linecolor], series[:linealpha])), - :highlightwidth => series[:linewidth], + rgba_string(plot_color(series[:line_color], series[:line_alpha])), + :highlightwidth => series[:line_width], ) plotattributes_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines) @@ -686,25 +686,25 @@ function plotly_series(plt::Plot, series::Series) inds = eachindex(x) plotattributes_out[:marker] = KW( :symbol => - get_plotly_marker(series[:markershape], string(series[:markershape])), - # :opacity => series[:markeralpha], - :size => 2_cycle(series[:markersize], inds), + get_plotly_marker(series[:marker_shape], string(series[:marker_shape])), + # :opacity => series[:marker_alpha], + :size => 2_cycle(series[:marker_size], inds), :color => rgba_string.( plot_color.( - get_markercolor.(series, inds), - get_markeralpha.(series, inds), + get_marker_color.(series, inds), + get_marker_alpha.(series, inds), ), ), :line => KW( :color => rgba_string.( plot_color.( - get_markerstrokecolor.(series, inds), - get_markerstrokealpha.(series, inds), + get_marker_stroke_color.(series, inds), + get_marker_stroke_alpha.(series, inds), ), ), - :width => _cycle(series[:markerstrokewidth], inds), + :width => _cycle(series[:marker_stroke_width], inds), ), ) end @@ -765,13 +765,13 @@ function plotly_series_shapes(plt::Plot, series::Series, clims) ), ), ) - if series[:markerstrokewidth] > 0 + if series[:marker_stroke_width] > 0 plotattributes_out[:line] = KW( :color => rgba_string( - plot_color(get_linecolor(series, clims, i), get_linealpha(series, i)), + plot_color(get_line_color(series, clims, i), get_line_alpha(series, i)), ), - :width => get_linewidth(series, i), - :dash => string(get_linestyle(series, i)), + :width => get_line_width(series, i), + :dash => string(get_line_style(series, i)), ) end plotattributes_out[:showlegend] = k == 1 ? should_add_to_legend(series) : false @@ -796,7 +796,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z st = series[:seriestype] sp = series[:subplot] isscatter = st in (:scatter, :scatter3d, :scattergl) - hasmarker = isscatter || series[:markershape] !== :none + hasmarker = isscatter || series[:marker_shape] !== :none hasline = st in (:path, :path3d, :straightline) hasfillrange = st in (:path, :scatter, :scattergl, :straightline) && @@ -853,39 +853,39 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z # add "marker" if hasmarker mcolor = rgba_string( - plot_color(get_markercolor(series, clims, i), get_markeralpha(series, i)), + plot_color(get_marker_color(series, clims, i), get_marker_alpha(series, i)), ) mcolor_next = if (mz = series[:marker_z]) !== nothing && i < length(mz) plot_color( - get_markercolor(series, clims, i + 1), - get_markeralpha(series, i + 1), + get_marker_color(series, clims, i + 1), + get_marker_alpha(series, i + 1), ) |> rgba_string else mcolor end lcolor = rgba_string( plot_color( - get_markerstrokecolor(series, i), - get_markerstrokealpha(series, i), + get_marker_stroke_color(series, i), + get_marker_stroke_alpha(series, i), ), ) lcolor_next = plot_color( - get_markerstrokecolor(series, i + 1), - get_markerstrokealpha(series, i + 1), + get_marker_stroke_color(series, i + 1), + get_marker_stroke_alpha(series, i + 1), ) |> rgba_string plotattributes_out[:marker] = KW( :symbol => get_plotly_marker( - _cycle(series[:markershape], i), - string(_cycle(series[:markershape], i)), + _cycle(series[:marker_shape], i), + string(_cycle(series[:marker_shape], i)), ), # :opacity => needs_scatter_fix ? [1, 0] : 1, - :size => 2_cycle(series[:markersize], i), + :size => 2_cycle(series[:marker_size], i), :color => needs_scatter_fix ? [mcolor, mcolor_next] : mcolor, :line => KW( :color => needs_scatter_fix ? [lcolor, lcolor_next] : lcolor, - :width => _cycle(series[:markerstrokewidth], i), + :width => _cycle(series[:marker_stroke_width], i), ), ) end @@ -894,9 +894,9 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z if hasline plotattributes_out[:line] = KW( :color => rgba_string( - plot_color(get_linecolor(series, clims, i), get_linealpha(series, i)), + plot_color(get_line_color(series, clims, i), get_line_alpha(series, i)), ), - :width => get_linewidth(series, i), + :width => get_line_width(series, i), :shape => if st === :steppre "vh" elseif st === :stepmid @@ -906,7 +906,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z else "linear" end, - :dash => string(get_linestyle(series, i)), + :dash => string(get_line_style(series, i)), ) end diff --git a/src/backends/pythonplot.jl b/src/backends/pythonplot.jl index 02fb4e207..f91752cbc 100644 --- a/src/backends/pythonplot.jl +++ b/src/backends/pythonplot.jl @@ -178,7 +178,7 @@ is_valid_cgrad_color(::Any) = false _py_linecolormap(series::Series) = if (color = get(series, :linecolor, nothing)) |> is_valid_cgrad_color - _py_colormap(cgrad(color, alpha = get_linealpha(series))) + _py_colormap(cgrad(color, alpha = get_line_alpha(series))) else nothing end @@ -190,7 +190,7 @@ _py_fillcolormap(series::Series) = end _py_markercolormap(series::Series) = if (color = get(series, :markercolor, nothing)) |> is_valid_cgrad_color - _py_colormap(cgrad(color, alpha = get_markeralpha(series))) + _py_colormap(cgrad(color, alpha = get_marker_alpha(series))) else nothing end @@ -366,9 +366,9 @@ function _py_add_series(plt::Plot{PythonPlotBackend}, series::Series) # some defaults cbar_scale = sp[:colorbar_scale] - linewidths = linewidth = _py_thickness_scale(plt, get_linewidth(series)) - linestyles = linestyle = _py_linestyle(st, get_linestyle(series)) - edgecolor = edgecolors = _py_color(get_linecolor(series, 1, cbar_scale)) + linewidths = linewidth = _py_thickness_scale(plt, get_line_width(series)) + linestyles = linestyle = _py_linestyle(st, get_line_style(series)) + edgecolor = edgecolors = _py_color(get_line_color(series, 1, cbar_scale)) facecolor = facecolors = _py_color(series[:fillcolor]) zorder = series[:series_plotindex] alpha = get_fillalpha(series) @@ -382,11 +382,11 @@ function _py_add_series(plt::Plot{PythonPlotBackend}, series::Series) map(arg -> arg[rng], xyargs)...; label = k == 1 ? label : "", color = _py_color( - single_color(get_linecolor(series, clims, i, cbar_scale)), - get_linealpha(series, i), + single_color(get_line_color(series, clims, i, cbar_scale)), + get_line_alpha(series, i), ), - linewidth = _py_thickness_scale(plt, get_linewidth(series, i)), - linestyle = _py_linestyle(st, get_linestyle(series, i)), + linewidth = _py_thickness_scale(plt, get_line_width(series, i)), + linestyle = _py_linestyle(st, get_line_style(series, i)), solid_capstyle = "butt", dash_capstyle = "butt", drawstyle = _py_stepstyle(st), @@ -436,14 +436,14 @@ function _py_add_series(plt::Plot{PythonPlotBackend}, series::Series) marker = _py_marker(_cycle(series[:markershape], i)), s = _py_thickness_scale(plt, _cycle(series[:markersize], i)) .^ 2, facecolors = _py_color( - get_markercolor(series, i, cbar_scale), - get_markeralpha(series, i), + get_marker_color(series, i, cbar_scale), + get_marker_alpha(series, i), ), edgecolors = _py_color( - get_markerstrokecolor(series, i), - get_markerstrokealpha(series, i), + get_marker_stroke_color(series, i), + get_marker_stroke_alpha(series, i), ), - linewidths = _py_thickness_scale(plt, get_markerstrokewidth(series, i)), + linewidths = _py_thickness_scale(plt, get_marker_stroke_width(series, i)), label, extrakw..., ) |> push_h @@ -454,11 +454,11 @@ function _py_add_series(plt::Plot{PythonPlotBackend}, series::Series) for segment in series_segments(series) i, rng = segment.attr_index, segment.range if length(rng) > 1 - lc = get_linecolor(series, clims, i, cbar_scale) + lc = get_line_color(series, clims, i, cbar_scale) fc = get_fillcolor(series, clims, i) - la = get_linealpha(series, i) + la = get_line_alpha(series, i) fa = get_fillalpha(series, i) - ls = get_linestyle(series, i) + ls = get_line_style(series, i) fs = get_fillstyle(series, i) has_fs = !isnothing(fs) @@ -471,7 +471,7 @@ function _py_add_series(plt::Plot{PythonPlotBackend}, series::Series) path; edgecolor = _py_color(lc, la), facecolor = _py_color(fc, has_fs ? 0 : fa), - linewidth = _py_thickness_scale(plt, get_linewidth(series, i)), + linewidth = _py_thickness_scale(plt, get_line_width(series, i)), linestyle = _py_linestyle(st, ls), fill = !has_fs, zorder, @@ -717,7 +717,7 @@ function _py_add_series(plt::Plot{PythonPlotBackend}, series::Series) dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng) end - la = get_linealpha(series, i) + la = get_line_alpha(series, i) fc = get_fillcolor(series, clims, i) fa = get_fillalpha(series, i) fs = get_fillstyle(series, i) @@ -1337,11 +1337,11 @@ function _py_add_legend(plt::Plot, sp::Subplot, ax) nseries += 1 # add a line/marker and a label if series[:seriestype] === :shape || series[:fillrange] !== nothing - lc = get_linecolor(series, clims) + lc = get_line_color(series, clims) fc = get_fillcolor(series, clims) - la = get_linealpha(series) + la = get_line_alpha(series) fa = get_fillalpha(series) - ls = get_linestyle(series) + ls = get_line_style(series) fs = get_fillstyle(series) has_fs = !isnothing(fs) @@ -1349,7 +1349,7 @@ function _py_add_legend(plt::Plot, sp::Subplot, ax) mpl.patches.Patch( edgecolor = _py_color(single_color(lc), la), facecolor = _py_color(single_color(fc), has_fs ? 0 : fa), - linewidth = _py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)), + linewidth = _py_thickness_scale(plt, clamp(get_line_width(series), 0, 5)), linestyle = _py_linestyle(series[:seriestype], ls), capstyle = "butt", ) |> push_h @@ -1369,19 +1369,19 @@ function _py_add_legend(plt::Plot, sp::Subplot, ax) capstyle = "butt", ) |> push_h elseif series[:seriestype] ∈ _py_legend_series - has_line = get_linewidth(series) > 0 + has_line = get_line_width(series) > 0 PythonPlot.pyplot.Line2D( (0, 1), (0, 0), color = _py_color( - single_color(get_linecolor(series, clims)), - get_linealpha(series), + single_color(get_line_color(series, clims)), + get_line_alpha(series), ), linewidth = _py_thickness_scale( plt, has_line * sp[:legend_font_pointsize] / 8, ), - linestyle = _py_linestyle(:path, get_linestyle(series)), + linestyle = _py_linestyle(:path, get_line_style(series)), solid_capstyle = "butt", solid_joinstyle = "miter", dash_capstyle = "butt", @@ -1389,16 +1389,16 @@ function _py_add_legend(plt::Plot, sp::Subplot, ax) marker = _py_marker(_cycle(series[:markershape], 1)), markersize = _py_thickness_scale(plt, 0.8sp[:legend_font_pointsize]), markeredgecolor = _py_color( - single_color(get_markerstrokecolor(series)), - get_markerstrokealpha(series), + single_color(get_marker_stroke_color(series)), + get_marker_stroke_alpha(series), ), markerfacecolor = _py_color( - single_color(get_markercolor(series, clims, 1, sp[:colorbar_scale])), - get_markeralpha(series), + single_color(get_marker_color(series, clims, 1, sp[:colorbar_scale])), + get_marker_alpha(series), ), markeredgewidth = _py_thickness_scale( plt, - 0.8get_markerstrokewidth(series) * sp[:legend_font_pointsize] / + 0.8get_marker_stroke_width(series) * sp[:legend_font_pointsize] / first(series[:markersize]), ), # retain the markersize/markerstroke ratio from the markers on the plot ) |> push_h diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 057c68d09..02c77362c 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -207,7 +207,7 @@ function addUnicodeSeries!( kw = ( kw..., zlabel = sp[:colorbar_title], - color = st ≡ :wireframe ? up_color(get_linecolor(series, 1)) : nothing, + color = st ≡ :wireframe ? up_color(get_line_color(series, 1)) : nothing, colormap = colormap ≡ :none ? up_cmap(series) : colormap, colorbar = hascolorbar(sp), zscale, @@ -226,9 +226,9 @@ function addUnicodeSeries!( if st in (:path, :path3d, :straightline, :shape, :mesh3d) func = UnicodePlots.lineplot! series_kw = (; head_tail = series[:arrow] isa Arrow ? series[:arrow].side : nothing) - elseif st in (:scatter, :scatter3d) || series[:markershape] ≢ :none + elseif st in (:scatter, :scatter3d) || series[:marker_shape] ≢ :none func = UnicodePlots.scatterplot! - series_kw = (; marker = series[:markershape]) + series_kw = (; marker = series[:marker_shape]) else throw(ArgumentError("Plots(UnicodePlots): series type $st not supported")) end @@ -237,7 +237,7 @@ function addUnicodeSeries!( for (n, segment) in enumerate(series_segments(series, st; check = true)) i, rng = segment.attr_index, segment.range - lc = get_linecolor(series, i) + lc = get_line_color(series, i) up = func( up, x[rng], @@ -291,7 +291,11 @@ function _show(io::IO, ::MIME"image/png", plt::Plot{UnicodePlotsBackend}) if (l = plt.layout[r, c]) isa GridLayout && size(l) != (1, 1) unsupported_layout_error() else - img = UnicodePlots.png_image(plt.o[sps += 1]; pixelsize = 32) + img = UnicodePlots.png_image( + plt.o[sps += 1]; + pixelsize = 32, + font = plt[:fontfamily], + ) img ≡ nothing && continue canvas_type = eltype(img) s1[r, c], s2[r, c] = size(img) diff --git a/src/components.jl b/src/components.jl index 0725ca3c9..daa4d797b 100644 --- a/src/components.jl +++ b/src/components.jl @@ -555,8 +555,8 @@ function series_annotations_shapes!(series::Series, scaletype::Symbol = :pixels) shapes[i] = scale(baseshape, msw * xscale / maxscale, msh * yscale / maxscale, (0, 0)) end - series[:markershape] = shapes - series[:markersize] = msize + series[:marker_shape] = shapes + series[:marker_size] = msize end nothing end @@ -836,4 +836,42 @@ end :match = ( :legend_font_color, :legend_title_font_family, :legend_title_font_color, +) :aliases = Dict( + :legend_position => (:legend, :leg, :key), + :legend_background_color => + (:background_legend, :background_colour_legend, :background_color_legend), + :legend_foreground_color => + (:foreground_legend, :foreground_color_legend, :foreground_colour_legend), +) + +### Line + +@add_attributes series struct Line + style = :solid + width = :auto + color = :auto + alpha = nothing +end :aliases = Dict( + :line_color => (:lc, :lcolor, :lcolour, :line_colour), + :line_alpha => (:lalpha,), + :line_width => (:w, :width, :lw), + :line_style => (:s, :style, :ls), +) + +### Marker + +@add_attributes series struct Marker + shape = :none + color = :match + alpha = nothing + stroke::Line = Line(:solid, 1, :match, nothing) + size = 4 +end :aliases = Dict( + :marker_color => (:mc, :mcolor, :mcolour, :marker_colour), + :marker_alpha => (:malpha,), + :marker_shape => (:shape,), + :marker_size => (:ms, :msize), + :marker_stroke_color => (:msc, :mscolor, :mscolour), + :marker_stroke_alpha => (:msalpha,), + :marker_stroke_width => (:msw, :mswidth), ) diff --git a/src/consts.jl b/src/consts.jl index 764ac3c7a..ee16414a2 100644 --- a/src/consts.jl +++ b/src/consts.jl @@ -42,7 +42,7 @@ const _internal_args = [ :plot_object, :series_plotindex, :series_index, - :markershape_to_add, + :marker_shape_to_add, :letter, :idxfilter, ] @@ -69,6 +69,9 @@ const _all_plot_args = _plot_args const _all_args = union(_lettered_all_axis_args, _all_subplot_args, _all_series_args, _all_plot_args) +const _all_segmenting_attributes = + Set(_segmenting_vector_attributes ∪ _segmenting_array_attributes) + # add all pluralized forms to the _keyAliases dict for arg in _all_args add_aliases(arg, makeplural(arg)) diff --git a/src/pipeline.jl b/src/pipeline.jl index 7eaf620a0..ed52b8f2c 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -10,7 +10,8 @@ function RecipesPipeline.warn_on_recipe_aliases!( ) pkeys = keys(plotattributes) for k in pkeys - if (dk = get(_keyAliases, k, nothing)) !== nothing + dk = get(_keyAliases, k, nothing) + if dk !== nothing kv = RecipesPipeline.pop_kw!(plotattributes, k) dk ∈ pkeys || (plotattributes[dk] = kv) end @@ -140,8 +141,9 @@ RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter, ## Plot recipes -RecipesPipeline.type_alias(plt::Plot, st) = get(_typeAliases, st, st) +RecipesPipeline.type_alias(pt::Type{<:Plots.Plot}, st) = get(_typeAliases, st, st) +RecipesPipeline.key_alias(pt::Type{<:Plots.Plot}, key) = get(_keyAliases, key, key) ## Plot setup function RecipesPipeline.plot_setup!(plt::Plot, plotattributes, kw_list) @@ -356,11 +358,11 @@ function RecipesPipeline.add_series!(plt::Plot, plotattributes) sp = _prepare_subplot(plt, plotattributes) if (perm = plotattributes[:permute]) !== :none letter1, letter2 = perm - ms = plotattributes[:markershape] + ms = plotattributes[:marker_shape] if ms === :hline && (perm == (:x, :y) || perm == (:y, :x)) - plotattributes[:markershape] = :vline + plotattributes[:marker_shape] = :vline elseif ms === :vline && (perm == (:x, :y) || perm == (:y, :x)) - plotattributes[:markershape] = :hline + plotattributes[:marker_shape] = :hline end plotattributes[letter1], plotattributes[letter2] = plotattributes[letter2], plotattributes[letter1] diff --git a/src/recipes.jl b/src/recipes.jl index 8f75dbeca..af8556770 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -46,20 +46,20 @@ RecipesBase.apply_recipe(plotattributes::AKW, ::Type{T}, plt::AbstractPlot) wher const POTENTIAL_VECTOR_ARGUMENTS = [ :seriescolor, :seriesalpha, - :linecolor, - :linealpha, - :linewidth, - :linestyle, + :line_color, + :line_alpha, + :line_width, + :line_style, :line_z, :fillcolor, :fillalpha, :fill_z, - :markercolor, - :markeralpha, - :markershape, + :marker_color, + :marker_alpha, + :marker_shape, :marker_z, - :markerstrokecolor, - :markerstrokealpha, + :marker_stroke_color, + :marker_stroke_alpha, :xerror, :yerror, :zerror, @@ -221,7 +221,7 @@ make_steps(t::Tuple, st, even) = Tuple(make_steps(ti, st, even) for ti in t) plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :pre, false) # create a secondary series for the markers - if plotattributes[:markershape] !== :none + if plotattributes[:marker_shape] !== :none @series begin seriestype := :scatter x := x @@ -246,7 +246,7 @@ end plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post, true) # create a secondary series for the markers - if plotattributes[:markershape] !== :none + if plotattributes[:marker_shape] !== :none @series begin seriestype := :scatter x := x @@ -271,7 +271,7 @@ end plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post, false) # create a secondary series for the markers - if plotattributes[:markershape] !== :none + if plotattributes[:marker_shape] !== :none @series begin seriestype := :scatter x := x @@ -319,7 +319,7 @@ end fillrange := nothing seriestype := :path if ( - plotattributes[:linecolor] === :auto && + plotattributes[:line_color] === :auto && plotattributes[:marker_z] !== nothing && plotattributes[:line_z] === nothing ) @@ -327,7 +327,7 @@ end end # create a primary series for the markers - if plotattributes[:markershape] !== :none + if plotattributes[:marker_shape] !== :none primary := false @series begin seriestype := :scatter @@ -465,13 +465,14 @@ end # draw the bar shapes @series begin + # line_color --> :black seriestype := :shape series_annotations := nothing primary := true x := xseg.pts y := yseg.pts # expand attributes to match indices in new series data - for k in _segmenting_vector_attributes ∪ _segmenting_array_attributes + for k in _all_segmenting_attributes if (v = get(plotattributes, k, nothing)) isa AVec if eachindex(v) != eachindex(y) @warn "Indices $(eachindex(v)) of attribute `$k` do not match data indices $(eachindex(y))." @@ -677,7 +678,7 @@ end end # create a secondary series for the markers - if plotattributes[:markershape] !== :none + if plotattributes[:marker_shape] !== :none @series begin seriestype := :scatter x := _bin_centers(edge) @@ -960,7 +961,7 @@ end @recipe function f(::Type{Val{:scatter3d}}, x, y, z) # COV_EXCL_LINE seriestype := :path3d - if plotattributes[:markershape] === :none + if plotattributes[:marker_shape] === :none markershape := :circle end linewidth := 0 @@ -998,12 +999,12 @@ export lens! series_plotindex := backup[:series_plotindex] seriestype := :path primary := false - linecolor := get(backup, :linecolor, :lightgray) - if haskey(backup, :linestyle) - linestyle := backup[:linestyle] + linecolor := get(backup, :line_color, :lightgray) + if haskey(backup, :line_style) + linestyle := backup[:line_style] end - if haskey(backup, :linewidth) - linewidth := backup[:linewidth] + if haskey(backup, :line_width) + linewidth := backup[:line_width] end bbx_mag = (x1 + x2) / 2 bby_mag = (y1 + y2) / 2 @@ -1082,11 +1083,11 @@ end haskey(plotattributes, :marker_z) && reset_kw!(plotattributes, :marker_z) haskey(plotattributes, :line_z) && reset_kw!(plotattributes, :line_z) - msc = if (msc = plotattributes[:markerstrokecolor]) === :match + msc = if (msc = plotattributes[:marker_stroke_color]) === :match plotattributes[:subplot][:foreground_color_subplot] elseif msc === :auto get_series_color( - plotattributes[:linecolor], + plotattributes[:line_color], plotattributes[:subplot], plotattributes[:series_plotindex], plotattributes[:seriestype], @@ -1099,7 +1100,7 @@ end markerstrokecolor --> msc markercolor --> msc linecolor --> msc - linewidth --> plotattributes[:markerstrokewidth] + linewidth --> plotattributes[:marker_stroke_width] label --> "" end @@ -1355,7 +1356,7 @@ end seriestype --> :shape # For backwards compatibility, column vectors of segmenting attributes are # interpreted as having one element per shape - for attr in union(_segmenting_array_attributes, _segmenting_vector_attributes) + for attr in _all_segmenting_attributes v = get(plotattributes, attr, nothing) if v isa AVec || v isa AMat && size(v, 2) == 1 @warn """ diff --git a/src/shorthands.jl b/src/shorthands.jl index 09fa9fd2b..e6d9cd5a0 100644 --- a/src/shorthands.jl +++ b/src/shorthands.jl @@ -7,10 +7,10 @@ Make a scatter plot of `y` vs `x`. # Keyword arguments -- $(_document_argument(:markersize)) -- $(_document_argument(:markercolor)) -- $(_document_argument(:markershape)) -- $(_document_argument(:markeralpha)) +- $(_document_argument(:marker_size)) +- $(_document_argument(:marker_color)) +- $(_document_argument(:marker_shape)) +- $(_document_argument(:marker_alpha)) # Examples ```julia-repl @@ -180,7 +180,7 @@ Draw a stick plot of `y` vs `x`. # Arguments - $(_document_argument(:fillrange)) -- $(_document_argument(:markershape)) +- $(_document_argument(:marker_shape)) # Example ```julia-repl diff --git a/src/types.jl b/src/types.jl index 6dc6067e2..b75e39e54 100644 --- a/src/types.jl +++ b/src/types.jl @@ -38,7 +38,7 @@ mutable struct Subplot{T<:AbstractBackend} <: AbstractLayout DEFAULT_MINPAD[], DEFAULT_BBOX[], DEFAULT_BBOX[], - DefaultsDict(KW(), _subplot_defaults), + DefaultsDict(T, KW(), _subplot_defaults), nothing, nothing, ) @@ -76,7 +76,7 @@ mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T} new{typeof(be)}( be, 0, - DefaultsDict(KW(), _plot_defaults), + DefaultsDict(Plots.Plot{typeof(be)}, KW(), _plot_defaults), Series[], nothing, Subplot[], diff --git a/src/utils.jl b/src/utils.jl index 44017021d..fe4caf3f0 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -463,16 +463,16 @@ function contour_levels(series::Series, clims) levels end -for comp in (:line, :fill, :marker) +for comp in (:line_, :fill, :marker_) compcolor = string(comp, :color) get_compcolor = Symbol(:get_, compcolor) - comp_z = string(comp, :_z) + comp_z = string(comp, comp === :fill ? :_z : :z) compalpha = string(comp, :alpha) get_compalpha = Symbol(:get_, compalpha) @eval begin - # defines `get_linecolor`, `get_fillcolor` and `get_markercolor` <- for grep + # defines `get_line_color`, `get_fillcolor` and `get_marker_color` <- for grep function $get_compcolor( series, cmin::Real, @@ -480,7 +480,7 @@ for comp in (:line, :fill, :marker) i::Integer = 1, s::Symbol = :identity, ) - c = series[$Symbol($compcolor)] # series[:linecolor], series[:fillcolor], series[:markercolor] + c = series[$Symbol($compcolor)] # series[:line_color], series[:fillcolor], series[:marker_color] z = series[$Symbol($comp_z)] # series[:line_z], series[:fill_z], series[:marker_z] if z === nothing isa(c, ColorGradient) ? c : plot_color(_cycle(c, i)) @@ -514,11 +514,11 @@ function get_colorgradient(series::Series) if (st = series[:seriestype]) in (:surface, :heatmap) || isfilledcontour(series) series[:fillcolor] elseif st in (:contour, :wireframe, :contour3d) - series[:linecolor] + series[:line_color] elseif series[:marker_z] !== nothing - series[:markercolor] + series[:marker_color] elseif series[:line_z] !== nothing - series[:linecolor] + series[:line_color] elseif series[:fill_z] !== nothing series[:fillcolor] end @@ -531,35 +531,35 @@ get_gradient(c) = cgrad() get_gradient(cg::ColorGradient) = cg get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true) -get_linewidth(series, i::Integer = 1) = _cycle(series[:linewidth], i) -get_linestyle(series, i::Integer = 1) = _cycle(series[:linestyle], i) -get_fillstyle(series, i::Integer = 1) = _cycle(series[:fillstyle], i) +get_line_width(series, i::Int = 1) = _cycle(series[:line_width], i) +get_line_style(series, i::Int = 1) = _cycle(series[:line_style], i) +get_fillstyle(series, i::Int = 1) = _cycle(series[:fillstyle], i) -get_markerstrokecolor(series, i::Integer = 1) = - let msc = series[:markerstrokecolor] - msc isa ColorGradient ? msc : _cycle(msc, i) - end +function get_marker_stroke_color(series, i::Int = 1) + msc = series[:marker_stroke_color] + isa(msc, ColorGradient) ? msc : _cycle(msc, i) +end -get_markerstrokealpha(series, i::Integer = 1) = _cycle(series[:markerstrokealpha], i) -get_markerstrokewidth(series, i::Integer = 1) = _cycle(series[:markerstrokewidth], i) +get_marker_stroke_alpha(series, i::Int = 1) = _cycle(series[:marker_stroke_alpha], i) +get_marker_stroke_width(series, i::Int = 1) = _cycle(series[:marker_stroke_width], i) const _segmenting_vector_attributes = ( :seriescolor, :seriesalpha, - :linecolor, - :linealpha, - :linewidth, - :linestyle, + :line_color, + :line_alpha, + :line_width, + :line_style, :fillcolor, :fillalpha, :fillstyle, - :markercolor, - :markeralpha, - :markersize, - :markerstrokecolor, - :markerstrokealpha, - :markerstrokewidth, - :markershape, + :marker_color, + :marker_alpha, + :marker_size, + :marker_stroke_color, + :marker_stroke_alpha, + :marker_stroke_width, + :marker_shape, ) const _segmenting_array_attributes = :line_z, :fill_z, :marker_z diff --git a/test/test_args.jl b/test/test_args.jl index 4001d8289..157320613 100644 --- a/test/test_args.jl +++ b/test/test_args.jl @@ -1,3 +1,4 @@ +using Plots, Test struct Foo{T} x::Vector{T} y::Vector{T} @@ -15,16 +16,17 @@ x = collect(0.0:10.0) foo = Foo(x, sin.(x)) @testset "Magic attributes" begin - @test plot(foo)[1][1][:markershape] === :+ - @test plot(foo, markershape = :diamond)[1][1][:markershape] === :diamond - @test plot(foo, marker = :diamond)[1][1][:markershape] === :diamond + @test plot(foo)[1][1][:marker_shape] === :+ + @test plot(foo, markershape = :diamond)[1][1][:marker_shape] === :diamond + @test plot(foo, marker = :diamond)[1][1][:marker_shape] === :diamond @test (@test_logs (:warn, "Skipped marker arg diamond.") plot( foo, marker = :diamond, markershape = :diamond, - )[1][1][:markershape]) === :diamond + )[1][1][:marker_shape]) === :diamond end +using Plots, Test @testset "Subplot Attributes" begin let pl = plot(rand(4, 4), layout = 2) @test pl[1].primary_series_count == 2 @@ -60,6 +62,9 @@ end @test yticks(pl2) == xticks(pl1) @test filter(isfinite, pl1[1][1][:x]) == filter(isfinite, pl2[1][1][:y]) @test filter(isfinite, pl1[1][1][:y]) == filter(isfinite, pl2[1][1][:x]) + @test pl1[1][1][:line_color] == RGBA{Float64}(0.0, 0.0, 0.0, 1.0) + @test pl1[1][2][:marker_size] == 0 + @test pl1[1][2][:marker_alpha] == 0 end @testset "@add_attributes" begin @@ -77,8 +82,19 @@ end :legend_font_color, :legend_title_font_family, :legend_title_font_color, + ) :aliases = Dict( + :legend_position => (:legend, :leg, :key), + :legend_background_color => + (:background_legend, :background_colour_legend, :background_color_legend), + :legend_title => (:key_title, :label_title, :leg_title), ) - @test true + @test Plots._subplot_defaults[:legend_font_family] == :match + @test Plots._subplot_defaults[:legend_column] == 1 + @test Plots._keyAliases[:legend] == :legend_position + @test Plots._keyAliases[:legends] == :legend_position + @test Plots._keyAliases[:bgcolourlegend] == :legend_background_color + @test Plots._keyAliases[:bgcolour_legend] == :legend_background_color + @test Plots._keyAliases[:legendfontsize] == :legend_font_pointsize end @testset "aspect_ratio" begin diff --git a/test/test_axes.jl b/test/test_axes.jl index d06eabc5e..9442c0f16 100644 --- a/test/test_axes.jl +++ b/test/test_axes.jl @@ -1,3 +1,4 @@ +using Plots, Test @testset "Axes" begin pl = plot() axis = pl.subplots[1][:xaxis] @@ -151,7 +152,7 @@ end @testset "Axis-aliases" begin @test haskey(Plots._keyAliases, :xguideposition) @test haskey(Plots._keyAliases, :x_guide_position) - @test !haskey(Plots._keyAliases, :xguide_position) + @test haskey(Plots._keyAliases, :xguide_position) pl = plot(1:2, xl = "x label") @test pl[1][:xaxis][:guide] === "x label" pl = plot(1:2, xrange = (0, 3)) @@ -177,7 +178,7 @@ end end @testset "Aliases" begin - compare(pl::Plot, s::Symbol, val, op) = + compare(pl::Plots.Plot, s::Symbol, val, op) = op(pl[1][:xaxis][s], val) && op(pl[1][:yaxis][s], val) && op(pl[1][:zaxis][s], val) pl = plot(1:2, guide = "all labels") @test compare(pl, :guide, "all labels", ===) diff --git a/test/test_preferences.jl b/test/test_preferences.jl index 033087001..e09d25860 100644 --- a/test/test_preferences.jl +++ b/test/test_preferences.jl @@ -35,6 +35,8 @@ using Pkg, Test; io = (devnull, stdout)[1] # toggle for debugging Pkg.activate(; temp = true, io) Pkg.develop(; path = "$(escape_string(pkgdir(Plots)))", io) + Pkg.develop(; path = "$(escape_string(joinpath(pkgdir(Plots), "RecipesPipeline")))", io) + Pkg.develop(; path = "$(escape_string(joinpath(pkgdir(Plots), "RecipesBase")))", io) Pkg.add("UnicodePlots"; io) # checked by Plots using Plots res = @testset "Prefs" begin diff --git a/test/test_recipes.jl b/test/test_recipes.jl index 1079306dc..89a42b1d2 100644 --- a/test/test_recipes.jl +++ b/test/test_recipes.jl @@ -1,3 +1,4 @@ +using Plots, Test using OffsetArrays @testset "User recipes" begin @@ -101,9 +102,9 @@ with(:gr) do plot!(p, x, y; linestyle = :dash) yerror!(p, x, y; yerror, linestyle = :dot) @test length(p.series_list) == 3 - @test p[1][1][:linestyle] == :solid - @test p[1][2][:linestyle] == :dash - @test p[1][3][:linestyle] == :dot + @test p[1][1][:line_style] == :solid + @test p[1][2][:line_style] == :dash + @test p[1][3][:line_style] == :dot end @testset "parametric" begin