diff --git a/src/args.jl b/src/args.jl index 390ba5f1..e2586610 100644 --- a/src/args.jl +++ b/src/args.jl @@ -417,6 +417,7 @@ const _all_defaults = KW[ ] const _initial_defaults = deepcopy(_all_defaults) +const _initial_axis_defaults = deepcopy(_axis_defaults) # to be able to reset font sizes to initial values const _initial_fontsizes = Dict(:titlefontsize => _subplot_defaults[:titlefontsize], @@ -616,7 +617,10 @@ function default(d::KW, k::Symbol) get(d, k, default(k)) end -reset_defaults() = foreach(merge!, _all_defaults, _initial_defaults) +function reset_defaults() + foreach(merge!, _all_defaults, _initial_defaults) + merge!(_axis_defaults, _initial_axis_defaults) +end # ----------------------------------------------------------------------------- diff --git a/src/themes.jl b/src/themes.jl index 840078dd..adf9df24 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -4,43 +4,166 @@ Specify the colour theme for plots. """ function theme(s::Symbol; kw...) - # reset? - if s == :none || s == :default - PlotUtils.clibrary(:Plots) - PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) - default(; - bg = :white, - bglegend = :match, - bginside = :match, - bgoutside = :match, - fg = :auto, - fglegend = :match, - fggrid = :match, - fgaxis = :match, - fgtext = :match, - fgborder = :match, - fgguide = :match, - palette = :auto - ) - return - end + defaults = _get_defaults(s) + _theme(s, defaults; kw...) +end - # update the default gradient and other defaults +function _get_defaults(s::Symbol) thm = PlotThemes._themes[s] - if thm.gradient != nothing + if :defaults in fieldnames(thm) + return thm.defaults + else # old PlotTheme type + defaults = KW( + :bg => thm.bg_secondary, + :bginside => thm.bg_primary, + :fg => thm.lines, + :fgtext => thm.text, + :fgguide => thm.text, + :fglegend => thm.text, + :palette => thm.palette, + ) + if thm.gradient != nothing + push!(defaults, :gradient => thm.gradient) + end + return defaults + end +end + +function _theme(s::Symbol, defaults::KW; kw...) + # Reset to defaults to overwrite active theme + reset_defaults() + + # Set the theme's gradient as default + if haskey(defaults, :gradient) PlotUtils.clibrary(:misc) PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) + else + PlotUtils.clibrary(:Plots) + PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) end - default(; - bg = thm.bg_secondary, - bginside = thm.bg_primary, - fg = thm.lines, - fgtext = thm.text, - fgguide = thm.text, - fglegend = thm.text, - palette = thm.palette, - kw... - ) + + # maybe overwrite the theme's gradient + kw = KW(kw) + if haskey(kw, :gradient) + kwgrad = pop!(kw, :gradient) + for clib in clibraries() + if kwgrad in cgradients(clib) + PlotUtils.clibrary(clib) + PlotUtils.default_cgrad(default = :sequential, sequential = kwgrad) + break + end + end + end + + # Set the theme's defaults + default(; defaults..., kw...) + return end @deprecate set_theme(s) theme(s) + +@userplot ShowTheme + +_color_functions = KW( + :protanopic => protanopic, + :deuteranopic => deuteranopic, + :tritanopic => tritanopic, +) +_get_showtheme_args(thm::Symbol) = thm, identity +_get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func, identity) + +@recipe function showtheme(st::ShowTheme) + thm, cfunc = _get_showtheme_args(st.args...) + defaults = _get_defaults(thm) + + # get the gradient + gradient_colors = pop!(defaults, :gradient, cgrad(:inferno).colors) + gradient = cgrad(cfunc.(RGB.(gradient_colors))) + + # get the palette + palette = pop!(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17)) + palette = cfunc.(RGB.(palette)) + + # apply the theme + for k in keys(defaults) + def = defaults[k] + arg = get(_keyAliases, k, k) + plotattributes[arg] = if typeof(def) <: Colorant + cfunc(RGB(def)) + elseif eltype(def) <: Colorant + cfunc.(RGB.(def)) + elseif contains(string(arg), "color") + cfunc.(RGB.(plot_color.(def))) + else + def + end + end + + srand(1) + + label := "" + colorbar := false + layout := (2, 3) + + for j in 1:4 + @series begin + subplot := 1 + palette := palette + seriestype := :path + linewidth := 2 + cumsum(randn(50)) + end + + @series begin + subplot := 2 + seriestype := :scatter + palette := palette + markersize := 5 + markerstrokewidth := 0 + marker := (:circle, :diamond, :star5, :square)[j] + randn(10), randn(10) + end + end + + @series begin + subplot := 3 + seriestype := :histogram + palette := palette + randn(1000) .+ (0:2:4)' + end + + f(r) = sin(r) / r + _norm(x, y) = norm([x, y]) + x = y = linspace(-3π, 3π, 30) + z = f.(_norm.(x, y')) + wi = 2:3:30 + + @series begin + subplot := 4 + seriestype := :heatmap + seriescolor := gradient + x, y, z + end + + @series begin + subplot := 5 + seriestype := :surface + seriescolor := gradient + x, y, z + end + + n = 100 + ts = linspace(0, 10π, n) + x = ts .* cos.(ts) + y = (0.1ts) .* sin.(ts) + z = 1:n + + @series begin + subplot := 6 + seriescolor := gradient + linewidth := 3 + line_z := z + x, y, z + end + +end