From f33905ed8089beff46a26979e93e533d32fd4002 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Thu, 26 May 2016 23:47:09 -0400 Subject: [PATCH] fixes for images/heatmaps/surfaces --- src/axes.jl | 15 +++++++++++++++ src/backends/pyplot.jl | 19 ++++++++++++++----- src/plot.jl | 28 ++++++++++++++++------------ src/series_new.jl | 42 ++++++++++++++++++++++++++---------------- 4 files changed, 71 insertions(+), 33 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index d4d9227e..6d322ca0 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -169,6 +169,21 @@ function discrete_value!(a::Axis, v::AVec) cvec, discrete_indices end +# add the discrete value for each item. return the continuous values and the indices +function discrete_value!(a::Axis, v::AMat) + n,m = size(v) + cmat = zeros(n,m) + discrete_indices = zeros(Int, n, m) + for i=1:n, j=1:m + cmat[i,j], discrete_indices[i,j] = discrete_value!(a, v[i,j]) + end + cmat, discrete_indices +end + +function discrete_value!(a::Axis, v::Surface) + map(Surface, discrete_value!(a, v.surf)) +end + function pie_labels(sp::Subplot, series::Series) d = series.d if haskey(d,:x_discrete_indices) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 2d52c792..b18667cf 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -714,6 +714,7 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series) end if st == :image + # @show typeof(z) img = Array(transpose_z(d, z.surf)) z = if eltype(img) <: Colors.AbstractGray float(img) @@ -723,15 +724,22 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series) z # hopefully it's in a data format that will "just work" with imshow end handle = ax[:imshow](z; - zorder = plt.n + zorder = plt.n, + cmap = getPyPlotColorMap([:black, :white]), + vmin = 0.0, + vmax = 1.0 ) push!(handles, handle) end if st == :heatmap x, y, z = heatmap_edges(x), heatmap_edges(y), transpose_z(d, z.surf) - if !(eltype(z) <: Number) - z, discrete_colorbar_values = indices_and_unique_values(z) + # if !(eltype(z) <: Number) + # z, discrete_colorbar_values = indices_and_unique_values(z) + # end + dvals = sp.attr[:zaxis][:discrete_values] + if !isempty(dvals) + discrete_colorbar_values = dvals end handle = ax[:pcolormesh](x, y, z; label = d[:label], @@ -784,7 +792,8 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series) kw = KW() if discrete_colorbar_values != nothing locator, formatter = get_locator_and_formatter(discrete_colorbar_values) - kw[:values] = 1:length(discrete_colorbar_values) + # kw[:values] = 1:length(discrete_colorbar_values) + kw[:values] = sp.attr[:zaxis][:continuous_values] kw[:ticks] = locator kw[:format] = formatter kw[:boundaries] = vcat(0, kw[:values] + 0.5) @@ -794,7 +803,7 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series) # note: the colorbar axis is positioned independently from the subplot axis fig = plt.o cbax = fig[:add_axes]([0.8,0.1,0.03,0.8]) - sp.attr[:cbar_handle] = fig[:colorbar](handle, cax = cbax, kw...) + sp.attr[:cbar_handle] = fig[:colorbar](handle; cax = cbax, kw...) sp.attr[:cbar_ax] = cbax end diff --git a/src/plot.jl b/src/plot.jl index 45a17ae0..1222d87b 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -43,7 +43,7 @@ When you pass in matrices, it splits by columns. See the documentation for more # this creates a new plot with args/kw and sets it to be the current plot function plot(args...; kw...) - pkg = backend() + # pkg = backend() d = KW(kw) preprocessArgs!(d) @@ -116,17 +116,21 @@ function _apply_series_recipe(plt::Plot, d::KW) end # adjust extrema and discrete info - for letter in (:x, :y, :z) - data = d[letter] - axis = sp.attr[symbol(letter, "axis")] - if eltype(data) <: Number - expand_extrema!(axis, data) - elseif data != nothing - # TODO: need more here... gotta track the discrete reference value - # as well as any coord offset (think of boxplot shape coords... they all - # correspond to the same x-value) - # @show letter,eltype(data),typeof(data) - d[letter], d[symbol(letter,"_discrete_indices")] = discrete_value!(axis, data) + if st != :image + for letter in (:x, :y, :z) + data = d[letter] + axis = sp.attr[symbol(letter, "axis")] + if eltype(data) <: Number + expand_extrema!(axis, data) + elseif isa(data, Surface) && eltype(data.surf) <: Number + expand_extrema!(axis, data) + elseif data != nothing + # TODO: need more here... gotta track the discrete reference value + # as well as any coord offset (think of boxplot shape coords... they all + # correspond to the same x-value) + # @show letter,eltype(data),typeof(data) + d[letter], d[symbol(letter,"_discrete_indices")] = discrete_value!(axis, data) + end end end diff --git a/src/series_new.jl b/src/series_new.jl index 6c12b9aa..31351ed0 100644 --- a/src/series_new.jl +++ b/src/series_new.jl @@ -148,7 +148,7 @@ end # function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, mat::AMat{T}) # if all3D(d) # n,m = size(mat) -# d[:x], d[:y], d[:z] = 1:n, 1:m, mat +# d[:x], d[:y], d[:z] = 1:m, 1:n, mat # else # d[:y] = mat # end @@ -158,9 +158,9 @@ end @recipe function f{T<:Number}(mat::AMat{T}) if all3D(d) n,m = size(mat) - 1:n, 1:m, Surface(mat) + SliceIt, 1:m, 1:n, Surface(mat) else - nothing, mat, nothing + SliceIt, nothing, mat, nothing end end @@ -170,7 +170,7 @@ end # function process_inputs{T<:Gray}(plt::AbstractPlot, d::KW, mat::AMat{T}) # d[:seriestype] = :image # n,m = size(mat) -# d[:x], d[:y], d[:z] = 1:n, 1:m, Surface(mat) +# d[:x], d[:y], d[:z] = 1:m, 1:n, Surface(mat) # # handle images... when not supported natively, do a hack to use heatmap machinery # if !nativeImagesSupported() # d[:seriestype] = :heatmap @@ -182,14 +182,14 @@ end @recipe function f{T<:Gray}(mat::AMat{T}) if nativeImagesSupported() - seriestype --> :image, force + seriestype := :image n, m = size(mat) - 1:n, 1:m, Surface(mat) + SliceIt, 1:m, 1:n, Surface(mat) else - seriestype --> :heatmap, force + seriestype := :heatmap yflip --> true fillcolor --> ColorGradient([:black, :white]) - 1:n, 1:m, Surface(convert(Matrix{Float64}, mat)) + SliceIt, 1:m, 1:n, Surface(convert(Matrix{Float64}, mat)) end end @@ -198,7 +198,7 @@ end # function process_inputs{T<:Colorant}(plt::AbstractPlot, d::KW, mat::AMat{T}) # d[:seriestype] = :image # n,m = size(mat) -# d[:x], d[:y], d[:z] = 1:n, 1:m, Surface(mat) +# d[:x], d[:y], d[:z] = 1:m, 1:n, Surface(mat) # # handle images... when not supported natively, do a hack to use heatmap machinery # if !nativeImagesSupported() # d[:yflip] = true @@ -209,14 +209,14 @@ end @recipe function f{T<:Colorant}(mat::AMat{T}) if nativeImagesSupported() - seriestype --> :image, force + seriestype := :image n, m = size(mat) - 1:n, 1:m, Surface(mat) + SliceIt, 1:m, 1:n, Surface(mat) else - seriestype --> :heatmap, force + seriestype := :heatmap yflip --> true z, d[:fillcolor] = replace_image_with_heatmap(mat) - 1:n, 1:m, Surface(z) + SliceIt, 1:m, 1:n, Surface(z) end end @@ -228,7 +228,7 @@ end # end @recipe function f(shape::Shape) - seriestype --> :shape, force + seriestype := :shape shape_coords(shape) end @@ -238,7 +238,7 @@ end # end @recipe function f(shapes::AVec{Shape}) - seriestype --> :shape, force + seriestype := :shape shape_coords(shapes) end @@ -312,12 +312,22 @@ end st = get(d, :seriestype, :none) if st == :scatter d[:seriestype] = :scatter3d - elseif !(st in _3dTypes) + elseif !is3d(st) d[:seriestype] = :path3d end SliceIt, x, y, z end +@recipe function f(x::AMat, y::AMat, z::AMat) + st = get(d, :seriestype, :none) + if size(x) == size(y) == size(z) + if !is3d(st) + seriestype := :path3d + end + end + SliceIt, x, y, z +end + # # # surface-like... function # function process_inputs{TX,TY}(plt::AbstractPlot, d::KW, x::AVec{TX}, y::AVec{TY}, zf::Function)