Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
I could come with a lualatex solution, if you are interested, but there are also "pure latex" packages to read and manipulate tabulated data. –  JLDiaz Mar 13 '13 at 18:39
    
@JLDiaz, I'm more interested in "pure latex" packages, but if LuaLaTeX's proves the better way to go, I won't rule out accepting an answer based on that approach. –  Richard Mar 13 '13 at 18:40
    
You can use the datatool package to read data from a file and then manipulate it as desired. –  Peter Grill Mar 13 '13 at 19:39
3  
have you seen Drawing heatmaps using TikZ –  cmhughes Mar 13 '13 at 20:33
add comment

1 Answer

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.

share|improve this answer
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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