JuliaPlots / Plots.jl

Powerful convenience for Julia visualizations and data analysis
https://docs.juliaplots.org
Other
1.84k stars 355 forks source link

OffsetArray and Plots.heatmap #2410

Open goretkin opened 4 years ago

goretkin commented 4 years ago

This doesn't seem to work neither with the GR backend (output below) or the PyPlot backend (stacktrace below).

import LinearAlgebra: I
import OffsetArrays: OffsetArray
import Plots
Plots.pyplot()
#Plots.gr()
bmp = OffsetArray(collect(I(11)), -5:5, -5:5)
Plots.heatmap(bmp)

PyPlot:

julia> Plots.heatmap(bmp)
Error showing value of type Plots.Plot{Plots.PyPlotBackend}:
ERROR: PyError ($(Expr(:escape, :(ccall(#= /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'TypeError'>
TypeError('Dimensions of C (11, 11) are incompatible with X (6) and/or Y (6); see help(pcolormesh)')
  File "/Users/goretkin/.julia/conda/3/lib/python3.7/site-packages/matplotlib/__init__.py", line 1805, in inner
    return func(ax, *args, **kwargs)
  File "/Users/goretkin/.julia/conda/3/lib/python3.7/site-packages/matplotlib/axes/_axes.py", line 5971, in pcolormesh
    X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
  File "/Users/goretkin/.julia/conda/3/lib/python3.7/site-packages/matplotlib/axes/_axes.py", line 5564, in _pcolorargs
    C.shape, Nx, Ny, funcname))

Stacktrace:
 [1] pyerr_check at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/exception.jl:60 [inlined]
 [2] pyerr_check at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/exception.jl:64 [inlined]
 [3] _handle_error(::String) at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/exception.jl:81
 [4] macro expansion at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/exception.jl:95 [inlined]
 [5] #110 at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/pyfncall.jl:43 [inlined]
 [6] disable_sigint at ./c.jl:446 [inlined]
 [7] __pycall! at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/pyfncall.jl:42 [inlined]
 [8] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{Array{Float64,1},Array{Float64,1},PyCall.PyObject}, ::Int64, ::PyCall.PyObject) at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/pyfncall.jl:29
 [9] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{Array{Float64,1},Array{Float64,1},PyCall.PyObject}, ::Base.Iterators.Pairs{Symbol,Any,NTuple{6,Symbol},NamedTuple{(:label, :zorder, :cmap, :alpha, :vmax, :vmin),Tuple{String,Int64,PyPlot.ColorMap,Nothing,Float64,Float64}}}) at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/pyfncall.jl:11
 [10] #_#117 at /Users/goretkin/.julia/packages/PyCall/kAhnQ/src/pyfncall.jl:86 [inlined]
 [11] (::Core.var"#kw#Any")(::NamedTuple{(:label, :zorder, :cmap, :alpha, :vmax, :vmin),Tuple{String,Int64,PyPlot.ColorMap,Nothing,Float64,Float64}}, ::PyCall.PyObject, ::Array{Float64,1}, ::Array{Float64,1}, ::PyCall.PyObject) at ./none:0
 [12] py_add_series(::Plots.Plot{Plots.PyPlotBackend}, ::Plots.Series) at /Users/goretkin/.julia/packages/Plots/12uaJ/src/backends/pyplot.jl:779
 [13] _before_layout_calcs(::Plots.Plot{Plots.PyPlotBackend}) at /Users/goretkin/.julia/packages/Plots/12uaJ/src/backends/pyplot.jl:975
 [14] prepare_output(::Plots.Plot{Plots.PyPlotBackend}) at /Users/goretkin/.julia/packages/Plots/12uaJ/src/plot.jl:253
 [15] display(::Plots.PlotsDisplay, ::Plots.Plot{Plots.PyPlotBackend}) at /Users/goretkin/.julia/packages/Plots/12uaJ/src/output.jl:143

GR: image

I have

  [91a5bcdd] Plots v0.29.1

Related: https://github.com/JuliaPlots/Plots.jl/pull/2304

JeffFessler commented 3 years ago

Here's a simpler example:

using Plots
using OffsetArrays
z = OffsetArray(ones(5)*(1:4)', (-3,-2))
heatmap(z) # fails

Error showing value of type Plots.Plot{Plots.GRBackend}:
ERROR: DimensionMismatch("new dimensions (4,) must be consistent with array size 20")
Stacktrace:
  [1] (::Base.var"#throw_dmrsa#234")(dims::Tuple{Int64}, len::Int64)
    @ Base ./reshapedarray.jl:41
  [2] reshape
    @ ./reshapedarray.jl:45 [inlined]
  [3] reshape
    @ ~/.julia/packages/OffsetArrays/EYLoR/src/OffsetArrays.jl:357 [inlined]
  [4] nonuniformcellarray(x::Vector{Float64}, y::Vector{Float64}, dimx::Int64, dimy::Int64, color::OffsetMatrix{Int32, Matrix{Int32}})
    @ GR ~/.julia/packages/GR/4DHy8/src/GR.jl:881
  [5] gr_draw_heatmap(series::Plots.Series, x::Vector{Float64}, y::Vector{Float64}, z::OffsetMatrix{Float64, Matrix{Float64}}, clims::Tuple{Float64, Float64})
    @ Plots ~/.julia/packages/Plots/FKcum/src/backends/gr.jl:1861
  [6] gr_add_series(sp::Plots.Subplot{Plots.GRBackend}, series::Plots.Series)
    @ Plots ~/.julia/packages/Plots/FKcum/src/backends/gr.jl:1665
  [7] gr_display(sp::Plots.Subplot{Plots.GRBackend}, w::Measures.AbsoluteLength, h::Measures.AbsoluteLength, viewport_canvas::Vector{Float64})
...

Using: [91a5bcdd] Plots v1.16.5

Here's my current workaround, in case it helps others:

using Plots
using OffsetArrays
z = OffsetArray(ones(5)*(1:4)', (-3,-2))

function Plots.heatmap(z::OffsetMatrix{<:Number}; kwargs...)
    x = axes(z,1); x = x.parent .+ x.offset
    y = axes(z,2); y = y.parent .+ y.offset
    heatmap(x, y, OffsetArrays.no_offset_view(z); kwargs...)
end

heatmap(z, title="it works")