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

  • 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) – Faekynn Aug 3 at 21:21
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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