diff --git a/Project.toml b/Project.toml index 00ffc174..727fdaaf 100644 --- a/Project.toml +++ b/Project.toml @@ -33,7 +33,7 @@ StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" [compat] -ColorSchemes = "3.6" +ColorSchemes = "3.7" Contour = "0.5" FFMPEG = "0.2, 0.3" FixedPointNumbers = "0.6, 0.7, 0.8" @@ -43,10 +43,10 @@ JSON = "0.21" Measures = "0.3" NaNMath = "0.3" PGFPlotsX = "1.2.0" -PlotThemes = "1" -PlotUtils = "0.6.5" +PlotThemes = "2" +PlotUtils = "0.7" RecipesBase = "1" -RecipesPipeline = "0.1.1" +RecipesPipeline = "0.1.3" Reexport = "0.2" Requires = "0.5, 1" Showoff = "0.3.1" diff --git a/src/args.jl b/src/args.jl index 47574cd0..88b1638c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1522,7 +1522,13 @@ function get_series_color(c::AbstractArray, sp::Subplot, n::Int, seriestype) end function ensure_gradient!(plotattributes::AKW, csym::Symbol, asym::Symbol) - if typeof(plotattributes[csym]) ∉ (ColorGradient, ColorPalette) + if plotattributes[csym] isa ColorPalette + α = nothing + if !(plotattributes[asym] isa AbstractVector) + α = plotattributes[asym] + end + plotattributes[csym] = cgrad(plotattributes[csym], categorical = true, alpha = α) + elseif !(plotattributes[csym] isa ColorGradient) 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 0af5fc06..04166e3f 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1333,7 +1333,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end xticks, yticks, xspine_segs, yspine_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xminorgrid_segs, yminorgrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp) - # @show xticks yticks #spine_segs grid_segs # draw the grid lines if xaxis[:grid] @@ -1661,14 +1660,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # 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. - colors = plot_color.(nan_get(fillgrad, z, clims), series[:fillalpha]) + colors = plot_color.(get(fillgrad, z, clims), series[:fillalpha]) rgba = gr_color.(colors) GR.drawimage(first(x), last(x), last(y), first(y), w, h, rgba) else if something(series[:fillalpha],1) < 1 || any(_gr_gradient_alpha .< 1) @warn "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored." end - colors = nan_get(fillgrad, z, clims) + colors = get(fillgrad, z, clims) z_normalized = map(c -> c == invisible() ? 256/255 : getinverse(fillgrad, c), colors) rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized] GR.nonuniformcellarray(x, y, w, h, rgba) @@ -1685,7 +1684,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if series[:y][end] != ny @warn "Right now only the maximum value of y (r) is taken into account." end - colors = nan_get(fillgrad, z, clims) + colors = get(fillgrad, z, clims) z_normalized = map(c -> c == invisible() ? 256/255 : getinverse(fillgrad.colors, c), colors) rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized] # GR.polarcellarray(0, 0, phimin, phimax, ymin, ymax, nx, ny, colors) diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index 24ac5080..ca6f1d61 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -214,7 +214,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend}) "colorbar" => nothing, "colormap name" => "plots$(sp.attr[:subplot_index])", ) - if cg isa ColorPalette + if cg isa PlotUtils.CategoricalColorGradient push!( axis_opt, "colormap access" => "piecewise const", @@ -690,6 +690,12 @@ function pgfx_colormap(v::Vector{<:Colorant}) @sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c), blue(c)) end, "\n") end +function pgfx_colormap(cg::ColorGradient) + join(map(1:length(cg)) do i + @sprintf("rgb(%.8fcm)=(%.8f,%.8f,%.8f)", cg.values[i], red(cg.colors[i]), green(cg.colors[i]), blue(cg.colors[i])) + end, "\n") +end + function pgfx_framestyle(style::Symbol) if style in _pgfx_framestyles diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index d12d845b..65eb2561 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -350,23 +350,29 @@ function plotly_layout_json(plt::Plot) end -plotly_colorscale(cg::ColorGradient, α = nothing) = plotly_colorscale(PlotUtils.color_list(cg), α) -plotly_colorscale(c::Colorant,α) = plotly_colorscale(_as_gradient(c), α = nothing) +plotly_colorscale(cg::ColorGradient, α = nothing) = + [[v, rgba_string(plot_color(cg.colors[v], α))] for v in cg.values] function plotly_colorscale(c::AbstractVector{<:Colorant}, α = nothing) if length(c) == 1 - return [[0.0, rgba_string(plot_color(c[1], α))], [1.0, rgba_string(plot_color(c[1], α))]] + return [ + [0.0, rgba_string(plot_color(c[1], α))], + [1.0, rgba_string(plot_color(c[1], α))], + ] else - vals = range(0.0, stop=1.0, length=length(c)) + vals = range(0.0, stop = 1.0, length = length(c)) return [[vals[i], rgba_string(plot_color(c[i], α))] for i in eachindex(c)] end end -function plotly_colorscale(cp::ColorPalette, α = nothing) - n = length(cp) - inds = repeat(1:n, inner = 2) - vals = vcat((i-1:i for i in 1:n)...) ./ n - return [[vals[i], rgba_string(plot_color(cp[ind], α))] for (i, ind) in enumerate(inds)] +function plotly_colorscale(cg::PlotUtils.CategoricalColorGradient, α = nothing) + n = length(cg) + cinds = repeat(1:n, inner = 2) + vinds = vcat((i:(i + 1) for i in 1:n)...) + return [ + [cg.values[vinds[i]], rgba_string(plot_color(color_list(cg)[cinds[i]], α))] + for i in eachindex(cinds) + ] end -# plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha) +plotly_colorscale(c, α = nothing) = plotly_colorscale(_as_gradient(c), α) const _plotly_markers = KW( diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index bbb02336..7f986a50 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -68,20 +68,19 @@ py_color(grad::PlotUtils.AbstractColorList) = py_color(color_list(grad)) py_color(c::Colorant, α) = py_color(plot_color(c, α)) function py_colormap(cg::ColorGradient) - n = length(cg) - pyvals = collect(zip(range(0, 1, length = n), py_color(PlotUtils.color_list(cg)))) + pyvals = collect(zip(cg.values, py_color(PlotUtils.color_list(cg)))) cm = pycolors."LinearSegmentedColormap"."from_list"("tmp", pyvals) cm."set_bad"(color=(0,0,0,0.0), alpha=0.0) cm end -function py_colormap(cp::ColorPalette) - n = length(cp) - pyvals = collect(zip(range(0, 1, length = n), py_color(PlotUtils.color_list(cp)))) - cm = pycolors."LinearSegmentedColormap"."from_list"("tmp", pyvals, n) +function py_colormap(cg::PlotUtils.CategoricalColorGradient) + r = range(0, 1, length = 256) + pyvals = collect(zip(r, py_color(cg[r]))) + cm = pycolors."LinearSegmentedColormap"."from_list"("tmp", pyvals) cm."set_bad"(color=(0,0,0,0.0), alpha=0.0) cm end -py_colormap(c::Colorant) = py_colormap(_as_gradient(c)) +py_colormap(c) = py_colormap(_as_gradient(c)) function py_shading(c, z) diff --git a/src/utils.jl b/src/utils.jl index 43a759d3..46b40e32 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -134,6 +134,7 @@ _cycle(cl::PlotUtils.AbstractColorList, idx::Int) = cl[mod1(idx, end)] _cycle(cl::PlotUtils.AbstractColorList, idx::AVec{Int}) = cl[mod1.(idx, end)] _as_gradient(grad) = grad +_as_gradient(cp::ColorPalette) = cgrad(cp, categorical = true) _as_gradient(c::Colorant) = ColorGradient([c,c]) makevec(v::AVec) = v @@ -521,7 +522,7 @@ for comp in (:line, :fill, :marker) if z === nothing isa(c, ColorGradient) ? c : plot_color(_cycle(c, i)) else - nan_get(get_gradient(c), z[i], (cmin, cmax)) + get(get_gradient(c), z[i], (cmin, cmax)) end end @@ -559,26 +560,7 @@ single_color(grad::ColorGradient, v = 0.5) = grad[v] get_gradient(c) = cgrad() get_gradient(cg::ColorGradient) = cg -get_gradient(cp::ColorPalette) = cp - -function nan_get(cs, x, range) - if !isfinite(x) - return invisible() - elseif range isa Tuple && range[1] == range[2] - return plot_color(cs[1]) - else - plot_color(get(cs, x, range)) - end -end -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 +get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true) function get_linewidth(series, i::Int = 1) _cycle(series[:linewidth], i) diff --git a/test/runtests.jl b/test/runtests.jl index 04426ec3..488faf8f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -47,7 +47,6 @@ img_tol = is_ci() ? 1e-2 : Sys.islinux() ? 1e-3 : 0.1 ## Uncomment the following lines to update reference images for different backends -#= @testset "GR" begin image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr]) end @@ -66,7 +65,9 @@ pgfplotsx() @testset "PGFPlotsX" begin image_comparison_facts(:pgfplotsx, tol=img_tol, skip = Plots._backend_skips[:pgfplotsx]) end -=# + +# 10 Histogram2D + ## @testset "Backends" begin