PColormesh equivalent in Makie

I’m looking for a Makie equivalent to the matplotlib pcolormesh. I attempted to do this with the mesh plotting function in CairoMakie.

I’m testing my code by trying to reproduce this plot from the pcolormesh documentation.

Here is my attempt:

using GeometryBasics, CairoMakie
x = hcat([range(-0.5, 10, length=10) for i in 1:6]...)'
y = hcat([collect(range(4.5, 11, length=6)) for i in 1:10]...)
X2d = x.+0.2.*y
Y2d = y +0.3.*x
Z2d = hcat([[0.7003673 , 0.74275081, 0.70928001, 0.56674552, 0.97778533,
0.70633485, 0.24791576, 0.15788335, 0.69769852, 0.71995667],
[0.25774443, 0.34154678, 0.96876117, 0.6945071 , 0.46638326,
0.7028127 , 0.51178587, 0.92874137, 0.7397693 , 0.62243903],
[0.65154547, 0.39680761, 0.54323939, 0.79989953, 0.72154473,
0.29536398, 0.16094588, 0.20612551, 0.13432539, 0.48060502],
[0.34252181, 0.36296929, 0.97291764, 0.11094361, 0.38826409,
0.78306588, 0.97289726, 0.48320961, 0.33642111, 0.56741904],
[0.04794151, 0.38893703, 0.90630365, 0.16101821, 0.74362113,
0.63297416, 0.32418002, 0.92237653, 0.23722644, 0.82394557],
[0.75060714, 0.11378445, 0.84536125, 0.92393213, 0.22083679,
0.93305388, 0.48899874, 0.47471864, 0.08916747, 0.22994818]]...)'

data = vec([(Float32(xv), Float32(yv)) for (xv,yv) in zip(vec(X2d), vec(Y2d))])
heights = [i for i in vec(Z2d)]
faces = decompose(QuadFace{GLIndex}, Tesselation(Rect(0, 0, 1, 1), size(X2d)))

msh = GeometryBasics.Mesh(GeometryBasics.Point2f.(data),faces)
fig = CairoMakie.Figure();
ax = Axis(fig[1,1], aspect=1)

CairoMakie.mesh!(ax, msh, color=heights)
display(fig)

This code produces an image that looks like this:

Which is very close to the correct answer except that it seems like the the mesh interpolates the vertex colors. Is there a way to stop that interpolation and to just have a flat color shading on each QuadFace?

You can do this easily if you are using Meshes.jl. We provide a Makie recipe that assigns colors to the quadrangle geometries of a grid (or general mesh), or to the vertices:

using Meshes
using Rotations

import GLMakie as Mke

grid = CartesianGrid(10, 10) |> Rotate(Angle2d(pi/4))

Mke.plot(grid, color = 1:nelements(grid))

Mke.plot(grid, color = 1:nvertices(grid))

Others can share a pure Makie.jl solution with the built-in heatmap, and image and mesh recipes.

You need four separate vertices for each face which all have the same color. The shared vertices of neighboring faces need to be duplicated because they carry a different color for each face.

Exactly. The recipe in Meshes.jl duplicates vertices in polygons to assign the same color to “disconnected” geometries. It works with triangles, quadrangles, or n-gons in general.

Success. Thanks so much. Here’s the Meshes, and Makie code I used to reproduce the pcolormesh plot.

using Meshes
using Rotations
import CairoMakie as CMke

x = hcat([range(-0.5, 10, length=11) for i in 1:7]...)'
y = hcat([collect(range(4.5, 11, length=7)) for i in 1:11]...)
X2d = x.+0.2.*y
Y2d = y +0.3.*x
Z2d = hcat([[0.7003673 , 0.74275081, 0.70928001, 0.56674552, 0.97778533,
0.70633485, 0.24791576, 0.15788335, 0.69769852, 0.71995667],
[0.25774443, 0.34154678, 0.96876117, 0.6945071 , 0.46638326,
0.7028127 , 0.51178587, 0.92874137, 0.7397693 , 0.62243903],
[0.65154547, 0.39680761, 0.54323939, 0.79989953, 0.72154473,
0.29536398, 0.16094588, 0.20612551, 0.13432539, 0.48060502],
[0.34252181, 0.36296929, 0.97291764, 0.11094361, 0.38826409,
0.78306588, 0.97289726, 0.48320961, 0.33642111, 0.56741904],
[0.04794151, 0.38893703, 0.90630365, 0.16101821, 0.74362113,
0.63297416, 0.32418002, 0.92237653, 0.23722644, 0.82394557],
[0.75060714, 0.11378445, 0.84536125, 0.92393213, 0.22083679,
0.93305388, 0.48899874, 0.47471864, 0.08916747, 0.22994818]]...)'

data = vec([(Float32(xv), Float32(yv)) for (xv,yv) in zip(vec(X2d), vec(Y2d))])
Z = collect(vec(reshape(Z2d, (1,60))))

grid= SimpleMesh(data, GridTopology(6,10))
CMke.plot(grid, color = Z)

Another one. I a mix of the above and this non-regular example

using GMT

X,Y = GMT.meshgrid(-3:6/17:3);
XX = X .+ 0.2 * Y;
YY = Y .+ 0.3 * X;

pcolor(XX,YY, reshape(repeat([1:18; 18:-1:1], 9,1), size(XX)), lc=:black, show=true)

Please reply to Python pcolormesh() alternative in Julia