Merge pull request #2299 from yha/uniform-heatmaps

Use GR.drawimage for uniform heatmaps
This commit is contained in:
Josef Heinen 2019-12-03 21:05:40 +01:00 committed by GitHub
commit ca9ce5427d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 12 deletions

View File

@ -69,6 +69,19 @@ const gr_font_family = Dict(
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
gr_color(c) = gr_color(c, color_type(c))
gr_color(c, ::Type{<:AbstractRGB}) = UInt32( round(UInt, clamp(alpha(c) * 255, 0, 255)) << 24 +
round(UInt, clamp(blue(c) * 255, 0, 255)) << 16 +
round(UInt, clamp(green(c) * 255, 0, 255)) << 8 +
round(UInt, clamp(red(c) * 255, 0, 255)) )
function gr_color(c, ::Type{<:AbstractGray})
g = round(UInt, clamp(gray(c) * 255, 0, 255))
α = round(UInt, clamp(alpha(c) * 255, 0, 255))
rgba = UInt32( α<<24 + g<<16 + g<<8 + g )
end
gr_color(c, ::Type) = gr_color(RGBA(c), RGB)
function gr_getcolorind(c) function gr_getcolorind(c)
gr_set_transparency(float(alpha(c))) gr_set_transparency(float(alpha(c)))
convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c))) convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c)))
@ -1318,9 +1331,23 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
x, y = heatmap_edges(series[:x], sp[:xaxis][:scale], series[:y], sp[:yaxis][:scale], size(series[:z])) 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 w, h = length(x) - 1, length(y) - 1
z_normalized = map(x -> GR.jlgr.normalize_color(x, zmin, zmax), z) z_normalized = map(x -> GR.jlgr.normalize_color(x, zmin, zmax), z)
z_normalized = map(x -> isnan(x) ? 256/255 : x, z_normalized) # results in color index = 1256 -> transparent if is_uniformly_spaced(x) && is_uniformly_spaced(y)
colors = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized] # For uniformly spaced data use GR.drawimage, which can be
GR.nonuniformcellarray(x, y, w, h, colors) # 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.
colors = plot_color.(series[:fillcolor][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)
end
else else
phimin, phimax = 0.0, 360.0 # nonuniform polar array is not yet supported in GR.jl phimin, phimax = 0.0, 360.0 # nonuniform polar array is not yet supported in GR.jl
nx, ny = length(series[:x]), length(series[:y]) nx, ny = length(series[:x]), length(series[:y])
@ -1439,15 +1466,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
z = transpose_z(series, series[:z].surf, true)' z = transpose_z(series, series[:z].surf, true)'
w, h = size(z) w, h = size(z)
xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y]) xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y])
if eltype(z) <: Colors.AbstractGray rgba = gr_color.(z)
grey = round.(UInt8, clamp.(float(z) * 255, 0, 255))
rgba = map(c -> UInt32( 0xff000000 + UInt(c)<<16 + UInt(c)<<8 + UInt(c) ), grey)
else
rgba = map(c -> UInt32( round(UInt, clamp(alpha(c) * 255, 0, 255)) << 24 +
round(UInt, clamp(blue(c) * 255, 0, 255)) << 16 +
round(UInt, clamp(green(c) * 255, 0, 255)) << 8 +
round(UInt, clamp(red(c) * 255, 0, 255)) ), z)
end
GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba)
end end

View File

@ -375,6 +375,11 @@ function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size:
return x, y return x, y
end end
function is_uniformly_spaced(v; tol=1e-6)
dv = diff(v)
maximum(dv) - minimum(dv) < tol * mean(abs.(dv))
end
function convert_to_polar(theta, r, r_extrema = ignorenan_extrema(r)) function convert_to_polar(theta, r, r_extrema = ignorenan_extrema(r))
rmin, rmax = r_extrema rmin, rmax = r_extrema
r = (r .- rmin) ./ (rmax .- rmin) r = (r .- rmin) ./ (rmax .- rmin)