How to use CairoMakie.contourf!

I cannot for the life of me figure out what the heck I need to pass to CairoMakie.contourf!. What I have tried thus far produces an error:

"""
Plots and electric field of two point charges with a countour plot
on the same axes.
"""

import CairoMakie as CM
import Base.Iterators as It

"""
A type representing a point charge.
"""
struct PointCharge
	charge::Float64
	position::Vector{Float64}
end # struct

"""
Computes a 2-norm for a set of vectors given as columns of a
matrix.
"""
function vec2Norm(vecs::Matrix{<:AbstractFloat})
	sqrt.( sum( vecs .^ 2, dims=1 ) )
end

"""
Computes an electric field for a point charge at given positions,
encoded into columns of a matrix.
"""
function EFn(pc::PointCharge, positions, ϵ0=1.0 )
	differences = positions .- pc.position
	distances = vec2Norm(differences)
	unitDifferences = differences ./ distances
	pc.charge ./ 4 ./ π ./ ϵ0 ./ distances .^ 2 .* unitDifferences
end # function

"""
Computes a potential field field for a point charge at given
positions, encoded into columns of a matrix.
"""
function uFn(pc::PointCharge,positions, ϵ0=1.0)
	differences = positions .- pc.position
	distances = vec2Norm(differences)
	pc.charge ./ 4 ./ π ./ ϵ0 ./ distances
end # function

"""
The main routine of this module.
"""
function main()

	println("Running main routine…")

	step = 0.8

	@show xx = -5 : step : 5

	@show yy = xx

	grid = collect(It.product(xx,yy))[:]

	gridx = first.(grid)

	gridy = last.(grid)

	@show size(collect(gridx'))

	@show size(collect(gridy'))

	gridMat = [gridx' ; gridy']

	@show size(gridMat)

	@show charge1 = PointCharge(-1.0,[-1,-1])

	@show charge2 = PointCharge(1.0,[1,1])

	E1 = EFn(charge1,gridMat)

	E2 = EFn(charge2,gridMat)

	u1 = uFn(charge1,gridMat)

	u2 = uFn(charge2,gridMat)

	u = u1 + u2

	@show size(u)

	@show typeof(u)

	E = E1 + E2

	@show size(E1)

	@show size(E2)

	fig, ax = CM.arrows(gridx,gridy,E[1,:],E[2,:])

	CM.scatter!(ax,charge1.position[1],charge1.position[2],markersize=20,color=:blue)

	CM.scatter!(ax,charge2.position[1],charge2.position[2],markersize=20,color=:red)

	CM.contourf!(ax,gridx,gridy,u)

	CM.save(abspath(joinpath(@__DIR__,"E.pdf")),fig)

end # function

# Run main function only if this file is invoked as a script.

if abspath(PROGRAM_FILE) == @__FILE__
	main()
end

The error:

ERROR: LoadError: Length of x (169) must be equal to number of columns in z (1)
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] isobands(xs::Vector{Float64}, ys::Vector{Float64}, zs::Matrix{Float64}, low_values::Vector{Float64}, high_values::Vector{Float64})
    @ Isoband ~/.julia/packages/Isoband/qUEGP/src/Isoband.jl:56
  [3] isobands(xs::Vector{Float32}, ys::Vector{Float32}, zs::LinearAlgebra.Adjoint{Float32, Matrix{Float32}}, lows::Vector{Float32}, highs::Vector{Float32})
    @ Isoband ~/.julia/packages/Isoband/qUEGP/src/Isoband.jl:32
  [4] (::Makie.var"#calculate_polys#563"{Observables.Observable{Vector{Float64}}, Observables.Observable{Vector{GeometryBasics.Polygon{2, Float32, GeometryBasics.Point{2, Float32}, GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}}}}}})(xs::Vector{Float32}, ys::Vector{Float32}, zs::Matrix{Float32}, levels::Vector{Float32}, is_extended_low::Bool, is_extended_high::Bool)
    @ Makie ~/.julia/packages/Makie/ND0gA/src/basic_recipes/contourf.jl:110
  [5] plot!(c::MakieCore.Plot{Makie.contourf, Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}})
    @ Makie ~/.julia/packages/Makie/ND0gA/src/basic_recipes/contourf.jl:132
  [6] connect_plot!(parent::Makie.Scene, plot::MakieCore.Plot{Makie.contourf, Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}})
    @ Makie ~/.julia/packages/Makie/ND0gA/src/interfaces.jl:260
  [7] plot!
    @ ~/.julia/packages/Makie/ND0gA/src/interfaces.jl:265 [inlined]
  [8] plot!(ax::Makie.Axis, plot::MakieCore.Plot{Makie.contourf, Tuple{Vector{Float32}, Vector{Float32}, Matrix{Float32}}})
    @ Makie ~/.julia/packages/Makie/ND0gA/src/figureplotting.jl:316
  [9] _create_plot!(::Function, ::Dict{Symbol, Any}, ::Makie.Axis, ::Vector{Float64}, ::Vararg{Any})
    @ Makie ~/.julia/packages/Makie/ND0gA/src/figureplotting.jl:284
 [10] contourf!(::Makie.Axis, ::Vararg{Any}; kw::@Kwargs{})
    @ Makie ~/.julia/packages/MakieCore/UAwps/src/recipes.jl:176
 [11] main()
    @ Main ~/tau-typst-presentation/images/dipoles.jl:103
 [12] top-level scope
    @ ~/tau-typst-presentation/images/dipoles.jl:112
in expression starting at /Users/soderhos/tau-typst-presentation/images/dipoles.jl:111

When I try to transpose gridx, I get an error about an unkown recipe for contourf. What am I doing wrong?

Your code is a bit too long for me to read through, but have you looked at the docs which have quite a few examples of how to use the function?

https://docs.makie.org/stable/reference/plots/contourf/

The documentation is useless, because it does not tell me anything about the required types and/or array shapes. At the end of the code, I am just trying to pass in a vector of x- ,y-coordinates, along with a vector/matrix of potential values corresponding to the x–y pairs, which is what the documentation tells me to do. Something as simple as this just fails…

I mean at the end of main.

If I append the data into a single matrix, I get not errors, but for some reason the image now has values for the potentials for values between 1:169, which is the size of a data vector. The values should be plotted into a grid between -5 and 5 in the x–y plane.

The documentation shows the usage with a matrix, where the x/y coordinates are implicitly given by the positions of values in the matrix.

Alternatively you can specify the x and y coordinates in separate vectors, together with z values as another vector:

julia> contourf(repeat(-5:5, 11), repeat(-5:5, inner = 11), rand(11*11))

works for me.

Alright, so the issue is probably that either you need to give it a single matrix, or 3 separate Vectors. A combination of Matrixes and Vectors does not work. I just need to convert the u matrix into a vector somehow.

Which is turning out to be a rather difficult task. Vector(matrix) does not work.

But vec(matrix) does. Now the code works.