# Pgfplot - add the mean to a histogram (bar plot)

I have a number of data files in the format count: frequency of count

1:  3691
2:  1492
3:  651
4:  922
5:  818
6:  1475
7:  335
8:  286
9:  165
10:     152
11:     208
12:     197
13:     137
14:     159
15:     87
16:     84
17:     40
18:     20
19:     37
20:     16
21:     38
22:     25
23:     17
24:     9
25:     18
26:     21
27:     4
28:     6
29:     3
30:     1
31:     5
33:     1
34:     1
35:     4
36:     3
37:     1
38:     2
39:     8
40:     3
42:     1
44:     1
46:     1
47:     12
52:     2
58:     1
83:     1
88:     1


I want to plot this as a histogram of counts (which I can do) with an average count (which I can't do).This is what is have so far:

\documentclass[]{standalone}

\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}

\maketitle

\begin{tikzpicture}
\begin{axis}[
xtick distance=10
]
\addplot[ybar interval] table [x, y, col sep=colon] {results/data.txt};

% this line is sort of what I want but I want the 7 to be calculated automatically as the average count
%\draw[] (axis cs:7, \pgfkeysvalueof{/pgfplots/ymin}) -- (axis cs:7, \pgfkeysvalueof{/pgfplots/ymax});

\end{axis}
\end{tikzpicture}

\end{document}


I found this example but the data format was different so I wasn't sure how to adapt it for my situation.

This is an example of what I'm after:

Can anyone tell me how to automatically calculate the average count and add it to my plot?

I don't know how you want to calculate the average, so here is an example of how to calculate averages from a table.

Be aware, that at no time any value is allowed to exceed 16383.9999. Otherwise you'll get a dimension too large error. To prevent this, you can divide a value by some constant while suming up and later multiply the average with it.

The code:

Edit: table and macro names for results are now passed as parameters.

\documentclass[]{article}
\usepackage{pgfplots}

% old code, table and macros for results fixed
%\newcommand*{\GetAverage}{%
%    \pgfmathsetmacro\dtcsum{0}%
%    \pgfmathsetmacro\dtfsum{0}%
%    \pgfmathsetmacro\dtcfsum{0}%
%    \pgfmathsetmacro\dtcnt{0}%
%    \pgfplotstableforeachcolumnelement{[index]0}\of\datatable\as\cellValue{%
%        \pgfplotstablegetelem{\pgfplotstablerow}{[index]1}\of\datatable
%        \pgfmathsetmacro{\dtfreq}{\pgfplotsretval}
%        % now: \cellValue = count; \dtfreq = frequency
%        % calculate sums
%        \pgfmathsetmacro{\dtcsum}{\dtcsum + \cellValue}%
%        \pgfmathsetmacro{\dtfsum}{\dtfsum + \dtfreq}%
%        % dividing \cellValue by 100 prevents dimension to large error
%        \pgfmathsetmacro{\dtcfsum}{\dtcfsum + (\cellValue / 100 * \dtfreq)}%
%        \pgfmathsetmacro{\dtcnt}{\dtcnt + 1}%
%    }
%    % calculate the averages
%    \pgfmathsetmacro{\dtcavg}{\dtcsum / \dtcnt}%
%    \pgfmathsetmacro{\dtfavg}{\dtfsum / \dtcnt}%
%    \pgfmathsetmacro{\dtcfavg}{\dtcfsum / \dtcnt * 100}%
%}
%\GetAverage

% new code, table and macros for results as parameters
\newcommand*{\GetAverage}[4]{%
\pgfmathsetmacro\dtcsum{0}%
\pgfmathsetmacro\dtfsum{0}%
\pgfmathsetmacro\dtcfsum{0}%
\pgfmathsetmacro\dtcnt{0}%
\pgfplotstableforeachcolumnelement{[index]0}\of#1\as\cellValue{%
\pgfplotstablegetelem{\pgfplotstablerow}{[index]1}\of#1
\pgfmathsetmacro{\dtfreq}{\pgfplotsretval}
% now: \cellValue = count; \dtfreq = frequency
% calculate sums
\pgfmathsetmacro{\dtcsum}{\dtcsum + \cellValue}%
\pgfmathsetmacro{\dtfsum}{\dtfsum + \dtfreq}%
% dividing \cellValue by 100 prevents dimension to large error
\pgfmathsetmacro{\dtcfsum}{\dtcfsum + (\cellValue / 100 * \dtfreq)}%
\pgfmathsetmacro{\dtcnt}{\dtcnt + 1}%
}
% calculate the averages
\pgfmathsetmacro{#2}{\dtcsum / \dtcnt}%
\pgfmathsetmacro{#3}{\dtfsum / \dtcnt}%
\pgfmathsetmacro{#4}{\dtcfsum / \dtcnt * 100}%
}
\GetAverage{\datatable}{\dtcavg}{\dtfavg}{\dtcfavg}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
xtick distance=10
]
\addplot[ybar interval] table [x, y] {\datatable};

% this line is sort of what I want but I want the 7 to be calculated automatically as the average count
\draw[blue] (axis cs:\dtcavg, \pgfkeysvalueof{/pgfplots/ymin}) --
(axis cs:\dtcavg, \pgfkeysvalueof{/pgfplots/ymax});

\end{axis}
\end{tikzpicture}

Average of column count is: \dtcavg

Average of column frequency is: \dtfavg

Average of count $\cdot$ frequency is: \dtcfavg
\end{document}


• how could I used this for more than one file? It seems that if I try and use it twice, the average macros become reset - even if I try and plot the results in between reusing the command. Oct 23 '17 at 21:54
• @JamesAllingham by passing the table and the macro names for the results as parameters. See edit of my answer. I left the old code in a comment for comparison.
– Mike
Oct 23 '17 at 22:21