2

I am using pgfplots to automatically plot data of a csv file. The file always maintains the same structure, but some times (e.g. sensor not connected...) there are no coodinates to plot for a particular data line (filled with nan). Then, pgfplots only shows the label name, but since there are no data points, the data do not match the legend name.

In the following MWE, the second legend entry is used for the third row.

\documentclass[multi]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

% In this example, the second dataline is all nan - but in general
% any data line (or here CSV-column) might be nan
\begin{filecontents}{plots.csv}
x1,y1,x2,y2,x3,y3
0,1,0,nan,0,3
1,1,1,nan,1,3
2,2,2,nan,2,4
3,2,3,nan,3,4
\end{filecontents} 

\begin{document}



\begin{tikzpicture}
    \begin{axis}[ymin=0]
    \addplot table  [x=x1, y=y1, col sep=comma] {plots.csv};
    \addlegendentry{Plot 1};

    \addplot table  [x=x2, y=y2, col sep=comma] {plots.csv};
    \addlegendentry{Plot 2};

    \addplot table  [x=x3, y=y3, col sep=comma] {plots.csv};
    \addlegendentry{Plot 3};

    \end{axis}
\end{tikzpicture}

\end{document}

screenshot of the corresponding plot result

Is there a way to place an legend entry for a non existing data row, such that all three rows are listed in the legend although only two of them are really plotted?

1

You can use \addlegendimage for that. I do not precisely know how image should look like, but you will probably find it easy to modify the nan legend style to your needs. Further, one can check whether or not the last plot is empty by looking at \pgfplots@currentplot@firstcoord@x. This is also what is used to trigger the warning

Package pgfplots Warning: the current plot has no coordinates (or all have been filtered away) on input line <x>.

so it is reliable. One can then define a command, called \Addlegendentry, that adds an empty legend entry if the plot has no data.

\documentclass[border=3mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfplotsset{
    /pgfplots/nan legend/.style={
        /pgfplots/legend image code/.code={%
            \draw [#1] (0cm,-0.1cm) rectangle (0.6cm,0.2cm)
            node[midway,scale=0.7,font=\sffamily]{nan};},
    },
}
\makeatletter
\newcommand{\Addlegendentry}[2][]{\ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty
\addlegendimage{nan legend}
\addlegendentry[#1]{#2}
\else
\addlegendentry[#1]{#2}
\fi
}
\makeatother
\begin{filecontents}{plots.csv}
x1,y1,x2,y2,x3,y3
0,1,0,nan,0,3
1,1,1,nan,1,3
2,2,2,nan,2,4
3,2,3,nan,3,4
\end{filecontents} 

\begin{document}



\begin{tikzpicture}
\def\NumPlotPts{0}
    \begin{axis}[ymin=0,nodes near coords={\coordindex\xdef\NumPlotPts{\coordindex}}]
    \addplot table  [x=x1, y=y1, col sep=comma] {plots.csv};
    \Addlegendentry{Plot 1}

    \addplot table  [x=x2, y=y2, col sep=comma] {plots.csv};
    \Addlegendentry{Plot 2}

    \addplot table  [x=x3, y=y3, col sep=comma] {plots.csv};
    \Addlegendentry{Plot 3}
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

If you want to completely suppress the legend for those plots, you can do

\documentclass[border=3mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfplotsset{
    /pgfplots/nan legend/.style={
        /pgfplots/legend image code/.code={%
            \draw [#1] (0cm,-0.1cm) rectangle (0.6cm,0.2cm)
            node[midway,scale=0.7,font=\sffamily]{nan};},
    },
}
\makeatletter
\newcommand{\Addlegendentry}[2][]{\ifx\pgfplots@currentplot@firstcoord@x\pgfutil@empty
% \addlegendimage{nan legend}
% \addlegendentry[#1]{#2}
\else
\addlegendentry[#1]{#2}
\fi
}
\makeatother
\begin{filecontents}{plots.csv}
x1,y1,x2,y2,x3,y3
0,1,0,nan,0,3
1,1,1,nan,1,3
2,2,2,nan,2,4
3,2,3,nan,3,4
\end{filecontents} 

\begin{document}



\begin{tikzpicture}
\def\NumPlotPts{0}
    \begin{axis}[ymin=0,nodes near coords={\coordindex\xdef\NumPlotPts{\coordindex}}]
    \addplot table  [x=x1, y=y1, col sep=comma] {plots.csv};
    \Addlegendentry{Plot 1}

    \addplot table  [x=x2, y=y2, col sep=comma] {plots.csv};
    \Addlegendentry{Plot 2}

    \addplot table  [x=x3, y=y3, col sep=comma] {plots.csv};
    \Addlegendentry{Plot 3}
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

| improve this answer | |
  • Thank you for your response. In your example, I have to know which plot does not possess any values in advance - Hence, it will fail for the general case, where the data is automatically taken from a CSV file, as described above. – Jup Pes Feb 18 at 17:21
  • @JupPes While this requirement can be indeed detected after being told explicitly about it, your example does IMHO not reflect it at all. I was writing an answer based on the example, which does not contain a csv file or anything of that sort. It would be great if the example would be such that it can be used as a basis for an answer. – user194703 Feb 18 at 17:27
  • Thank's again, I modified the MWE for clarification – Jup Pes Feb 18 at 17:41
  • @JupPes I updated the answer accordingly. You can also modify it to do what your own answer does, but this answer answers how I read the question. – user194703 Feb 18 at 19:19
1

I found a possibility: pgfplots: how to check if addplot filters all data

\documentclass[multi]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}


\begin{filecontents}{plots.csv}
x1,y1,x2,y2,x3,y3
0,1,0,nan,0,3
1,1,1,nan,1,3
2,2,2,nan,2,4
3,2,3,nan,3,4
\end{filecontents} 

\begin{document}



\begin{tikzpicture}
    \begin{axis}[ymin=0]
    \addplot +[execute at end plot visualization=\addlegendentry{Plot 1}] table [x=x1, y=y1, col sep=comma] {plots.csv};


    \addplot +[execute at end plot visualization=\addlegendentry{Plot 2}] table [x=x2, y=y2, col sep=comma] {plots.csv};

    \addplot  +[execute at end plot visualization=\addlegendentry{Plot 3}] table    [x=x3, y=y3, col sep=comma] {plots.csv};
    \addlegendentry{Plot 3};

    \end{axis}
\end{tikzpicture}

\end{document}

So, the legend entry will only be set if there is the corresponding data line. enter image description here

| improve this answer | |

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.