解释

解释

我想在 pgfplot 中添加一条直线来表示数据的平均值。对于直方图,这应该是一条垂直线;对于简单图,应该是一条水平线。现在,我已经在提供的最小工作示例中做到了这一点。

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\begin{filecontents}{data.csv}
1.84919
0.97280
4.78586
3.95797
4.50753
2.52274
5.13984
0.29474
5.39946
4.40204
\end{filecontents}
\newcommand*{\manmean}{3.3832}
\begin{document}
  \begin{tikzpicture}
  \begin{axis}
    \addplot[hist={bins=6,}, fill=teal, draw=teal!50!black] table[y index=0] {data.csv};
    \addplot[teal, ultra thick, dashed] coordinates {(3.3832, 0) (3.3832, 3)};
  \end{axis}
\end{tikzpicture}
%
\begin{tikzpicture}
  \begin{axis}
    \addplot[teal, mark=*] table [x expr=\coordindex+1, y index=0] {data.csv};
    \addplot[teal, ultra thick, dashed] coordinates {(1, \manmean) (10, \manmean)};
  \end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

然而,仍然存在两个问题:

  • 需要手动计算平均值
  • 需要手动输入线路的起点和终点

实际上,这条线应该沿着轴的整个延伸延伸并触及边界。

pgfplots 手册中提到/pgfplots/xmin,,/pgfplots/xmax以及/pgfplots/ymin/pgfplots/ymax4.14.1 限值范围配置/pgfplots/boxplot/average.还有5.11 统计。但是,我找不到访问这些值的方法。

理论上,我可以使用以下公式计算平均值awk。然而,这并不奏效,因为pdflatex不知何故无法使用带有printf引号的 shell 命令进行编译。

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{filecontents}
\pgfplotsset{compat=1.9}
\begin{filecontents*}{data.csv}
1.84919
0.97280
4.78586
3.95797
4.50753
2.52274
5.13984
0.29474
5.39946
4.40204
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
  \begin{axis}
    \addplot[teal, mark=*] table [x expr=\coordindex+1, y index=0] {data.csv};
    \addplot[teal, ultra thick, dashed, mark=*] shell {awk '{ sum += $1 } END { printf "%i %f\n%i %f\n", 1, sum/NR, NR, sum/NR }' data.csv};
  \end{axis}
\end{tikzpicture}
\end{document}

-shell-escape请注意,编译包含 shell 脚本的文档时需要参数,例如pdflatex -shell-escape mwe-mean-awk.tex

它给出的错误:

Runaway argument?
{awk '{ sum += $1 } END { printf "\end {axis} \end {tikzpicture} \end \ETC.
! Paragraph ended before \pgfplots@addplotimpl@shell@opt was complete.
<to be read again> 
                   \par 
l.25 

?

即使这种方法可行,但对于一张漂亮的照片来说,这条线还是太短了。

答案1

这是一个选项:

\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.9}

\usepackage{filecontents}
\begin{filecontents*}{data.csv}
level
1.84919
0.97280
4.78586
3.95797
4.50753
2.52274
5.13984
0.29474
5.39946
4.40204
\end{filecontents*}

\usepackage{filecontents}
\begin{filecontents*}{dataA.csv}
level
2
4
6
8
10
9
7
5
3
1
\end{filecontents*}

\newcommand\DrawVMean[1][]{
\draw[#1] 
  (axis cs:\Mean,\pgfkeysvalueof{/pgfplots/ymin}) -- 
  (axis cs:\Mean,\pgfkeysvalueof{/pgfplots/ymax});
}
\newcommand\DrawHMean[1][]{
\draw[#1] 
  (axis cs:\pgfkeysvalueof{/pgfplots/xmin},\Mean) -- 
  (axis cs:\pgfkeysvalueof{/pgfplots/xmax},\Mean);
}

\newcommand\GetMean[2]{
  \pgfplotstableread{#1}\tableA
  \pgfplotstableset{
    create on use/new/.style={
    create col/expr={\pgfmathaccuma + \thisrow{#2}}},
  }
  \pgfplotstablegetrowsof{\tableA}
  \pgfmathsetmacro{\NumRows}{\pgfplotsretval}
  \pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1} 
  \pgfmathsetmacro{\Sum}{\pgfplotsretval}
  \pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}

\begin{document}

\begin{tikzpicture}
\GetMean{data.csv}{level}
\begin{axis}
    \addplot[hist={bins=6,}, fill=teal, draw=teal!50!black] table[y index=0] {data.csv};
\DrawVMean[teal, ultra thick, dashed] 
\end{axis}
\end{tikzpicture}\qquad
%
\begin{tikzpicture}
\GetMean{data.csv}{level}
  \begin{axis}
    \addplot[teal, mark=*] table [x expr=\coordindex+1, y index=0] {data.csv};
\DrawHMean[teal, ultra thick, dashed] 
  \end{axis}
\end{tikzpicture}\par\bigskip

\begin{tikzpicture}
\GetMean{dataA.csv}{level}
\begin{axis}
    \addplot[hist={bins=6,}, fill=cyan!20, draw=cyan!50!black] table[y index=0] {dataA.csv};
\DrawVMean[orange, ultra thick, dashed] 
\end{axis}
\end{tikzpicture}\qquad
%
\begin{tikzpicture}
\GetMean{dataA.csv}{level}
  \begin{axis}
    \addplot[cyan!50, mark=*] table [x expr=\coordindex+1, y index=0] {dataA.csv};
\DrawHMean[orange, ultra thick, dashed] 
  \end{axis}
\end{tikzpicture}

\end{document}

结果:

在此处输入图片描述

解释

  • 用于获取文件中\GetMean{<data-file>}{<col-name>}具有名称的列的平均值。<col-name><data-file>
  • axis环境中使用\DrawVMean[<options>]/\DrawHMean[<options>]在媒体位置自动绘制垂直/水平线。

相关内容