From a728ed9a60f0b83da19c461d126c87d0524d4d4d Mon Sep 17 00:00:00 2001 From: Lukas Hauertmann Date: Tue, 5 Nov 2019 00:06:33 +0100 Subject: [PATCH] Add new method for `heatmap_edges` New method check input vectors for x and y in compatibility with the 2D input array z. It also decides whether x and y represend the midpoints or the egdes of the heatmap pixels. --- src/backends/gr.jl | 19 ++++--------------- src/utils.jl | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 6fa33080..50d67f16 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -921,17 +921,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) for ax in (sp[:xaxis], sp[:yaxis]) v = series[ax[:letter]] end - nx, ny = length(series[:x]), length(series[:y]) - z = series[:z] - use_midpoints = size(z) == (ny, nx) - use_edges = size(z) == (ny - 1, nx - 1) - if !use_midpoints && !use_edges - error("""Length of x & y does not match the size of z. - Must be either `size(z) == (length(y), length(x))` (x & y define midpoints) - or `size(z) == (length(y)+1, length(x)+1))` (x & y define edges).""") - end - x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]; isedges = use_edges), - heatmap_edges(series[:y], sp[:yaxis][:scale]; isedges = use_edges) + x, y = heatmap_edges(series[:x], sp[:xaxis][:scale], series[:y], sp[:yaxis][:scale], size(series[:z])) xy_lims = x[1], x[end], y[1], y[end] expand_extrema!(sp[:xaxis], x) expand_extrema!(sp[:yaxis], y) @@ -1323,18 +1313,17 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :heatmap zmin, zmax = clims - nx, ny = length(series[:x]), length(series[:y]) - use_midpoints = length(z) == ny * nx if !ispolar(sp) GR.setspace(zmin, zmax, 0, 90) - x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]; isedges = !use_midpoints), - heatmap_edges(series[:y], sp[:yaxis][:scale]; isedges = !use_midpoints) + 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) + 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) 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 diff --git a/src/utils.jl b/src/utils.jl index bd127f6c..cd7bb414 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -357,6 +357,22 @@ function heatmap_edges(v::AVec, scale::Symbol = :identity; isedges::Bool = false map(invf, _heatmap_edges(map(f,v), isedges)) end +function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size::Tuple{Int, Int}) + nx, ny = length(x), length(y) + # use_midpoints = z_size == (ny, nx) # This fails some tests, but would actually be + # the correct check, since (4, 3) != (3, 4) and a missleading plot is produced. + use_midpoints = prod(z_size) == (ny * nx) + use_edges = z_size == (ny - 1, nx - 1) + if !use_midpoints && !use_edges + error("""Length of x & y does not match the size of z. + Must be either `size(z) == (length(y), length(x))` (x & y define midpoints) + or `size(z) == (length(y)+1, length(x)+1))` (x & y define edges).""") + end + x, y = heatmap_edges(x, xscale; isedges = use_edges), + heatmap_edges(y, yscale; isedges = use_edges) + return x, y +end + function convert_to_polar(theta, r, r_extrema = ignorenan_extrema(r)) rmin, rmax = r_extrema r = (r .- rmin) ./ (rmax .- rmin)