10

I'm trying to automatically generate a plot, which visualizes the difference of two other plots. The input source is a single(!) file. The data is filtered by one column with /tr/rowfilter. Here is an example image:

enter image description here

I want that the "difference (b-a)" plot is generated by TikZ/PGFPlots/PGFPlotstable/LaTeX. I've experimented with /pgfplots/x filter, but I wasn't successful (I don't even know, if it's possible) Here is the corresponding tex example:

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\pgfkeys{
    /tr/rowfilter/.style 2 args={
        /pgfplots/x filter/.append code={
            \edef\arga{\thisrow{#1}}
            \edef\argb{#2}
            \ifx\arga\argb
            \else
                \def\pgfmathresult{}
            \fi
        }
    }
}

\usepackage{filecontents}
\begin{filecontents}{diagram.dat}
x y kind
1 1 a
2 6 a
3 10 a
4 13 a
5 15 a

1 1 b
2 7 b
3 13 b
4 17 b
5 20 b
\end{filecontents}
\begin{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{\huge The way it is now:}
\vspace{0.5cm}

\begin{tikzpicture}
\begin{axis}[
filter discard warning=false,
height=8cm,
width=12cm,
grid=major,
legend pos=outer north east
]
\addplot table[/tr/rowfilter={kind}{a}] {diagram.dat};
\addlegendentry{curve a}
\addplot table[/tr/rowfilter={kind}{b}] {diagram.dat};
\addlegendentry{curve b}
\end{axis}
\end{tikzpicture}
\vspace{1cm}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{\huge The way it should look like}
\vspace{0.5cm}

\begin{tikzpicture}
\begin{axis}[
filter discard warning=false,
height=8cm,
width=12cm,
grid=major,
legend pos=outer north east
]
\addplot table[/tr/rowfilter={kind}{a}] {diagram.dat};
\addlegendentry{curve a}
\addplot table[/tr/rowfilter={kind}{b}] {diagram.dat};
\addlegendentry{curve b}

%%% This should be generated with Tikz/PGFPLOTS/PGFPLOTSTABLE/Latex!!!
\addplot coordinates {
(1,0) 
(2,1)
(3,3)
(4,4)
(5,5)
};
\addlegendentry{difference (b-a)}

\end{axis}
\end{tikzpicture}

\end{document}

Can you help me?

Jake
  • 232,450
  • 2
    Welcome to TeX.SE. And thanks for posting a complete MWE. – Peter Grill Jul 07 '12 at 04:34
  • 1
    See also my proposal for http://tex.stackexchange.com/questions/62536/calculate-and-draw-multiplying-dividing-or-adding-of-two-plots-automatically - perhaps that is interesting for you as well. In short: if you can efford a simpler input table format, you can simplify the task drastically. – Christian Feuersänger Jul 07 '12 at 21:01
  • Thanks for the comment, but changing the table format means probably more programming in c (or post-processing with some other tools), so the solution with PGFPLOTS is better for me in this case – Thomas Rebele Jul 13 '12 at 20:14

1 Answers1

13

You can use the stack plot=y functionality, using stack dir=minus to subtract the a plot from the b plot.

When plotting the b plot, add stack plots=y to the options:

\addplot +[stack plots=y] table[/tr/rowfilter={kind}{b}] {diagram.dat};

and then plot the difference by "stacking" the a plot on top, with a negative sign:

\addplot +[stack plots=y, stack dir=minus] table[/tr/rowfilter={kind}{a}] {diagram.dat};

et voilà:

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\pgfkeys{
    /tr/rowfilter/.style 2 args={
        /pgfplots/x filter/.append code={
            \edef\arga{\thisrow{#1}}
            \edef\argb{#2}
            \ifx\arga\argb
            \else
                \def\pgfmathresult{}
            \fi
        }
    }
}

\usepackage{filecontents}
\begin{filecontents}{diagram.dat}
x y kind
1 1 a
2 6 a
3 10 a
4 13 a
5 15 a

1 1 b
2 7 b
3 13 b
4 17 b
5 20 b
\end{filecontents}
\begin{document}

\begin{tikzpicture}
\begin{axis}[
filter discard warning=false,
height=8cm,
width=12cm,
grid=major,
legend pos=outer north east
]
\addplot table[/tr/rowfilter={kind}{a}] {diagram.dat};
\addlegendentry{curve a}

% Make the "b" plot the first "stacked" plot
\addplot +[stack plots=y] table[/tr/rowfilter={kind}{b}] {diagram.dat};
\addlegendentry{curve b}

% Plot the "a" plot again, "stacking" it on the "b" plot in the negative direction 
\addplot +[stack plots=y, stack dir=minus] table[/tr/rowfilter={kind}{a}] {diagram.dat};
\addlegendentry{$(b-a)$}
\end{axis}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
  • Thanks, that's exactly what I needed! I definitely have to read the whole manuals of TikZ and PGFPLOTS, when I have more time:) – Thomas Rebele Jul 07 '12 at 14:32