Skip to content

Commit

Permalink
Cache axis args in a dictionary (#3775)
Browse files Browse the repository at this point in the history
Co-authored-by: t-bltg <tf.bltg@gmail.com>
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
  • Loading branch information
3 people authored Aug 31, 2021
1 parent 1e44dd7 commit 70b635d
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 104 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version = "1.21.2"
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Contour = "d38c429a-6771-53c6-b99e-75d170b6e991"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
Expand All @@ -31,7 +32,6 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[compat]
Contour = "0.5"
Expand Down
88 changes: 49 additions & 39 deletions src/args.jl
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ function hasgrid(arg::Symbol, letter)
arg in (:all, :both, :on) || occursin(string(letter), string(arg))
else
@warn(
"Unknown grid argument $arg; $(Symbol(letter, :grid)) was set to `true` instead."
"Unknown grid argument $arg; $(get_attr_symbol(letter, :grid)) was set to `true` instead."
)
true
end
Expand Down Expand Up @@ -316,7 +316,7 @@ function showaxis(arg::Symbol, letter)
arg in (:all, :both, :on, :yes) || occursin(string(letter), string(arg))
else
@warn(
"Unknown showaxis argument $arg; $(Symbol(letter, :showaxis)) was set to `true` instead."
"Unknown showaxis argument $arg; $(get_attr_symbol(letter, :showaxis)) was set to `true` instead."
)
true
end
Expand Down Expand Up @@ -571,11 +571,6 @@ function reset_axis_defaults_byletter!()
end
reset_axis_defaults_byletter!()

for letter in (:x, :y, :z), k in keys(_axis_defaults)
# allow the underscore version too: xguide or x_guide
add_aliases(Symbol(letter, k), Symbol(letter, "_", k))
end

const _all_defaults = KW[_series_defaults, _plot_defaults, _subplot_defaults]

const _initial_defaults = deepcopy(_all_defaults)
Expand Down Expand Up @@ -620,6 +615,20 @@ const _all_subplot_args = sort(union([_subplot_args; _magic_subplot_args]))
const _all_series_args = sort(union([_series_args; _magic_series_args]))
const _all_plot_args = _plot_args

for letter in (:x, :y, :z)
_attrsymbolcache[letter] = Dict{Symbol, Symbol}()
for k in keys(_axis_defaults)
# populate attribute cache
lk = Symbol(letter, k)
_attrsymbolcache[letter][k] = lk
# allow the underscore version too: xguide or x_guide
add_aliases(lk, Symbol(letter, "_", k))
end
for k in (_magic_axis_args..., :(_discrete_indices))
_attrsymbolcache[letter][k] = Symbol(letter, k)
end
end

const _all_args =
sort(union([_all_axis_args; _all_subplot_args; _all_series_args; _all_plot_args]))

Expand Down Expand Up @@ -1216,69 +1225,69 @@ end

function processGridArg!(plotattributes::AKW, arg, letter)
if arg in _allGridArgs || isa(arg, Bool)
plotattributes[Symbol(letter, :grid)] = hasgrid(arg, letter)
plotattributes[get_attr_symbol(letter, :grid)] = hasgrid(arg, letter)

elseif allStyles(arg)
plotattributes[Symbol(letter, :gridstyle)] = arg
plotattributes[get_attr_symbol(letter, :gridstyle)] = arg

elseif typeof(arg) <: Stroke
arg.width === nothing ||
(plotattributes[Symbol(letter, :gridlinewidth)] = arg.width)
(plotattributes[get_attr_symbol(letter, :gridlinewidth)] = arg.width)
arg.color === nothing || (
plotattributes[Symbol(letter, :foreground_color_grid)] =
plotattributes[get_attr_symbol(letter, :foreground_color_grid)] =
arg.color in (:auto, :match) ? :match : plot_color(arg.color)
)
arg.alpha === nothing || (plotattributes[Symbol(letter, :gridalpha)] = arg.alpha)
arg.style === nothing || (plotattributes[Symbol(letter, :gridstyle)] = arg.style)
arg.alpha === nothing || (plotattributes[get_attr_symbol(letter, :gridalpha)] = arg.alpha)
arg.style === nothing || (plotattributes[get_attr_symbol(letter, :gridstyle)] = arg.style)

# linealpha
elseif allAlphas(arg)
plotattributes[Symbol(letter, :gridalpha)] = arg
plotattributes[get_attr_symbol(letter, :gridalpha)] = arg

# linewidth
elseif allReals(arg)
plotattributes[Symbol(letter, :gridlinewidth)] = arg
plotattributes[get_attr_symbol(letter, :gridlinewidth)] = arg

# color
elseif !handleColors!(plotattributes, arg, Symbol(letter, :foreground_color_grid))
elseif !handleColors!(plotattributes, arg, get_attr_symbol(letter, :foreground_color_grid))
@warn("Skipped grid arg $arg.")
end
end

function processMinorGridArg!(plotattributes::AKW, arg, letter)
if arg in _allGridArgs || isa(arg, Bool)
plotattributes[Symbol(letter, :minorgrid)] = hasgrid(arg, letter)
plotattributes[get_attr_symbol(letter, :minorgrid)] = hasgrid(arg, letter)

elseif allStyles(arg)
plotattributes[Symbol(letter, :minorgridstyle)] = arg
plotattributes[Symbol(letter, :minorgrid)] = true
plotattributes[get_attr_symbol(letter, :minorgridstyle)] = arg
plotattributes[get_attr_symbol(letter, :minorgrid)] = true

elseif typeof(arg) <: Stroke
arg.width === nothing ||
(plotattributes[Symbol(letter, :minorgridlinewidth)] = arg.width)
(plotattributes[get_attr_symbol(letter, :minorgridlinewidth)] = arg.width)
arg.color === nothing || (
plotattributes[Symbol(letter, :foreground_color_minor_grid)] =
plotattributes[get_attr_symbol(letter, :foreground_color_minor_grid)] =
arg.color in (:auto, :match) ? :match : plot_color(arg.color)
)
arg.alpha === nothing ||
(plotattributes[Symbol(letter, :minorgridalpha)] = arg.alpha)
(plotattributes[get_attr_symbol(letter, :minorgridalpha)] = arg.alpha)
arg.style === nothing ||
(plotattributes[Symbol(letter, :minorgridstyle)] = arg.style)
plotattributes[Symbol(letter, :minorgrid)] = true
(plotattributes[get_attr_symbol(letter, :minorgridstyle)] = arg.style)
plotattributes[get_attr_symbol(letter, :minorgrid)] = true

# linealpha
elseif allAlphas(arg)
plotattributes[Symbol(letter, :minorgridalpha)] = arg
plotattributes[Symbol(letter, :minorgrid)] = true
plotattributes[get_attr_symbol(letter, :minorgridalpha)] = arg
plotattributes[get_attr_symbol(letter, :minorgrid)] = true

# linewidth
elseif allReals(arg)
plotattributes[Symbol(letter, :minorgridlinewidth)] = arg
plotattributes[Symbol(letter, :minorgrid)] = true
plotattributes[get_attr_symbol(letter, :minorgridlinewidth)] = arg
plotattributes[get_attr_symbol(letter, :minorgrid)] = true

# color
elseif handleColors!(plotattributes, arg, Symbol(letter, :foreground_color_minor_grid))
plotattributes[Symbol(letter, :minorgrid)] = true
elseif handleColors!(plotattributes, arg, get_attr_symbol(letter, :foreground_color_minor_grid))
plotattributes[get_attr_symbol(letter, :minorgrid)] = true
else
@warn("Skipped grid arg $arg.")
end
Expand Down Expand Up @@ -1344,7 +1353,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end
# handle axis args
for letter in (:x, :y, :z)
asym = Symbol(letter, :axis)
asym = get_attr_symbol(letter, :axis)
args = RecipesPipeline.pop_kw!(plotattributes, asym, ())
if !(typeof(args) <: Axis)
for arg in wraptuple(args)
Expand All @@ -1371,7 +1380,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end
# handle individual axes grid args
for letter in (:x, :y, :z)
gridsym = Symbol(letter, :grid)
gridsym = get_attr_symbol(letter, :grid)
args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ())
for arg in wraptuple(args)
processGridArg!(plotattributes, arg, letter)
Expand All @@ -1386,7 +1395,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end
# handle individual axes grid args
for letter in (:x, :y, :z)
gridsym = Symbol(letter, :minorgrid)
gridsym = get_attr_symbol(letter, :minorgrid)
args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ())
for arg in wraptuple(args)
processMinorGridArg!(plotattributes, arg, letter)
Expand All @@ -1397,16 +1406,16 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
args = RecipesPipeline.pop_kw!(plotattributes, fontname, ())
for arg in wraptuple(args)
for letter in (:x, :y, :z)
processFontArg!(plotattributes, Symbol(letter, fontname), arg)
processFontArg!(plotattributes, get_attr_symbol(letter, fontname), arg)
end
end
end
# handle individual axes font args
for letter in (:x, :y, :z)
for fontname in (:tickfont, :guidefont)
args = RecipesPipeline.pop_kw!(plotattributes, Symbol(letter, fontname), ())
args = RecipesPipeline.pop_kw!(plotattributes, get_attr_symbol(letter, fontname), ())
for arg in wraptuple(args)
processFontArg!(plotattributes, Symbol(letter, fontname), arg)
processFontArg!(plotattributes, get_attr_symbol(letter, fontname), arg)
end
end
end
Expand All @@ -1415,7 +1424,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
if haskey(plotattributes, k) && k !== :link
v = plotattributes[k]
for letter in (:x, :y, :z)
lk = Symbol(letter, k)
lk = get_attr_symbol(letter, k)
if !is_explicit(plotattributes, lk)
plotattributes[lk] = v
end
Expand Down Expand Up @@ -1922,7 +1931,8 @@ function _update_axis(
end

# then get those args that were passed with a leading letter: `xlabel = "X"`
lk = Symbol(letter, k)
lk = get_attr_symbol(letter, k)

if haskey(plotattributes_in, lk)
kw[k] = slice_arg(plotattributes_in[lk], subplot_index)
end
Expand Down Expand Up @@ -1979,7 +1989,7 @@ function _update_subplot_args(
lims_warned = false
for letter in (:x, :y, :z)
_update_axis(plt, sp, plotattributes_in, letter, subplot_index)
lk = Symbol(letter, :lims)
lk = get_attr_symbol(letter, :lims)

# warn against using `Range` in x,y,z lims
if !lims_warned &&
Expand Down
54 changes: 27 additions & 27 deletions src/axes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function Axis(sp::Subplot, letter::Symbol, args...; kw...)
end

function get_axis(sp::Subplot, letter::Symbol)
axissym = Symbol(letter, :axis)
axissym = get_attr_symbol(letter, :axis)
if haskey(sp.attr, axissym)
sp.attr[axissym]
else
Expand All @@ -35,40 +35,40 @@ function process_axis_arg!(plotattributes::AKW, arg, letter = "")
T = typeof(arg)
arg = get(_scaleAliases, arg, arg)
if typeof(arg) <: Font
plotattributes[Symbol(letter, :tickfont)] = arg
plotattributes[Symbol(letter, :guidefont)] = arg
plotattributes[get_attr_symbol(letter, :tickfont)] = arg
plotattributes[get_attr_symbol(letter, :guidefont)] = arg

elseif arg in _allScales
plotattributes[Symbol(letter, :scale)] = arg
plotattributes[get_attr_symbol(letter, :scale)] = arg

elseif arg in (:flip, :invert, :inverted)
plotattributes[Symbol(letter, :flip)] = true
plotattributes[get_attr_symbol(letter, :flip)] = true

elseif T <: AbstractString
plotattributes[Symbol(letter, :guide)] = arg
plotattributes[get_attr_symbol(letter, :guide)] = arg

# xlims/ylims
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
sym = typeof(arg[1]) <: Number ? :lims : :ticks
plotattributes[Symbol(letter, sym)] = arg
plotattributes[get_attr_symbol(letter, sym)] = arg

# xticks/yticks
elseif T <: AVec
plotattributes[Symbol(letter, :ticks)] = arg
plotattributes[get_attr_symbol(letter, :ticks)] = arg

elseif arg === nothing
plotattributes[Symbol(letter, :ticks)] = []
plotattributes[get_attr_symbol(letter, :ticks)] = []

elseif T <: Bool || arg in _allShowaxisArgs
plotattributes[Symbol(letter, :showaxis)] = showaxis(arg, letter)
plotattributes[get_attr_symbol(letter, :showaxis)] = showaxis(arg, letter)

elseif typeof(arg) <: Number
plotattributes[Symbol(letter, :rotation)] = arg
plotattributes[get_attr_symbol(letter, :rotation)] = arg

elseif typeof(arg) <: Function
plotattributes[Symbol(letter, :formatter)] = arg
plotattributes[get_attr_symbol(letter, :formatter)] = arg

elseif !handleColors!(plotattributes, arg, Symbol(letter, :foreground_color_axis))
elseif !handleColors!(plotattributes, arg, get_attr_symbol(letter, :foreground_color_axis))
@warn("Skipped $(letter)axis arg $arg")
end
end
Expand Down Expand Up @@ -297,7 +297,7 @@ for l in (:x, :y, :z)
end
end
# get_ticks from axis symbol :x, :y, or :z
get_ticks(sp::Subplot, s::Symbol) = get_ticks(sp, sp[Symbol(s, :axis)])
get_ticks(sp::Subplot, s::Symbol) = get_ticks(sp, sp[get_attr_symbol(s, :axis)])
get_ticks(p::Plot, s::Symbol) = [get_ticks(sp, s) for sp in p.subplots]

function get_ticks(ticks::Symbol, cvals::T, dvals, args...) where {T}
Expand Down Expand Up @@ -393,7 +393,7 @@ end

function reset_extrema!(sp::Subplot)
for asym in (:x, :y, :z)
sp[Symbol(asym, :axis)][:extrema] = Extrema()
sp[get_attr_symbol(asym, :axis)][:extrema] = Extrema()
end
for series in sp.series_list
expand_extrema!(sp, series.plotattributes)
Expand Down Expand Up @@ -446,7 +446,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
)
data = [NaN]
end
axis = sp[Symbol(letter, "axis")]
axis = sp[get_attr_symbol(letter, :axis)]

if isa(data, Volume)
expand_extrema!(sp[:xaxis], data.x_extents)
Expand All @@ -463,7 +463,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
# TODO: need more here... gotta track the discrete reference value
# as well as any coord offset (think of boxplot shape coords... they all
# correspond to the same x-value)
plotattributes[letter], plotattributes[Symbol(letter, "_discrete_indices")] =
plotattributes[letter], plotattributes[get_attr_symbol(letter, :(_discrete_indices))] =
discrete_value!(axis, data)
expand_extrema!(axis, plotattributes[letter])
end
Expand Down Expand Up @@ -502,7 +502,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
plotattributes[:bar_width] =
_bar_width * ignorenan_minimum(filter(x -> x > 0, diff(sort(data))))
end
axis = sp.attr[Symbol(dsym, :axis)]
axis = sp.attr[get_attr_symbol(dsym, :axis)]
expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw))
expand_extrema!(axis, ignorenan_minimum(data) - 0.5minimum(bw))
end
Expand All @@ -511,8 +511,8 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
if plotattributes[:seriestype] == :heatmap
for letter in (:x, :y)
data = plotattributes[letter]
axis = sp[Symbol(letter, "axis")]
scale = get(plotattributes, Symbol(letter, "scale"), :identity)
axis = sp[get_attr_symbol(letter, :axis)]
scale = get(plotattributes, get_attr_symbol(letter, :scale), :identity)
expand_extrema!(axis, heatmap_edges(data, scale))
end
end
Expand Down Expand Up @@ -586,10 +586,10 @@ end
function axis_limits(
sp,
letter,
should_widen = default_should_widen(sp[Symbol(letter, :axis)]),
should_widen = default_should_widen(sp[get_attr_symbol(letter, :axis)]),
consider_aspect = true,
)
axis = sp[Symbol(letter, :axis)]
axis = sp[get_attr_symbol(letter, :axis)]
ex = axis[:extrema]
amin, amax = ex.emin, ex.emax
lims = axis[:lims]
Expand Down Expand Up @@ -724,10 +724,10 @@ end
# compute the line segments which should be drawn for this axis
function axis_drawing_info(sp, letter)
# find out which axis we are dealing with
asym = Symbol(letter, :axis)
asym = get_attr_symbol(letter, :axis)
isy = letter === :y
oletter = isy ? :x : :y
oasym = Symbol(oletter, :axis)
oasym = get_attr_symbol(oletter, :axis)

# get axis objects, ticks and minor ticks
ax, oax = sp[asym], sp[oasym]
Expand Down Expand Up @@ -856,9 +856,9 @@ function axis_drawing_info_3d(sp, letter)
near_letter = letter in (:x, :z) ? :y : :x
far_letter = letter in (:x, :y) ? :z : :x

ax = sp[Symbol(letter, :axis)]
nax = sp[Symbol(near_letter, :axis)]
fax = sp[Symbol(far_letter, :axis)]
ax = sp[get_attr_symbol(letter, :axis)]
nax = sp[get_attr_symbol(near_letter, :axis)]
fax = sp[get_attr_symbol(far_letter, :axis)]

amin, amax = axis_limits(sp, letter)
namin, namax = axis_limits(sp, near_letter)
Expand Down
Loading

0 comments on commit 70b635d

Please sign in to comment.