# How to annotate a Grid?

I have the following grid, which is a partial table for the linear function f[x]:

f[x_] := 2 x + 3
Grid[Join[{{x, y}}, Table[{i, f[i]}, {i, 0, 4}]],
Dividers -> {{2 -> Directive[Red, Thin]}, {2 ->
Directive[Red, Thin]}}, Alignment -> {Right, Center}]


What I'd like to do is annotate this grid, to indicate the slope and y-intercept of f[x], as the following graphic shows:

I can figure out how to draw the dashed ellipse and colored arrows on my own. What I can't figure out is how to add these graphical annotations to the grid. Is this possible?

(Note that f[x] will be defined "on the fly", and so including a static image is not a possible solution.)

-
wrong construct for what you are doing. Use Graphics for this sort of thing. Arrows, circles, lines,ellipses, etc..., these are Graphics things. Grid is meant for basic control of structured data, not meant for general purpose graphics board. –  Nasser Aug 26 '13 at 23:50
@Nasser: Well ideally I could overlay the Graphics with the Grid using Show, Overlay, etc. But this doesn't work. I will have to disagree that this is the wrong construct. –  Steve D Aug 26 '13 at 23:54
It is a wrong construct. You want graphics, use GraphicsGrid, and use Graphics to draw the other items. Grid is not graphics. –  Nasser Aug 26 '13 at 23:55
You can use Show if you Rasterize your Grid. This is a viable way to go unless you want to export vector graphics (.eps, .svg). –  Pickett Aug 27 '13 at 0:26
@Nasser: perhaps you could post an example of how to achieve this table with the graphics using GraphicsGrid. I don't see how using a GraphicsGrid alleviates the need to connect different cells with arrows, etc. –  Steve D Aug 27 '13 at 0:29

In your case, the biggest advantage of GraphicsGrid over Grid is the Epilog option which allows you to put the additional elements over your grid of numbers:

f[x_] := 2 x + 3
GraphicsGrid[
Join[{{Style[x, 36], Style[y, 36]}},
Table[{Style[i, 36], Style[f[i], 36]}, {i, 0, 4}]],
Dividers -> {{2 -> Directive[Red, Thin]}, {2 ->
Directive[Red, Thin]}}, Alignment -> {Right, Center},
Epilog -> {
{Dashed, Circle[{480, -570}, {400, 136}]},
{Blue, Arrow[{{679, -567}, {1028, -1000}}],
Arrow[{{679, -1000}, {1028, -1000}}]},
{Black, Text[Style[2, 26], {1058, -1000}]}
}, ImagePadding -> {{0, 70}, {0, 0}}
]


It is a bit inconvenient to determine the coordinates of the GraphicsGrid but you can play around with the individual elements within a Manipulate to get the shapes where you want them.

-
Wow, thanks! I'll try that out now and see if I can find a way to "automate" finding the coordinates for the arrows. –  Steve D Aug 27 '13 at 1:24

Since an example using GraphicsGrid is posted, here is an example using direct Graphics.

It is good to try to separate the data from presentation. Also, since we use Mathematica, then lets try to automate things a little more.

So, this function takes list of data as it, and draw it. It uses only 2 parameters, which you can either fix or supply. There are the x,y spacings in the table. Here is a small Manipulate around the function to illustrate. You can easily adjust things as needed. (add color, etc...)

Manipulate[

Module[{i},
data = Table[{i, f[i]}, {i, 0, n}];
tbl[data, delX, delY] ],

{{n, 4, "how big?"}, 2, 20, 1},
{{delX, 0.06, "x spacing?"}, 0.02, 0.1, 0.01},
{{delY, 0.03, "y spacing?"}, 0.02, 0.1, 0.01},

Initialization ->
(
f[x_] := 2 x + 3;

tbl[lst_List, delX_, delY_] :=
Module[{n = Length[lst], sideItem = 2},

getRow[i_, y_] := {Text[ Style[lst[[i, 1]], Large], {0, y}],
Text[ Style[lst[[i, 2]], Large], {delX, y}]};
getArrowDown[j_] := Arrow[{{1.08 delX, j}, {1.5 delX, j - delY}}];
getArrowRight[j_] := Arrow[{{1.08 delX, j}, {1.5 delX, j}}];
getSideItem[j_] := Text[Style[sideItem, Large], {1.6 delX, j}];

Text@Graphics[
{
Text[Style["x", Italic, Large], {0, 0}],
Text[Style["y", Italic, Large], {delX, 0}],

Table[getRow[i, -i*delY], {i, n}],
Table[getArrowDown[-i*delY], {i, n - 1}],
Table[getArrowRight[-i*delY], {i, 2, n}],
Table[getSideItem[-i*delY], {i, 2, n}],

Line[{{delX/2,delY/2}, {delX/2, -(n + 1)*delY}}],(*vertical line*)
Line[{{-delX/2, -delY/2}, {1.5 delX, -delY/2}}] ,(*horizontal line*)
{Dashed, Circle[{delX/2, -delY}, {delX, 0.4 delY}]}
},
PlotRange -> {{-.03, .2}, {.03, -.4}},Frame->False, Axes->False,ImageSize->300
]
];
)
]

-
This is really nice. Not just the result but the way the code is written. If you don't mind, what does Text@Graphics do? –  Pickett Aug 27 '13 at 10:25
@Anon, probably not needed here. It is a habit. I normally wrap the top-most evaluation graphics or expression returned, which is meant for display ofcourse, with Text@, It makes text in embedded expressions look better. Compare: Text[Row[{"test"}]] vs Row[{"test"}] for example. So instead of wrapping everything with Text@, I put Text@ around the whole thing. In this example, I might not have needed it, since I have Text inside already. But as I said, I just throw it there by habit sometimes ;) –  Nasser Aug 27 '13 at 10:31
I see, that's good to know. Ty. –  Pickett Aug 27 '13 at 14:16