yosuga
yosuga

Reputation: 351

How to plot 3D HeatMap in Julia?

I want to plot 3D HeatMap for 3D function f(x,y,z).

For 2D function f(x,y), I know the below code works.

using Plots

x = 1:L  # coordinate range
y = 1:L

F = Float64[f(ix,iy) for ix in x, iy in y]' #convert f(x,y) to an array

plot(F,st=:heatmap,color= cgrad(:blues))
plot!(xlabel="x",ylabel="y",aspect_ratio=:equal)
plot!(xlims=(1,L),ylims=(1,L))

For 3D function, where should I change?

using Plots

x = 1:L  # coordinate range
y = 1:L
z = 1:L

F = Float64[f(ix,iy,iz) for ix in x, iy in y,iz in z] #convert f(x,y,z) to an array

plot(F,st=:heatmap,color = cgrad(:blues),alpha=0.1)
plot!(xlabel="x",ylabel="y",zlabel="z",aspect_ratio=:equal)
plot!(xlims=(1,L),ylims=(1,L),zlims=(1,L))

This code passes, but something is wrong.
color = cgrad(:blues),alpha=0.1,xlabel="x",ylabel="y" are not reflected.
In addition, the figure does not seem to be f(x,y,z). For example, f(x,y,z) = x^2 + y^2 +z^2 gives a spherical gradation, but the result is not.

Upvotes: 1

Views: 1914

Answers (2)

Lazaro Alonso
Lazaro Alonso

Reputation: 56

The above approach is slow for more data points. However, I think you don't want heatmaps as the heatmaps in the previous link are just projections from 2D into 3D planes.

I think you need something like this. See code here.

https://lazarusa.github.io/BeautifulMakie/surfWireLines/volume/

See image

And for convenience also here:

using GLMakie
let
    x = 1:10
    y = 1:10
    z = 1:10
    f(x,y,z) = x^2 + y^2 + z^2
    vol = [f(ix,iy,iz) for ix in x, iy in y, iz in z]
    fig, ax, _ = volume(x, y, z, vol, colormap = :plasma,colorrange = (minimum(vol), maximum(vol)),
        figure = (; resolution = (800,800)),  
        axis=(; type=Axis3, perspectiveness = 0.5,  azimuth = 7.19, elevation = 0.57,  
            aspect = (1,1,1)))

    fig
end

Upvotes: 1

yosuga
yosuga

Reputation: 351

3D HeatMap by Makie.jl
I don't know how to plot 3D HeatMap by Plots.jl yet, but I found the another way by Makie.jl : https://lazarusa.github.io/BeautifulMakie/surfWireLines/RGBcube/ .
With the help of this sample code, I got the following code.

using GLMakie, GeometryBasics, Colors

positions = vec([(i, j, k) for i=1:L,j=1:L,k=1:L]) #3D coordinate
F = zeros(Float64,length(positions)

for i = 1:length(positions) #convert f(x,y,z) to an array
  x = positions[i][1]
  y = positions[i][2]
  z = positions[i][3]
   F[i] = f(x,y,z)
end
fig, ax = mesh(HyperRectangle(Vec3f0(positions[1]...),Vec3f0(0.8)), color = RGBA(0,0,F[1],0.5), transparency = false) #HyperRectangle(::position,::length),color=(::red,::green,::blue,::alpha)
wireframe!(ax,HyperRectangle(Vec3f0(positions[1]...), Vec3f0(0.8)), linewidth = 0.1, overdraw = false)

for i in 2:length(positions)
  mesh!(ax, HyperRectangle(Vec3f0(positions[i]...), Vec3f0(0.8)), color = RGBA(0,0,F[i],0.5))
  wireframe!(ax, HyperRectangle(Vec3f0(positions[i]...), Vec3f0(0.8)), linewidth = 0.1, overdraw = false)
end

fig

Upvotes: 0

Related Questions