根据曲线下的面积对图中的曲线进行归一化

根据曲线下的面积对图中的曲线进行归一化

在下面的 MWE 中,有两个表,每个表中有一列(公共)x 值和两列 y 值(A 和 B)。在对每个表的 B 列的最大值进行归一化之后,它们绘制在同一张图中(还添加了一个偏移量)。

如何用 B 列和 A 列之间的面积代替每个表的 B 列最大值的归一化?换句话说:我想将每组两条曲线归一化为 B 和 A 之间的面积。如何实现?

虽然从数值上来说不是很复杂,但我不知道如何在 pgfplots 中实现它(这将消除每次绘制此图时将数据放入和取出 Matlab 或 Octave 的需要)。

梅威瑟:

在此处输入图片描述

\documentclass{article}
\usepackage[tightpage,active]{preview}
\usepackage{pgfplotstable}

\newcommand{\offset}{1}

\newcommand{\findmax}[3]{
    \pgfplotstablesort[sort key={#2},sort cmp={float >}]{\sorted}{#1}%
    \pgfplotstablegetelem{0}{#2}\of{\sorted}%
    \pgfmathsetmacro#3{\pgfplotsretval}
}

\pgfplotstableread{
X A B
0 1 5
1 1 7
2 2 7
3 2 5
4 2 3
}\tableone
\findmax{\tableone}{B}{\Bmaxone}

\pgfplotstableread{
X A B
0 10 24
1 13 45
2 24 66
3 26 33
4 26 27
}\tabletwo
\findmax{\tabletwo}{B}{\Bmaxtwo}

\begin{document}
\begin{preview}
\begin{tikzpicture}
\begin{axis}

\addplot [black]
table[x=X,y expr=\thisrow{A}/\Bmaxone] {\tableone};
\addplot [black] 
table[x=X,y expr=\thisrow{B}/\Bmaxone] {\tableone};

\addplot [black]
table[x=X,y expr=\thisrow{A}/\Bmaxtwo+\offset] {\tabletwo};
\addplot [black] 
table[x=X,y expr=\thisrow{B}/\Bmaxtwo+\offset] {\tabletwo};

\end{axis}
\end{tikzpicture}
\end{preview}
\end{document}

答案1

计算曲线下的面积需要一点循环,但它相当简单。

请注意,如果您有很多数字,或者值很大(总计超过 16000),则需要使用该fpu库,如下例所示。

\documentclass{article}
\usepackage{pgfplotstable}


\newcommand{\calcarea}[3]{
    \pgfplotstablegetrowsof{#1}
    \pgfmathtruncatemacro\numrows{\pgfplotsretval-1}
    \pgfkeys{/pgf/fpu=true}
    \def\cumsum{0}
    \pgfplotstableforeachcolumnelement{#2}\of{#1}\as\elem{
        \pgfmathparse{\cumsum+\elem}
        \def\cumsum{\pgfmathresult}
    }
    \pgfplotstablegetelem{0}{#2}\of{#1}%
    \pgfmathparse{2*\cumsum-\pgfplotsretval}
    \def\cumsum{\pgfmathresult}
    \pgfplotstablegetelem{\numrows}{#2}\of{#1}
    \pgfmathparse{(\cumsum-\pgfplotsretval)/2}
    \pgfmathfloattofixed{\pgfmathresult}
    \edef#3{\pgfmathresult}
    \pgfkeys{/pgf/fpu=false}
}


\pgfplotstableread{
X A B
0 1 5
1 1 7
2 2 7
3 2 5
4 2 3
}\tableone

\pgfplotstableread{
X A B
0 10 2400
1 13 4500
2 24 6600
3 26 3300
4 26 2700
}\tabletwo

\begin{document}

\calcarea{\tableone}{A}{\areaA}

\calcarea{\tableone}{B}{\areaB}

\calcarea{\tabletwo}{A}{\areaAtwo}

\calcarea{\tabletwo}{B}{\areaBtwo}


\begin{tikzpicture}
\begin{axis}

\addplot [black]
table[x expr=\coordindex,y expr=\thisrow{A}/abs(\areaA-\areaB)] {\tableone};
\addplot [black] 
table[x expr=\coordindex,y expr=\thisrow{B}/abs(\areaA-\areaB)] {\tableone};
\addplot [red]
table[x=X,y expr=\thisrow{A}/abs(\areaAtwo-\areaBtwo)+0.5] {\tabletwo};
\addplot [red] 
table[x=X,y expr=\thisrow{B}/abs(\areaAtwo-\areaBtwo)+0.5] {\tabletwo};

\end{axis}
\end{tikzpicture}
\end{document}

相关内容