# How to plot a 2D rotated array

**URL:** <https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603>\
**Category:** Visualization\
**Tags:** question, plotting, plots, gmt\
**Created:** [October 1, 2020, 3:08pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603 "2020-10-01T15:08:56Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![luraess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luraess/32/16189_2.png) [@luraess](https://discourse.julialang.org/u/luraess)\
**Post date:** [October 1, 2020, 3:08pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/1 "2020-10-01T15:08:56Z")

</div>

I am trying to plot a `heatmap` (or `contourf`, or similar) of a 2D array as function of rotated x and y coordinates. Here a code snippet of what I am trying to achieve:

```julia
using Plots
α = 10.0
lx, ly = 300.0, 100.0
nx, ny = 61, 21
(xc, yc ) = (LinRange(-lx/2, lx/2, nx), LinRange(-ly/2, ly/2, ny))
(Xc2,Yc2) = ([x for x=xc,y=yc], [y for x=xc,y=yc])
(X2r,Y2r) = (Xc2*cosd(α) - sind(α)*Yc2, Xc2*sind(α) + cosd(α)*Yc2)
display(heatmap(X2r, Y2r, rand(nx,ny)'))

```

Because of the rotation, the coordinate passed to the plotting function must be 2D array as well. This seems to be a problem in Plots.jl as the 2D plotting routines only accept coordinate vectors. Thus I get the following error:

```julia
ERROR: MethodError: no method matching heatmap_edges(::Surface{Array{Float64,2}}, ::Symbol)

```

The above exemple would work if I do following `display(heatmap(xc, yc, rand(nx,ny)'))` but then I do not get rotation. Any hints how to solve this issue are welcome !

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [October 1, 2020, 3:42pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/2 "2020-10-01T15:42:03Z")

</div>

You mean, something like

```julia
using GMT

julia> G = GMT.peaks();

julia> imshow(G, view=(45,90), xlabel="X", ylabel="Y", fmt=:png)

```

 ![GMTjl_tmp](https://global.discourse-cdn.com/julialang/original/3X/7/e/7ec7b0baed26c923e3c394bf3be14a50d51af129.png)

---

<div class="post-metadata">

**Author:** ![luraess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luraess/32/16189_2.png) [@luraess](https://discourse.julialang.org/u/luraess)\
**Post date:** [October 1, 2020, 3:51pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/3 "2020-10-01T15:51:39Z")

</div>

Yes, thanks @joa-quim for the example using GMT. Do you know if this could be achieved using `Plots.jl` (or similar) as well ?

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [October 1, 2020, 3:54pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/4 "2020-10-01T15:54:41Z")

</div>

Sorry, I guess it does it too but I don’t use plots so unable to help you there.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [October 1, 2020, 5:55pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/5 "2020-10-01T17:55:32Z")

</div>

GeoArrays.jl seems to have that capability using Plots, see bottom of [https://github.com/evetion/GeoArrays.jl](https://github.com/evetion/GeoArrays.jl). Maybe you can check their source?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [October 1, 2020, 5:59pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/6 "2020-10-01T17:59:55Z")

</div>

Can you plot in cartesian coordinations with a function that transforms x and y?

```julia
α = pi/3

# make some data
sz = (40, 80)
dat = reshape(1:prod(sz), sz)
x, y = axes(dat)

# performs rotation about center (or about c if provided)
# rounds and clamps the return value so it's a valid index
function rotate_coord(x, y, α, c = sz .÷ 2)
    x -= c[1]; y -= c[2]
    sα, cα = sincos(α)

    new_pt = (x*cα - y*sα, x*sα + y*cα) .+ c
    return clamp.(round.(Int, new_pt), 1, sz)
end 

# plot heatmap(x, y, f(x, y)).
heatmap(x, y, (x, y) -> dat[rotate_coord(x, y, α)...])

```

---

<div class="post-metadata">

**Author:** ![luraess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luraess/32/16189_2.png) [@luraess](https://discourse.julialang.org/u/luraess)\
**Post date:** [October 1, 2020, 7:20pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/7 "2020-10-01T19:20:43Z")

</div>

Thanks @tomerarnon for your suggestion. From testing it, it looks like it rotates the data but not the plot axes.

---

<div class="post-metadata">

**Author:** ![luraess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luraess/32/16189_2.png) [@luraess](https://discourse.julialang.org/u/luraess)\
**Post date:** [October 1, 2020, 7:43pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/8 "2020-10-01T19:43:55Z")

</div>

> [@mauro3](#):
>
> GeoArrays.jl seems to have that capability using Plots

Thanks for suggesting. However the example on git does not rotate the figure for plotting as depicted on the README…

---

<div class="post-metadata">

**Author:** ![luraess](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luraess/32/16189_2.png) [@luraess](https://discourse.julialang.org/u/luraess)\
**Post date:** [October 2, 2020, 9:40pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/9 "2020-10-02T21:40:20Z")

</div>

An alternative working solution is to use `pcolor()` available within `PyPlot.jl` to produce a heatmap-like output for a 2D data array as function of 2D coordinate fields (which can be rotated or not):

```julia
using PyPlot
α = 10.0
lx, ly = 300.0, 100.0
nx, ny = 61, 21
(xc, yc ) = (LinRange(-lx/2, lx/2, nx), LinRange(-ly/2, ly/2, ny))
(Xc2,Yc2) = ([x for x=xc,y=yc], [y for x=xc,y=yc])
(X2r,Y2r) = (Xc2*cosd(α) - sind(α)*Yc2, Xc2*sind(α) + cosd(α)*Yc2)
pcolor(X2r, Y2r, rand(nx,ny))

```

which will produce following output

 ![pcolor_out](https://global.discourse-cdn.com/julialang/original/3X/0/2/02bd43aeef57d912b2f1910e43ae9527917374ce.png)

Would be nice to have such capability within the `Plots.jl` environment. Any suggestion welcome.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 12, 2022, 4:30pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/10 "2022-06-12T16:30:03Z")

</div>

> [@luraess](#):
>
> Would be nice to have such capability within the `Plots.jl` environment. Any suggestion welcome.

One suggestion using Plots.jl, is to display the data via colored rotated rectangles. The result looks like a rotated heatmap for practical purposes:

 ![Plots_gr_rotated_heatmap](https://global.discourse-cdn.com/julialang/original/3X/9/8/9808e3c3de8d8f0adba40553923cd8665bbfa7d3.jpeg)

> **Plots.jl gr() code (no bells & whistles)**
>
> ```julia
> using ColorSchemes, Plots; gr(dpi=600)
> import ColorSchemes.viridis
> 
> rotx(x,y,α) = x*cosd(α) - y*sind(α)
> roty(x,y,α) = x*sind(α) + y*cosd(α)
> 
> function rectangle(x, y, w, h, α)
> X, Y = [0,w,w,0], [0,0,h,h]
> Shape(x .+ rotx.(X,Y,α), y .+ roty.(X,Y,α))
> end
> 
> # 1 - INPUT DATA
> α = 45.0
> x1, x2 = -150, 150
> y1, y2 = -80, 80
> w, h = 4.0, 2.0
> xc, yc = -w/2 .+ range(x1, x2, step=w), -h/2 .+ range(y1, y2, step=h)
> cp = Iterators.product(xc,yc)
> Xc, Yc = first.(cp), last.(cp)
> Xr, Yr = rotx.(Xc,Yc,α), roty.(Xc,Yc,α)
> Z = sin.(hypot.(Xr,Yr)/10) # some function of (x,y)
> 
> # 2- PLOT ROTATED HEATMAP
> zc = (Z .- minimum(Z))/(maximum(Z) - minimum(Z)) # normalize extrema to (0,1)
> Cz = get.(Ref(viridis), zc) # compute RGB colors
> clims = extrema(Z)
> heatmap(xc, yc, NaN*Z, ratio=1, clims=clims, frame=:none, legend=:outerright)
> for (x, y, c) in zip(Xr,Yr,Cz)
> plot!(rectangle(x, y, w, h, α), c=c, lw=0.1, lc=c);
> end
> 
> xaxis = [-w/2 + x1, w/2 + x2]
> yaxis = [-h/2 + y1, h/2 + y2]
> xt, yt = LinRange(x1, x2, 9), LinRange(y1, y2, 9)
> Xxt, Yxt = rotx.(xt, yaxis[1] .+ zero(xt), α), roty.(xt, yaxis[1] .+ zero(xt), α)
> Xyt, Yyt = rotx.(xaxis[1] .+ zero(yt), yt, α), roty.(xaxis[1] .+ zero(yt), yt, α)
> Xx, Xy = rotx.(xaxis, yaxis[1] .+ [0,0], α), roty.(xaxis, yaxis[1] .+ [0,0], α)
> Yx, Yy = rotx.(xaxis[1] .+ [0,0], yaxis, α), roty.(xaxis[1] .+ [0,0], yaxis, α)
> c = (y2-y1)/(x2-x1)
> dX, dY = c*[diff(Xx)[], diff(Xy)[]]/10, [diff(Yx)[], diff(Yy)[]]/10
> for (x,y) in zip(Xxt,Yxt)
> plot!([x, x - dY[1]/3], [y, y - dY[2]/3], lc=:black)
> end
> for (x,y) in zip(Xyt,Yyt)
> plot!([x, x - dX[1]/3], [y, y - dX[2]/3], lc=:black)
> end
> plot!(Xx, Xy, lc=:black, lw=1)
> plot!(Yx, Yy, lc=:black, lw=1)
> annotate!(Xxt .- dY[1], Yxt .- dY[2], text.(string.(round.(xt, digits=1)), 5, rotation=α, "Computer Modern"))
> annotate!(Xyt .- dX[1], Yyt .- dX[2], text.(string.(round.(yt, digits=1)), :right, 5, rotation=α, "Computer Modern"))
> Plots.current()
> 
> ```

---

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [June 13, 2022, 11:08am UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/11 "2022-06-13T11:08:16Z")

</div>

Another version using `ImageTransformations.jl` and `Plots.jl`:

```julia
using ImageTransformations, Rotations, OffsetArrays, CoordinateTransformations, Plots
s=0.05
yl = range(-5, stop= 5, step=s)
xl = range(-5, stop= 10, step=s)
x = [xe for ye in yl, xe in xl]
y = [ye for ye in yl, xe in xl]
z = @. sin(x)^10 + cos(10 + y*x) + cos(x) + 0.2*y + 0.1*x
trfm = CoordinateTransformations.recenter(RotMatrix(-pi/4), ImageTransformations.center(z));
rotatedz = warp(z, trfm; fillvalue=NaN); 
m, n = size(rotatedz)
newz = OffsetArray(rotatedz, 1:m, 1:n)
heatmap(newz, c=:curl, size=(450, 360))

```

![rotated-heatmap](https://global.discourse-cdn.com/julialang/original/3X/9/b/9bee2d262c5b25b1d0b95832c27162b1271484b0.png)

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 13, 2022, 8:58pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/12 "2022-06-13T20:58:52Z")

</div>

@empet, your heatmap _en pète_, but if we use few cells we see they are not rotated:

 ![Plots_heatmap_rotated_data_but_not_the_cells](https://global.discourse-cdn.com/julialang/original/3X/a/1/a1a096e96af66a1ad12b533e04cc0e7317231388.png)

---

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [June 13, 2022, 9:29pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/13 "2022-06-13T21:29:22Z")

</div>

Your pixelated heatmap is associated to an usual matrix (newz), hence it is expected to have squares of sides parallel to axes.  
This mehod, based on ImageTransformations.jl, works for “continuous” heatmaps, because the function warp acts on non-pixelated images.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 13, 2022, 9:36pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/14 "2022-06-13T21:36:42Z")

</div>

If I turn my lunch box, I don’t want it to come out bitten.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [June 13, 2022, 10:16pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/15 "2022-06-13T22:16:28Z")

</div>

Wasn’t it a OP’s condition that the axes are rotated too? Only one posted solution fulfills it.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 14, 2022, 9:01pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/16 "2022-06-14T21:01:24Z")

</div>

> [@joa-quim](#):
>
> Wasn’t it a OP’s condition that the axes are rotated too? Only one posted solution fulfills it.

Look again.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [June 14, 2022, 9:06pm UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/17 "2022-06-14T21:06:46Z")

</div>

Ok, Ok, 2. (but that colorbar, tch,tch, it should join the group too 🙂 )

---

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [June 17, 2022, 8:58am UTC](https://discourse.julialang.org/t/how-to-plot-a-2d-rotated-array/47603/18 "2022-06-17T08:58:01Z")

</div>

```julia
using Images, Plots
s=0.05
yl = range(-5, stop= 5, step=s)
xl = range(-5, stop= 10, step=s)
x = [xe for ye in yl, xe in xl]
y = [ye for ye in yl, xe in xl]
z = @. sin(x)^10 + cos(10 + y*x) + cos(x) + 0.2*y + 0.1*x
pl= heatmap(z, c=:curl, size=(500, 300))
png("heatmap")
img= load("heatmap.png")
newimg = imrotate(img, pi/4, fillvalue=1)

```

 ![rotatedheatmap-colorbar](https://global.discourse-cdn.com/julialang/original/3X/8/9/8918f48a2799a73584dbd4fa60e1f051e37a6099.png)
