10
$\begingroup$

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}]

enter image description here

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]

enter image description here

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?

$\endgroup$
2
  • $\begingroup$ @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? $\endgroup$
    – josh
    Jun 14 at 19:49
  • $\begingroup$ @Michael E2: Ok. I meant map onto the surface of f(x,y). Changed title. $\endgroup$
    – josh
    Jun 14 at 20:03

3 Answers 3

12
$\begingroup$

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,
   MeshShading -> Reverse@errorTable,
   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.

$\endgroup$
6
  • $\begingroup$ Can speed it up a little withmem : memRasterize[expr_] := mem = Rasterize[expr, ImageSize -> 400] and memRasterize[n] instead of Rasterize[...] $\endgroup$
    – Michael E2
    Jun 14 at 20:16
  • $\begingroup$ 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. $\endgroup$
    – josh
    Jun 14 at 20:51
  • $\begingroup$ @josh MaTeX does not need the memoization, since it caches its results automatically. $\endgroup$
    – Michael E2
    Jun 14 at 21:17
  • $\begingroup$ The MaTex version looks publish-quality! Appreciate your work. Will set a bounty when eligible. $\endgroup$
    – josh
    Jun 14 at 21:33
  • $\begingroup$ I appreaciate your help in this matter. I chose ImportString below for the bounty because it's simple and fast. $\endgroup$
    – josh
    Jun 17 at 23:00
5
+100
$\begingroup$

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]

enter image description here

$\endgroup$
4
  • $\begingroup$ 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! $\endgroup$
    – josh
    Jun 16 at 12:35
  • $\begingroup$ +1 but why not just use pic = Rasterize[grid]? $\endgroup$
    – Michael E2
    Jun 16 at 15:13
  • $\begingroup$ @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. $\endgroup$
    – cvgmt
    Jun 16 at 15:43
  • $\begingroup$ 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.) $\endgroup$
    – Michael E2
    Jun 16 at 16:05
3
$\begingroup$

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]]]];

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.