# Mapping a numerical array of numbers onto the surface of f(x,y) possible?

I'm considering mapping an error estimate matrix onto the surface of a function f(x,y) in the indicated range:

theF[x_, y_] = -1.295 + y (-0.1098 - 0.43 Log[x]) - 2.36 Log[x]
Plot3D[theF[x, y], {x, 0.056, 0.83}, {y, 50, 508}, PlotRange -> All,
BoxRatios -> {1, 1, 1}]


For a matrix of points in the plot range, there is an error matrix assigning to each point, a corresponding non-negative error code:

errorTable = {{8, 7, 6, 5, 4, 4, 3, 3, 3, 2, 2, 1, 2, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0}, {8, 7, 6, 5, 4, 4, 4, 3, 2, 2, 2, 2, 1, 1,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {7, 6, 5, 5, 4, 3, 3, 3, 2, 2,
2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {6, 5, 5, 4, 4, 3,
3, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, {7, 6,
5, 4, 4, 4, 3, 3, 3, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1}, {7, 6, 5, 4, 4, 4, 4, 3, 2, 2, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1}, {7, 6, 5, 4, 4, 4, 3, 3, 3, 3, 2, 3, 2, 2, 2, 2,
2, 1, 1, 1, 1, 1, 1, 1, 1}, {7, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2,
2, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1}, {5, 4, 4, 4, 3, 4, 3, 3,
3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, {6, 5, 5, 5,
4, 4, 4, 3, 4, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 2, 2, 2, 2, 2, 2}};


The dimension of errorTable is {10,25} and as an example, can just use a random matrix:

errorTable = Table[RandomInteger[{0, 8}], {10}, {25}]


For example, in the matrix above errorTable[[1,1]]=8 and that corresponds to the error for the point (x,y)=(0.056,50) and so forth. I know how to create an ArrayPlot and color the error codes and then map this plot as a texture to the surface of f:

theF[x_, y_] = -1.295 + y (-0.1098 - 0.43 Log[x]) - 2.36 Log[x]
ap = ArrayPlot[errorTable,
ColorRules -> {-1 -> Red, 0 -> Black, 1 -> Blue, 2 -> Green,
3 -> Yellow, 4 -> Purple, 5 -> Orange, 6 -> White, 7 -> Magenta,
8 -> Pink}];

cPlot = Plot3D[
theF[x, y], {x, Abs[aVals[[1]]], Last@Abs[aVals]}, {y, 50,
seriesSize}, Mesh -> False, PlotStyle -> {Texture[ap]},
TextureCoordinateFunction -> ({#1, #2} &), BoxRatios -> {1, 1, 1},
PlotRange -> All]


And I could add a legend but it's not quickly comprehensible and confussing-looking. Is there a way to map the error matrix numbers directly onto F in a clear and easy to read way and if so could someone help me do this?

• @Michael E2: Don't understand your question. I mean to write the numbers on the surface of f(x,y) but not just write graphics numbers over the corresponding point (x,y,z) but rather write the numbers as a texture onto the surface?
– josh
Jun 14 at 19:49
• @Michael E2: Ok. I meant map onto the surface of f(x,y). Changed title.
– josh
Jun 14 at 20:03

Via MeshShading and Texture:

theF[x_, y_] = -1.295 + y (-0.1098 - 0.43 Log[x]) - 2.36 Log[x];
pp = Plot3D[theF[x, y], {x, 0.056, 0.83}, {y, 50, 508},
PlotRange -> All, BoxRatios -> {1, 1, 1},
Mesh -> Reverse@Dimensions@errorTable - 1,
TextureCoordinateFunction -> (Evaluate[
Reverse@Dimensions@errorTable {#1, #2}] &)];

pp /. {a___, n_, g_GraphicsGroup, b___} :> {a,
Texture[Rasterize[n, ImageSize -> 400]], g, b}


Update: Via MaTeX

(* ResourceFunction["MaTeXInstall"][] (* if needed *)*)
Needs@"MaTeX"
pp /. {a___, n_, g_GraphicsGroup, b___} :>
{a, Texture[MaTeX[n]], g, b}


Update 2: Color

Replace MaTeX[n] by something like one of the following to color the surface.

Show[MaTeX[n], Background -> GrayLevel[0.5 + n/16]]
Show[MaTeX[n], Background -> Lighter@ColorData["Rainbow"][n/8]]


I'd also recommend Lighting -> "Neutral" in original Plot3D, so that the colors of the lights don't affect the colors on the surface.

• Can speed it up a little withmem : memRasterize[expr_] := mem = Rasterize[expr, ImageSize -> 400] and memRasterize[n] instead of Rasterize[...] Jun 14 at 20:16
• Your mem code dropped the timing from about 20 seconds to one second on my machine. Nice improvement! It looks nice. Didn't think this was possible. Thank you.
– josh
Jun 14 at 20:51
• @josh MaTeX does not need the memoization, since it caches its results automatically. Jun 14 at 21:17
• The MaTex version looks publish-quality! Appreciate your work. Will set a bounty when eligible.
– josh
Jun 14 at 21:33
• I appreaciate your help in this matter. I chose ImportString below for the bounty because it's simple and fast.
– josh
Jun 17 at 23:00

Use Grid and export it to "PNG".

theF[x_, y_] = -1.295 + y (-0.1098 - 0.43 Log[x]) - 2.36 Log[x];
errorTable = Table[RandomInteger[{0, 8}], {10}, {25}];
grid = Grid[errorTable, Frame -> All,
ItemStyle -> {FontFamily -> Times, 20}];
(* pic=ImportString[ExportString[grid,"PNG"]] *)
pic = First[
ImportString[ExportString[grid, "PDF"], {"PDF", "PageGraphics"},
"TextOutlines" -> True]]
Plot3D[theF[x, y], {x, 0.056, 0.83}, {y, 50, 508}, PlotRange -> All,
BoxRatios -> {1, 1, 1}, PlotStyle -> Texture[pic], Mesh -> None,
PlotPoints -> 50]


• Very nice and compact. Takes 1.2 seconds on my machine! The numbers are very clear and readable and even though the random matrix looks confussing, in my application there is a distinct distribution, like above example, which is almost instantly comprehended when viewed and that is my desire without the need to make some mental color-conversion. Thank you!
– josh
Jun 16 at 12:35
• +1 but why not just use pic = Rasterize[grid]? Jun 16 at 15:13
• @MichaelE2 Thanks! I also test the Rasterize approach. But I also want to test whether the texture suport vector format such asPDF,that is when we use pic = First[ImportString[ExportString[grid, "PDF"], {"PDF", "PageGraphics"}, "TextOutlines" -> True]]. So I post the above code. Jun 16 at 15:43
• Did it support vector graphics? I tried it and it seemed not to work. But maybe there's a way around. (MaTeX produces vector graphics, too, which it why I tried it.) Jun 16 at 16:05

Adding these lines after the definition of errorTable in the previous answers keeps both the colors (showing the distribution) and the numbers.

colors = <|-1 -> Red, 0 -> Black, 1 -> Blue, 2 -> Darker@Green,
3 -> Gray, 4 -> Purple, 5 -> Orange, 6 -> Brown, 7 -> Magenta,
8 -> Pink|>;
errorTable = errorTable /. a_Integer :> Style[a, colors[[Key[a]]]];
`