9

I have a grid file with data such as:

5
4
0 0 0 0 0
0 1 1 2 0
0 2 2 1 0
3 0 0 3 1

where 5 is the width of the grid, 4 is the height, and each number in the grid corresponds to an elevation. I can cut out the 5 and 4 if necessary.

I'd like to display this as a grid of coloured squares in LaTeX with the numbers printed in the center of each square.

I know how to draw rectangles and labels with TikZ, so I think I can figure that part out. It's reading in the data (and converting the numbers to a colour) that is stumping me. Any thoughts on how I could do it?

Richard
  • 5,723

1 Answers1

8

Lualatex solution:

\begin{tikzpicture}
\directlua{grid = readGridFile("example.dat"); 
           plot(grid)}
\end{tikzpicture}
\end{document}

Result

Now the whole document. Note that I used package filecontents to include in a single source all the required files to typeset the example. You can safely remove those filecontents* environments after the first compilation, since you will have then the required files example.dat and gridlua.lua.

\documentclass{standalone}
\usepackage{luacode}
\usepackage{tikz}
\usepackage{filecontents}

\begin{filecontents*}{gridlua.lua}
function readGridFile(filename)
  local f, columns, rows
  local grid={}
  f = io.open(filename, "r")
  columns = tonumber( f:read("*line") )    -- To convert it to int
  rows    = tonumber( f:read("*line") )
  for i = 1, rows, 1 do
     local row = {}
     line = f:read("*line")
     for data in line:gmatch("%w+") do table.insert(row, data) end
     table.insert(grid, row)
  end
  return grid
end

function plot(grid)
  for i,row in ipairs(grid) do
    for j, data in ipairs(row) do
        tex.print(string.format(
             "\\node[data, style%d] at (%d,%d) (data%d%d) {%d};", 
             data, j, -i, j, i, data))
    end
    tex.sprint("\\par")
  end
end
\end{filecontents*}

\begin{filecontents*}{example.dat}
5
4
0 0 0 0 0
0 1 1 2 0
0 2 2 1 0
3 0 0 3 1
\end{filecontents*}

\directlua{dofile("gridlua.lua")}

\begin{document}
\tikzset{
    data/.style = {draw, rectangle, inner sep=0pt, minimum width=1cm, 
        minimum height = 1cm},
    style0/.style = { fill=white },
    style1/.style = { fill=yellow!60 },
    style2/.style = { fill=orange!60 },
    style3/.style = { fill=red!80 },
}

\begin{tikzpicture}
\directlua{grid = readGridFile("example.dat"); 
           plot(grid)}
% You can even point to some particular datum:
% \draw[<-, shorten <=-5pt] (data42) to[bend left] +(3,2) node[right]{See here};
\end{tikzpicture}
\end{document}

The lua code generates tikz commands to create the graphical grid, and assigns an automatic name to each node, which is dataXY. For example, 0 at the top left corner will be named data11, and the 1 at the bottom left will be data54.

JLDiaz
  • 55,732
  • 2
    At first my jaw dropped and I thought "It cannot be that easy". Then I saw the rest of your document and I realized it was not quite that easy :-) – Richard Mar 13 '13 at 20:13