1

I am trying to create a normalized frequency histogram. A minimal working example is adapted from this TexStackExchange answer by @Jake (see code below). I know I can switch add density to hist={} but that is not doing what I want. I want to divide the frequency of the specific interval by the total number of observations (here it is 10). The goal is to always have a y-axis that is scaled between 0 and 1. I get

what I get

but I want (note the epic hand drawn paint zeros on the y-axis :D). what I want

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}
\usepgfplotslibrary{statistics}

\begin{filecontents}{data.csv}
dist
0.00
0.15
0.15
0.25
0.25
0.25
0.40
0.40
0.40
0.40
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    ybar,
    ymin=0,
    ymax=4
]
\addplot +[
    hist={
        density,
        bins=4,
        data min=0.0,
        data max=0.4
    }   
] table [y index=0] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}
  • Divide the counts by the total number of observations, like here: tex.stackexchange.com/a/276201 – Ross Apr 13 '19 at 12:30
  • @Ross: Thank you for your comment. But dividing by the total number of observations is not a possibility for me. I have too many histograms and manually calculating the total number of observations would be a pain. – MachineLearner Apr 13 '19 at 12:42
1

This is a duplicate of this question: Histogram in pgfplots: Count the total number of data values answered by @Torbjørn T.

His solution uses the \pgfplotstablegetrowsof macro from the pgfplotstable package to determine the number of rows in the data file. The value of \pgfplotstablegetrowsof is then assigned to \NRows.

The x-axis values are then produced by dividing the value of the tick by the value of \NRows using yticklabel={\pgfmathparse{(\tick/\NRows)*100}\pgfmathprintnumber{\pgfmathresult}\%}.

In his answer, Torbjørn also produces the x-axis labels as intervals, which is also applied here.

This is the MWE:

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}
\usepgfplotslibrary{statistics}

\begin{filecontents}{data.csv}
dist
0.00
0.15
0.15
0.25
0.25
0.25
0.40
0.40
0.40
0.40
\end{filecontents}

% Get the number of rows
\pgfplotstablegetrowsof{data.csv}
\pgfmathsetmacro\NRows{\pgfplotsretval}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    ybar interval,
    ymin=0,
    ymax=4,
    xticklabel={\pgfmathprintnumber\tick--\pgfmathprintnumber\nexttick},
    yticklabel={\pgfmathparse{(\tick/\NRows)*100}\pgfmathprintnumber{\pgfmathresult}\%},
    yticklabel style={
      /pgf/number format/.cd,
      fixed, precision=0,
      /tikz/.cd
    },
]
\addplot +[
    hist={
        density,
        bins=4,
        data min=0.0,
        data max=0.4
    }
] table [y index=0] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}

This is the output:

enter image description here

| improve this answer | |
  • 1
    Thank you! That was what I was looking for. I also upvoted the original cited duplicate question. – MachineLearner Apr 14 '19 at 8:12
3

one possibilities is define ytick and ticklabels manually:

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}
\usepgfplotslibrary{statistics}

\begin{filecontents}{data.csv}
dist
0.00
0.15
0.15
0.25
0.25
0.25
0.40
0.40
0.40
0.40
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    ybar,
    ymin=0,
    ymax=4,
    ytick={0,...,4},                   % <---
    yticklabels={0.0,0.1,0.2,0.3,0.4}, % <---
]
\addplot +[
    hist={
        density,
        bins=4,
        data min=0.0,
        data max=0.4,
    }
] table [y index=0] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}

addendum: regarding to OP comment, for the particular case shown in question, y tick labels can be calculated from \ticks as follows:

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}
\usepgfplotslibrary{statistics}

\begin{filecontents}{data.csv}
dist
0.00
0.15
0.15
0.25
0.25
0.25
0.40
0.40
0.40
0.40
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    ybar,
    ymin=0,
    ymax=4,
    yticklabel={\pgfmathparse{\tick/10}                   % <---
                \pgfmathprintnumber[fixed]{\pgfmathresult}% <---
       },
]
\addplot +[
    hist={
        density,
        bins=4,
        data min=0.0,
        data max=0.4,
    }
] table [y index=0] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}

which gives:

enter image description here

| improve this answer | |
  • Thank you for your answer. But manual labeling is not an option for me. I have a lot of such histograms and I would need to calculate the total amount of observations by hand and then calculate the percentages which would be quite suboptimal. – MachineLearner Apr 13 '19 at 11:14
  • @MachineLearner, see addendum in answer. – Zarko Apr 13 '19 at 13:25

Not the answer you're looking for? Browse other questions tagged or ask your own question.