3

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: enter image description here

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

0
4

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}

\pgfplotstableread[col sep=colon]{pgfplots-histo-average.dat}\datatable

% 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}

enter image description here

2
  • 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

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.