3

I am importing the data for my plot from a .dat file produced in matlab. I would also like to set axis limits from a .dat file. Is there a way to set xmin, xmax, ymin and ymax from a table in a .dat matrix (like the data plotted later)? How I'm currently setting the axis limits is shown below.

\documentclass{standalone}
\usepackage{tikz} 
\usepackage{pgfplots}
\usepackage{pgf,pgffor}
\pgfplotsset{compat=1.15}

\def\names{{Folder1/}{Folder2/}{Folder3/}}

\foreach \x in \names{
\graphicspath{ \x {Icons/}}  

\begin{document}

    \begin{tikzpicture} 

    \begin{axis}[
    enlargelimits = false,
    hide axis,
    ]
        \addplot graphics [
            xmin=-80.5430, xmax=-80.5150,
            ymin=43.4580, ymax=43.4740,
            ]{ov2.png};
        \addplot[
            only marks,
            mark=text,
            text mark={\includegraphics[scale=0.02]{icon.png}}
        ]
        table [search path={\x}]{overnight.dat};
        \end{axis}
    \end{tikzpicture}

\end{document}

Rather than define the xmin xmax in the code I would like to have them defined in a .dat file containing the axis limits (they are not a function of the data being plotted they are the GPS coordinates of the corners of the image ov2.png being overlaid)

3
  • 1
    Could you perhaps consider making the question more precise? Which information is in the .dat file? The actual xmin, xmax, ymin and ymax, or a set of x and y values from which one has to determine these values?
    – user121799
    Commented Jul 18, 2018 at 16:01
  • It appears you are using a separate file for each \addplot, where the columns are titled x and y. Once can read such a file using \pgfplotstable and extract individual numbers using \pgfplotstablegetelem. [xmin={\xmin}] Commented Jul 18, 2018 at 20:43
  • Can you please provide code we can compile? Your code right now is just a snippet of a document, lacking lots of essential parts and reliant on external files we don't have. So we can't play around with it to try anything out.
    – cfr
    Commented Jul 23, 2018 at 1:14

1 Answer 1

4

As already mentioned, you can use \pgfplotstablegetelem to access an individual element of a data file. This requires you to know the row and the column of it. The value is returned in \pgfplotsretval. Columns can be referenced by name and rows by their index, starting with 0.

It is also possible to loop through a column and do something with each value, using \pgfplotstableforeachcolumnelement. This can, for example, be used to find the minimum, maximum or average.

It's a good idea, to write a few macros for this, especially in the second case. The following code shows some examples:

\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\usepackage{filecontents}

\begin{filecontents}{data.csv}
x y
-1.5 27.3
-1.0 24.8
-0.5 22.1
0.0 30.7
0.5 11.3
1.0 15.9
1.5 20.4
2.0 21.8
2.5 22.8
\end{filecontents}

% read the table
\pgfplotstableread{data.csv}\datatable

% get specific element and store it in a macro
% #1: table
% #2: row
% #3: column (name or [index]<index>)
% #4: macro for value
\newcommand*{\GetElement}[4]{%
    \pgfplotstablegetelem{#2}{#3}\of{#1}%
    \let#4\pgfplotsretval
}

% get the first element of a column and store it in a macro
% #1: table
% #2: column (name or [index]<index>)
% #3: macro for value
\newcommand*{\GetFirstElement}[3]{%
    \GetElement{#1}{0}{#2}{#3}%
}

% get the last element of a column and store it in a macro
% #1: table
% #2: column (name or [index]<index>)
% #3: macro for value
\newcommand*{\GetLastElement}[3]{%
    \pgfplotstablegetrowsof{#1}%
    \pgfmathsetmacro\lastrowidx{int(\pgfplotsretval - 1)}%
    \GetElement{#1}{\lastrowidx}{#2}{#3}%
}

% get maximum and minimum value of a column and store them in macros
% #1: table
% #2: column
% #3: macro for max
% #4: macro for min
\newcommand*{\GetMinMax}[4]{%
    \pgfmathsetmacro#3{-16383}%
    \pgfmathsetmacro#4{16383}%
    \pgfplotstableforeachcolumnelement{#2}\of{#1}\as\cellValue{%
        \ifx\cellValue\@empty\else
            \pgfmathsetmacro{#3}{max(#3,\cellValue)}%
            \pgfmathsetmacro{#4}{min(#4,\cellValue)}%
        \fi
    }
}

% get average of column and store it in a macro
% #1: table
% #2: column
% #3: macro for average
\newcommand*{\GetAverage}[3]{%
    \pgfplotstablegetrowsof{#1}%
    \let\rownumber\pgfplotsretval
    \def#3{0}%
    \pgfplotstableforeachcolumnelement{#2}\of{#1}\as\cellValue{%
        \ifx\cellValue\@empty
            % don't count emplty cells
            \pgfmathsetmacro{\rownumber}{\rownumber - 1}%
        \else
            \pgfmathsetmacro{#3}{#3 + \cellValue}%
        \fi
    }
    \pgfmathsetmacro{#3}{#3 / \rownumber}%
}


\GetMinMax{\datatable}{x}{\dataxmax}{\dataxmin}
\GetMinMax{\datatable}{y}{\dataymax}{\dataymin}
\GetElement{\datatable}{5}{y}{\value}
\GetFirstElement{\datatable}{y}{\first}
\GetLastElement{\datatable}{y}{\last}
\GetMinMax{\datatable}{x}{\dataxmax}{\dataxmin}
\GetMinMax{\datatable}{y}{\dataymax}{\dataymin}
\GetAverage{\datatable}{y}{\average}

\begin{document}
\begin{tikzpicture}
\begin{axis}[%
    xlabel=$x$-label,
    ylabel=$y$-label,
    xmin=\dataxmin, xmax=\dataxmax,
    ymin=\dataymin, ymax=\dataymax,
]
\addplot table[x=x,y=y] {\datatable};
\draw[red] (axis cs:\dataxmin,\value) -- node[pos=0.35, above] {\value} (axis cs:\dataxmax,\value);
\draw[green] (axis cs:\dataxmin,\first) -- node[pos=0.07, above] {\first} node[pos=0.93, above] {\last} (axis cs:\dataxmax,\last);
\draw[cyan] (axis cs:\dataxmin,\average) -- node[pos=0.25, below] {average $=$ \average} (axis cs:\dataxmax,\average);
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

1
  • 1
    Some commands are very similar to what one finds here (and also here)...
    – user121799
    Commented Jul 23, 2018 at 18:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .