# Plotting matrix image data

I have data from infrared measurements in a file with 194 rows and 194 columns, each value representing the temperature at a certain pixel.

As the image from the camera does not look nice, I would like to plot it with pgfplots in a similar way. This means for each value in my data matrix, a certain color should be plotted.

The data matrix looks like this:

22.93   22.97   23.07   23.11   23.11
23.1    23.05   23.1    23.12   23.12
23.11   23.3    23.3    23.17   23.18
23.08   23.11   23.3    23.17   23.18
23.12   23.1    23.18   23.22   23.14


My most promising try was the following code:

\begin{tikzpicture}
\begin{axis}

\pgfplotstableread{pictures/test.txt} \datatable
\addplot3[surf, shader=interp, mesh/rows=5]table from \datatable;

\end{axis}
\end{tikzpicture}


That's the outcome.

I wish to obtain a density plot as shown in the following picture (the colorbar on the right is not a problem, I found the solution with groupplot...):

## 3 Answers

Something like this? The drawback is, you have to adopt the data format.

\documentclass[tikz]{standalone}

\usepackage{pgfplots, filecontents}

\begin{filecontents*}{temp.dat}
0 0 22.93
1 0 22.97
2 0 23.07
3 0 23.11
4 0 23.11

0 1 23.1
1 1 23.05
2 1 23.1
3 1 23.12
4 1 23.12

0 2 23.11
1 2 23.3
2 2 23.3
3 2 23.17
4 2 23.18

0 3 23.08
1 3 23.11
2 3 23.3
3 3 23.17
4 3 23.18

0 4 23.12
1 4 23.1
2 4 23.18
3 4 23.22
4 4 23.14
\end{filecontents*}

\begin{document}

\begin{tikzpicture}
\begin{axis}[view={0}{90},
xlabel=$x$,
ylabel=$y$,
colorbar,
colorbar style={
title=$^\circ C$,
yticklabel style={
/pgf/number format/.cd,
fixed,
fixed zerofill
}
},
title=data from infrared measurements]
\addplot3[surf] file {temp.dat};
\end{axis}
\end{tikzpicture}

\end{document}


• That solution looks pretty good!! Many thanks! I had to make some adjustments (the yicklabel style didnt't work for some reason). I was able to get it running with just a couple of data. Whith 194x194 however the latex-memory gets a problem (of course). Do you know a solution how to increase the memory size? Error says "TeX capacity exceeded, sorry [main memory size=3000000] – nmy2015 Jul 16 '15 at 3:19
• I managed to somewhat get it compiled when using lualatex instead of pdflatex. The picture shows in the main document but is not externalized as a pdf file. I receive the following error message: Package tikz Error: Sorry, the system call 'pdflatex -halt-on-error -interact – nmy2015 Jul 16 '15 at 6:42

Using the matrix plot* feature of PGFPlots v1.13 should exactly do what you want (see section 4.6.12 on page 164 of the manual). I assume you want to show the values of the pixels as given in your data points.

If so, using surf (only) doesn't do what you want, because then the a cell is build from "surrounding" coordinates showing the mean value of these surrounding coordinates. That means that mean coordinate for the lower left cell is (0.5,0.5) and has a temperature of around 23.0°C. And because of this behavior you just get a 4x4 matrix although your input is a 5x5 matrix.

It gets a bit better when using surf,shader=flat corner where you also (just) get a 4x4 matrix, but the cell temperature is taken from the lower left coordinate of the cell, e.g. (0,0) for the lower left cell. As you can see now, the temperature is much lower (in color: more blue) then compared to the upper variant.

Only with matrix plot* you will get the 5x5 matrix where the center of the cell is the specified coordinate also showing the corresponding temperature.

\documentclass[tikz]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots}
\begin{filecontents*}{temp.dat}
0 0 22.93
1 0 22.97
2 0 23.07
3 0 23.11
4 0 23.11

0 1 23.1
1 1 23.05
2 1 23.1
3 1 23.12
4 1 23.12

0 2 23.11
1 2 23.3
2 2 23.3
3 2 23.17
4 2 23.18

0 3 23.08
1 3 23.11
2 3 23.3
3 3 23.17
4 3 23.18

0 4 23.12
1 4 23.1
2 4 23.18
3 4 23.22
4 4 23.14
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
view={0}{90},   % not needed for matrix plot*' variant
xlabel=$x$,
ylabel=$y$,
colorbar,
colorbar style={
title=$^\circ \mathrm{C}$,
yticklabel style={
/pgf/number format/.cd,
fixed,
precision=1,
fixed zerofill,
},
},
title=data from infrared measurements,
%
% added these key-values
enlargelimits=false,
axis on top,
point meta min=22.9,
point meta max=23.3,
%
% uncomment me to show, that there are really no cells plotted
% when using the second variant (surf, shader=flat corner')
%xmax=5,
%ymax=5,
]
%% gives the mean temperature of the neighbouring cells (4x4 matrix)
%\addplot3 [surf] file {temp.dat};

%% gives the temperature of each point where the reference point
%% is the lower left corner of the cell (also a 4x4 matrix)
%% (I already asked the package author if this is intended or a bug)
%\addplot3 [surf,shader=flat corner] file {temp.dat};

% this should give the desired output (5x5 matrix)
\addplot [matrix plot*,point meta=explicit] file [meta=index 2] {temp.dat};
\end{axis}
\end{tikzpicture}
\end{document}


Many thanks sergej, for your very valuable answer.

I managed to get it running now with all the big data I'm using.

Here's the code I applied:

\tikzsetnextfilename{temp1C50DOD}
\begin{tikzpicture}
\begin{axis}
[view={0}{90},
xlabel=$x$,
ylabel=$y$,
colorbar,
colorbar style={
title=$^\circ C$,
yticklabel style={/pgf/number format/.cd, fixed zerofill, precision=1}
},
title=
]

\addplot3[surf, shader=interp, mesh/rows=194]file {pictures/test2.txt};

\end{axis}
\end{tikzpicture}


My test2.txt looks like you suggested. (with an excel macro it was easy to sort the data accordingly). The Macro looks like this:

Sub Columns2Column()
'
' Columns2Column Macro
'

'
Dim i As Integer
Dim j As Integer
Dim lngZeile As Long
With ActiveSheet
For i = 2 To .Cells(1, .Columns.Count).End(xlToLeft).Column
lngZeile = lngZeile + 194
For j = 1 To 194
.Cells(lngZeile + j, 1).Value = Cells(j, i).Value
Next j
Next i
End With
End Sub


Additionally, as the big data were too much I changed to lualatex instead of pdflatex by just replacing the exe file in the command configuration of my editior.

As tikz externalize still didn't work with this, I had to add the following lines into my header file:

\tikzset{external/system call={lualatex
\tikzexternalcheckshellescape -halt-on-error -interaction=batchmode
-jobname "\image" "\texsource"}}


I hope this solution helps others as well :)

And here is the beautiful outcome:

• The outcome is really beautiful! Thanks for sharing. – sergej Jul 16 '15 at 8:13
• You can add yticklabel style={/pgf/number format/.cd, fixed zerofill, precision=1} to the colorbar style to get a decimal point and a trailing zero after the 23. – sergej Jul 16 '15 at 8:21
• Thanks sergej, I did that and added it to above code. Nice thing! I only now have the problem, if I want to create a second such picture with different data, it does run in errors whose origin I can't really figure out at the moment. It seems, lualatex and externalize still have their problems with each other. It says: Syntax error: couldn't find trailer dictionary Syntax error: Couldn't read xref table. Anyone any idea what this means? – nmy2015 Jul 16 '15 at 10:25
• I found out, how this problem can be solved: \tikzexternalize needs to get the option optimize=false so it works. I just have one more question: As I have multiple plots, I'd like to adjust the colorbar to a certain range that is applicable for all plots. Is there any option to set the range of the colorbar? – nmy2015 Jul 20 '15 at 10:17
• It seems optimize=false was not the proper solution. What finally really helped to compile the document without problems with all the tikz-pictures was to update ALL packages and to remove inputenc, which does not work together with lualatex. (see thread here: tex.stackexchange.com/questions/256081/…) – nmy2015 Jul 30 '15 at 2:46