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.

2 Likes

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.

1 Like

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)

2 Likes

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)

1 Like

Please reply to Python pcolormesh() alternative in Julia