Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add permute, deprecate orientation #4164

Merged
merged 16 commits into from
May 5, 2022
Merged
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.28.2"
version = "1.29.0"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
3 changes: 2 additions & 1 deletion src/arg_desc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ const _arg_desc = KW(
:line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. 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 => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.",
:levels => "Integer (number of contours) or AbstractVector (contour values). Determines contour levels for a contour type.",
:orientation => "Symbol. 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).",
:permute => "Tuple{Symbol,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 not be implemented fully)",
:bar_width => "nothing or Number. 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)?",
Expand Down
16 changes: 12 additions & 4 deletions src/args.jl
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ const _series_defaults = KW(
:stride => (1, 1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride.
:connections => nothing, # tuple of arrays to specifiy connectivity of a 3d mesh
:z_order => :front, # one of :front, :back or integer in 1:length(sp.series_list)
:permute => :none, # tuple of two symbols to be permuted
:extra_kwargs => Dict(),
)

Expand Down Expand Up @@ -1611,7 +1612,7 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes)
already_warned = get!(_already_warned, bend, Set{Symbol}())
extra_kwargs = Dict{Symbol,Any}()
for k in keys(plotattributes)
is_attr_supported(pkg, k) && continue
is_attr_supported(pkg, k) && !(k in keys(_deprecated_attributes)) && continue
k in _suppress_warnings && continue
default_value = default(k)
if ismissing(default_value)
Expand All @@ -1625,9 +1626,16 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes)
get(plotattributes, :warn_on_unsupported, should_warn_on_unsupported(pkg))
for k in sort(collect(_to_warn))
push!(already_warned, k)
@warn(
"Keyword argument $k not supported with $pkg. Choose from: $(join(supported_attrs(pkg), ", "))"
)
if k in keys(_deprecated_attributes)
@warn("""
Keyword argument `$k` is deprecated.
Please use `$(_deprecated_attributes[k])` instead.
""")
else
@warn(
"Keyword argument $k not supported with $pkg. Choose from: $(join(supported_attrs(pkg), ", "))"
)
end
end
end
return extra_kwargs
Expand Down
9 changes: 9 additions & 0 deletions src/axes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,15 @@ end
# these methods track the discrete (categorical) values which correspond to axis continuous values (cv)
# whenever we have discrete values, we automatically set the ticks to match.
# we return (continuous_value, discrete_index)
function discrete_value!(plotattributes, letter::Symbol, dv)
l = if plotattributes[:permute] !== :none
only(filter(!=(letter), plotattributes[:permute]))
else
letter
end
discrete_value!(plotattributes[:subplot][get_attr_symbol(l, :axis)], dv)
end

function discrete_value!(axis::Axis, dv)
cv_idx = get(axis[:discrete_map], dv, -1)
if cv_idx == -1
Expand Down
2 changes: 2 additions & 0 deletions src/backends.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ const _base_supported_args = [
:projection,
:show_empty_bins,
:z_order,
:permute,
]

function merge_with_base_supported(v::AVec)
Expand Down Expand Up @@ -949,6 +950,7 @@ const _unicodeplots_seriestype = [
:heatmap,
:contour,
# :contour3d,
:permute,
:spy,
:surface,
:wireframe,
Expand Down
1 change: 1 addition & 0 deletions src/consts.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

const _deprecated_attributes = Dict{Symbol,Symbol}(:orientation => :permute)
const _all_defaults = KW[_series_defaults, _plot_defaults, _subplot_defaults]

const _initial_defaults = deepcopy(_all_defaults)
Expand Down
24 changes: 24 additions & 0 deletions src/pipeline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ end
function _preprocess_userrecipe(kw::AKW)
_add_markershape(kw)

if get(kw, :permute, default(:permute)) != :none
l1, l2 = kw[:permute]
for k in _axis_args
k1 = _attrsymbolcache[l1][k]
k2 = _attrsymbolcache[l2][k]
kwk = keys(kw)
if k1 in kwk || k2 in kwk
kw[k1], kw[k2] = get(kw, k2, default(k2)), get(kw, k1, default(k1))
end
end
end
# map marker_z if it's a Function
if isa(get(kw, :marker_z, default(:marker_z)), Function)
# TODO: should this take y and/or z as arguments?
Expand Down Expand Up @@ -338,6 +349,19 @@ RecipesPipeline.is_seriestype_supported(plt::Plot, st) = is_seriestype_supported

function RecipesPipeline.add_series!(plt::Plot, plotattributes)
sp = _prepare_subplot(plt, plotattributes)
if plotattributes[:permute] != :none
letter1, letter2 = plotattributes[:permute]
if plotattributes[:markershape] == :hline &&
(plotattributes[:permute] == (:x, :y) || plotattributes[:permute] == (:y, :x))
plotattributes[:markershape] = :vline
elseif plotattributes[:markershape] == :vline && (
plotattributes[:permute] == (:x, :y) || plotattributes[:permute] == (:y, :x)
)
plotattributes[:markershape] = :hline
end
plotattributes[letter1], plotattributes[letter2] =
plotattributes[letter2], plotattributes[letter1]
end
_expand_subplot_extrema(sp, plotattributes, plotattributes[:seriestype])
_update_series_attributes!(plotattributes, plt, sp)
_add_the_series(plt, sp, plotattributes)
Expand Down
2 changes: 1 addition & 1 deletion src/recipes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ end
procx, procy, xscale, yscale, baseline = _preprocess_barlike(plotattributes, x, y)
nx, ny = length(procx), length(procy)
axis = plotattributes[:subplot][isvertical(plotattributes) ? :xaxis : :yaxis]
cv = [discrete_value!(axis, xi)[1] for xi in procx]
cv = [discrete_value!(plotattributes, :x, xi)[1] for xi in procx]
procx = if nx == ny
cv
elseif nx == ny + 1
Expand Down
9 changes: 9 additions & 0 deletions test/test_args.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@ end
@test pl[1][axis][:tickfontfamily] == "Times"
end
end

@testset "Permute recipes" begin
pl = bar(["a", "b", "c"], [1, 2, 3])
ppl = bar(["a", "b", "c"], [1, 2, 3], permute = (:x, :y))
@test xticks(ppl) == yticks(pl)
@test yticks(ppl) == xticks(pl)
@test filter(isfinite, pl[1][1][:x]) == filter(isfinite, ppl[1][1][:y])
@test filter(isfinite, pl[1][1][:y]) == filter(isfinite, ppl[1][1][:x])
end