From 66d2e4746aecb4f5ee1f1379fdf6e6e4e807b0d2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 10 Apr 2020 13:04:38 +0200 Subject: [PATCH] implement ColorSchemes integration in PlotUtils --- src/Plots.jl | 4 ++-- src/args.jl | 14 +++++--------- src/backends/gr.jl | 21 ++++++++------------- src/backends/pgfplotsx.jl | 4 ++-- src/themes.jl | 28 +++++++++------------------- src/utils.jl | 26 +++++++++++++++++++++----- test/test_pgfplotsx.jl | 6 +++--- 7 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 7ec451f1..b849e609 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -245,7 +245,7 @@ end const CURRENT_BACKEND = CurrentBackend(:none) -include("precompile.jl") -_precompile_() +# include("precompile.jl") +# _precompile_() end # module diff --git a/src/args.jl b/src/args.jl index bca85309..47574cd0 100644 --- a/src/args.jl +++ b/src/args.jl @@ -481,10 +481,7 @@ is_default_attribute(k) = k in _internal_args || k in _all_args || is_axis_attr_ makeplural(s::Symbol) = Symbol(string(s,"s")) -autopick(arr::AVec, idx::Integer) = arr[mod1(idx,length(arr))] -autopick(notarr, idx::Integer) = notarr - -autopick_ignore_none_auto(arr::AVec, idx::Integer) = autopick(setdiff(arr, [:none, :auto]), idx) +autopick_ignore_none_auto(arr::AVec, idx::Integer) = _cycle(setdiff(arr, [:none, :auto]), idx) autopick_ignore_none_auto(notarr, idx::Integer) = notarr function aliasesAndAutopick(plotattributes::AKW, sym::Symbol, aliases::Dict{Symbol,Symbol}, options::AVec, plotIndex::Int) @@ -1410,8 +1407,7 @@ end function _update_subplot_colors(sp::Subplot) # background colors color_or_nothing!(sp.attr, :background_color_subplot) - bg = plot_color(sp[:background_color_subplot]) - sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], bg, 30) + sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], 30) color_or_nothing!(sp.attr, :background_color_legend) color_or_nothing!(sp.attr, :background_color_inside) @@ -1514,9 +1510,9 @@ end # and assigns a color automatically function get_series_color(c, sp::Subplot, n::Int, seriestype) if c == :auto - c = like_surface(seriestype) ? cgrad() : autopick(sp[:color_palette], n) + c = like_surface(seriestype) ? cgrad() : _cycle(sp[:color_palette], n) elseif isa(c, Int) - c = autopick(sp[:color_palette], c) + c = _cycle(sp[:color_palette], c) end plot_color(c) end @@ -1526,7 +1522,7 @@ function get_series_color(c::AbstractArray, sp::Subplot, n::Int, seriestype) end function ensure_gradient!(plotattributes::AKW, csym::Symbol, asym::Symbol) - if !isa(plotattributes[csym], ColorGradient) + if typeof(plotattributes[csym]) ∉ (ColorGradient, ColorPalette) plotattributes[csym] = typeof(plotattributes[asym]) <: AbstractVector ? cgrad() : cgrad(alpha = plotattributes[asym]) end end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 5dfe6013..d7e93a0c 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1661,34 +1661,29 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :heatmap zmin, zmax = clims + fillgrad = _as_gradient(series[:fillcolor]) + colors = plot_color.(nan_get(fillgrad, z, clims), series[:fillalpha]) + rgba = gr_color.(colors) if !ispolar(sp) - GR.setspace(zmin, zmax, 0, 90) + GR.setspace(clims..., 0, 90) x, y = heatmap_edges(series[:x], sp[:xaxis][:scale], series[:y], sp[:yaxis][:scale], size(series[:z])) w, h = length(x) - 1, length(y) - 1 - z_normalized = map(x -> GR.jlgr.normalize_color(x, zmin, zmax), z) if is_uniformly_spaced(x) && is_uniformly_spaced(y) # For uniformly spaced data use GR.drawimage, which can be # much faster than GR.nonuniformcellarray, especially for # pdf output, and also supports alpha values. # Note that drawimage draws uniformly spaced data correctly # even on log scales, where it is visually non-uniform. - fillgrad = _as_gradient(series[:fillcolor]) - colors = plot_color.(fillgrad[z_normalized], series[:fillalpha]) - colors[isnan.(z_normalized)] .= RGBA(0,0,0,0) - rgba = gr_color.(colors) GR.drawimage(first(x), last(x), last(y), first(y), w, h, rgba) else - (something(series[:fillalpha],1) < 1 || any(_gr_gradient_alpha .< 1)) && @warn( - "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored.") - z_normalized = map(x -> isnan(x) ? 256/255 : x, z_normalized) # results in color index = 1256 -> transparent - colors = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized] - GR.nonuniformcellarray(x, y, w, h, colors) + if something(series[:fillalpha],1) < 1 || any(_gr_gradient_alpha .< 1) + @warn "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored." + end + GR.nonuniformcellarray(x, y, w, h, rgba) end else phimin, phimax = 0.0, 360.0 # nonuniform polar array is not yet supported in GR.jl nx, ny = length(series[:x]), length(series[:y]) - z_normalized = map(x -> GR.jlgr.normalize_color(x, zmin, zmax), z) - colors = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized] xmin, xmax, ymin, ymax = xy_lims rmax = data_lims[4] GR.setwindow(-rmax, rmax, -rmax, rmax) diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index b6864402..ac80ce2c 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -677,8 +677,8 @@ function pgfx_filllegend!(series_opt, opt) }""") end -function pgfx_colormap(grad::ColorGradient) - join(map(grad.colors) do c +function pgfx_colormap(grad::Union{ColorGradient, ColorPalette}) + join(map(color_list(grad)) do c @sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c), blue(c)) end, "\n") end diff --git a/src/themes.jl b/src/themes.jl index 3b812ee8..bb1489f9 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -14,25 +14,15 @@ function _theme(s::Symbol, defaults::AKW; kw...) # Set the theme's gradient as default if haskey(defaults, :colorgradient) - PlotUtils.clibrary(:misc) - PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) - pop!(defaults, :colorgradient) + PlotUtils.default_cgrad(pop!(defaults, :colorgradient)) else - PlotUtils.clibrary(:Plots) - PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) + PlotUtils.default_cgrad(:default) end # maybe overwrite the theme's gradient kw = KW(kw) if haskey(kw, :colorgradient) - kwgrad = pop!(kw, :colorgradient) - for clib in clibraries() - if kwgrad in cgradients(clib) - PlotUtils.clibrary(clib) - PlotUtils.default_cgrad(default = :sequential, sequential = kwgrad) - break - end - end + PlotUtils.default_cgrad(pop!(kw, :colorgradient)) end # Set the theme's defaults @@ -57,12 +47,12 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func defaults = PlotThemes._themes[thm].defaults # get the gradient - gradient_colors = get(defaults, :colorgradient, cgrad(:inferno).colors) + gradient_colors = color_list(cgrad(get(defaults, :colorgradient, :default))) colorgradient = cgrad(cfunc.(RGB.(gradient_colors))) # get the palette - palette = get(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17)) - palette = cfunc.(RGB.(palette)) + cp = color_list(palette(get(defaults, :palette, :default))) + cp = cfunc.(RGB.(cp)) # apply the theme for k in keys(defaults) @@ -89,7 +79,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func for j in 1:4 @series begin subplot := 1 - palette := palette + color_palette := cp seriestype := :path cumsum(randn(50)) end @@ -97,7 +87,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func @series begin subplot := 2 seriestype := :scatter - palette := palette + color_palette := cp marker := (:circle, :diamond, :star5, :square)[j] randn(10), randn(10) end @@ -106,7 +96,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func @series begin subplot := 3 seriestype := :histogram - palette := palette + color_palette := cp randn(1000) .+ (0:2:4)' end diff --git a/src/utils.jl b/src/utils.jl index 481def0f..59386f86 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -130,10 +130,12 @@ _cycle(v::AVec, indices::AVec{Int}) = map(i -> _cycle(v,i), indices) _cycle(v::AMat, indices::AVec{Int}) = map(i -> _cycle(v,i), indices) _cycle(v, indices::AVec{Int}) = fill(v, length(indices)) -_cycle(grad::ColorGradient, idx::Int) = _cycle(grad.colors, idx) -_cycle(grad::ColorGradient, indices::AVec{Int}) = _cycle(grad.colors, indices) +_cycle(cg::ColorGradient, idx::Int) = cg[mod1(idx, end)] +_cycle(cg::ColorGradient, idx::AVec{Int}) = cg[mod1.(idx, end)] +_cycle(cp::ColorPalette, idx::Int) = cp[mod1(idx, end)] +_cycle(cp::ColorPalette, idx::AVec{Int}) = cp[mod1.(idx, end)] -_as_gradient(grad::ColorGradient) = grad +_as_gradient(grad) = grad _as_gradient(c::Colorant) = ColorGradient([c,c]) makevec(v::AVec) = v @@ -521,8 +523,7 @@ for comp in (:line, :fill, :marker) if z === nothing isa(c, ColorGradient) ? c : plot_color(_cycle(c, i)) else - grad = isa(c, ColorGradient) ? c : cgrad() - grad[clamp((_cycle(z, i) - cmin) / (cmax - cmin), 0, 1)] + nan_get(get_gradient(c), z[i], (cmin, cmax)) end end @@ -543,6 +544,21 @@ end single_color(c, v = 0.5) = c single_color(grad::ColorGradient, v = 0.5) = grad[v] +get_gradient(c) = cgrad() +get_gradient(cg::ColorGradient) = cg +get_gradient(cp::ColorPalette) = cp + +nan_get(cs, x, range) = isfinite(x) ? plot_color(get(cs, x, range)) : invisible() +function nan_get(cs, v::AbstractVector, range) + colors = fill(invisible(), length(v)) + for (i, x) in enumerate(v) + if isfinite(x) + colors[i] = get(cs, x, range) + end + end + return colors +end + function get_linewidth(series, i::Int = 1) _cycle(series[:linewidth], i) end diff --git a/test/test_pgfplotsx.jl b/test/test_pgfplotsx.jl index 162e6d3b..a21ed191 100644 --- a/test/test_pgfplotsx.jl +++ b/test/test_pgfplotsx.jl @@ -71,7 +71,7 @@ end pl = scatter!( y, zcolor = abs.(y .- 0.5), - m = (:heat, 0.8, Plots.stroke(1, :green)), + m = (:hot, 0.8, Plots.stroke(1, :green)), ms = 10 * abs.(y .- 0.5) .+ 4, lab = ["grad", "", "ient"], ) @@ -122,7 +122,7 @@ end plot( Plots.fakedata(100, 10), layout = 4, - palette = [:grays :blues :heat :lightrainbow], + palette = [:grays :blues :hot :rainbow], bg_inside = [:orange :pink :darkblue :black], ) end # testset @@ -211,7 +211,7 @@ end marker_z = ((x, y) -> begin x + y end), - color = :bluesreds, + color = :bwr, legend = false, ) plot(p1, p2)