4

This is the simplified version of this question. While the other question contains raw data consisting of real dates, in this question I have converted the raw dates to decimal date values (unit: hours) in the very first column.

Consider the following Minimum Working Example (MWE):

\documentclass[tikz]{standalone}
\usepackage{pgfplots, filecontents}

\begin{filecontents*}{data.dat}
0.000 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 2   2
0.083 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 3   3
0.167 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 4   4
0.250 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 5   5
0.333 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 6   6
0.417 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 7   7
0.500 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 8   8
0.583 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 9   9
0.667 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 10  10
0.750 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 11  11
\end{filecontents*}

\begin{document}

    \begin{tikzpicture}
        \begin{axis}[view={0}{90}]
            \addplot3[surf, mesh/cols=10] table {data.dat};
        \end{axis}
    \end{tikzpicture}

\end{document}

Explanation of the table: First column serves the date as decimal_date (unit: hours), rest of the table is y-columns including a z-value in each cell for each heatmap coordinate. Furthermore, the column index numbers from 1 to 10 also provide the real index numbers of each column in reality. For example, with 10 columns, the y-values of the heatmap would go from 1 to 10.


Screenshot of the result:

Screenshot of the current state


How do I have to configure the plot to get the following behavior:

  • first column of data table (decimal hours) should provide x-axis values (= 10 pcs)
  • index numbers of columns should provide y-axis values (= 10 pcs)
  • cell values should provide corresponding heatmap coordinate values (= 100 pcs)

In the end it should look like this (no colorbar required):

Screenshot of the desired state

crateane
  • 2,217
Dave
  • 3,758
  • Is your data whitespace-delimited? In the other question, the data has semicolons. In my answer, each line of a file is splitted at whitespaces with the line for v in string.gmatch(line, "%S+") do. The %S would need to be replaced appropriately for other delimiters (which should of course not occur in the data items) – crateane Aug 03 '19 at 21:21

1 Answers1

3

Basically, this seems to be the problem of reordering the matrix data into a vector. The easiest solution is certainly to save the data in a format suitable for pgfplots. But it is also possible to reorder the data with the help of a lua script. I have adapted another answer of mine tackling the same problem, but with a slightly different data structure.

\documentclass[tikz]{standalone}
\usepackage{pgfplots,filecontents,luacode}
\pgfplotsset{compat=1.16}

\begin{filecontents*}{data.dat}
0.000 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 2   2
0.083 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 3   3
0.167 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 4   4
0.250 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 5   5
0.333 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 6   6
0.417 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 7   7
0.500 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 8   8
0.583 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 9   9
0.667 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 10  10
0.750 0.083   0.25    0.25    0.2 0.22    0.45    0.6 0.5 11  11
\end{filecontents*}


\begin{filecontents}{mat-rewrite.lua}
\begin{luacode}

function rewrite_mat(infilename, outfilename)
  infile  = io.open( infilename, "r")
  outfile = io.open(outfilename, "w")

  ynum = 0
  xnum = 0
  yvals={}
  xvals={}
  zvals={}

  for line in infile:lines() do
    t={}                               -- make a table from the line (whitespace-delimited)
    length=0
    for v in string.gmatch(line, "%S+") do
      length = length + 1
      t[length]=v
    end 

    if ynum == 0 then
      ynum = length - 1
    end

    xnum = xnum + 1                    -- count number of x values 

    xvals[xnum]=t[1]                 -- all other lines: store x and z values
    for y=1,ynum do
      index = ynum*(xnum-1)+y
      zvals[index]=t[y+1]
    end
  end

  infile:close()
  --znum = xnum * ynum  -- not needed

  for x = 1,xnum do
    for y = 1,ynum do
      -- commented debug output
      --tex.print(xvals[x], yvals[y], zvals[(x-1)*ynum+y],"") 
      --print(xvals[x], yvals[y], zvals[(x-1)*ynum+y],"") 
      outfile:write(xvals[x] .. " " .. y .. " " .. zvals[(x-1)*ynum+y] .. " " .. "\string\n")
    end
  end

  outfile:close()

end  
\end{luacode}
\end{filecontents}
% load function
\input{mat-rewrite.lua}
% run function mat-in.txt for structure, mat-in2 for matrix with values


\begin{document}
\directlua{rewrite_mat("data.dat","out.txt")}
\begin{tikzpicture}
\begin{axis}[mesh/ordering=y varies, unbounded coords=jump,colorbar,title={data from infrared measurements},view={0}{90},xlabel=$x$,ylabel=$y$,colorbar style={xlabel=$^\circ\mathrm{C}$,xticklabel pos=upper,xlabel style={yshift=.22cm}}]
\addplot3[surf,mesh/rows=10] 
  table {out.txt};
\end{axis}
\end{tikzpicture}
\end{document}

The output looks similar to your example, but with different data values. The height adjustment of °C is done quick and dirty with the yshift option.

enter image description here

crateane
  • 2,217