1

As the title says, I would like to create a histogram from integer values. My MWE is:

\documentclass[border=5]{standalone}

\usepackage{pgfplots} %Random data between 10 and 20 -- could also be between 100 and 200 or what ever \begin{filecontents}{data.txt} 18 15 18 19 14 15 12 11 18 18 12 11 17 \end{filecontents}

\begin{document} \begin{tikzpicture} \begin{axis}[ axis lines=left, ymajorgrids=true, title={Histogram}, xlabel=points, ylabel=headcount, ybar ] \addplot+ [hist] table[y index= 0]{data.txt}; \end{axis} \end{tikzpicture} \end{document}

The result is:

enter image description here

What i would like to get is (note: unfortunately, I have double-counted the values):

![target](https://imgur.com/a/MZdQrYZ)

My problems are, the x-axis is not discrete, and that's why the labels are shifted. I would like to have space between the bars - also between y-axis and the first bar and at the end.

Some additional infos: I am using LaTeX. I have already tried to set the precision to 0 and using datatool to first count the frequencies and then draw a simple bar chart. I have struggled with various label and area styles, but couldn't achieve my goal.

Ribooko
  • 13
  • 4
  • 1
    I think you need to decide, if you want a bar plot or a histogram. The lower plot you show id not a histogram, but a bar plot. – hpekristiansen Feb 08 '24 at 10:07
  • It seems I might be confusing the terms. I want to create a chart that represents the frequency of numbers from a table. – Ribooko Feb 08 '24 at 11:16

2 Answers2

2

You can use gnuplot to create the histogram data and then plot these data as a bar plot. To compile, you need gnuplot installed and compile with --shell-escape : What does --shell-escape do?

\begin{filecontents*}{data.txt}
18
15
18
19
14
15
12
11
18
18
12
11
17
\end{filecontents*}
\documentclass[tikz, border=1cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
ybar,
xmin=10, xmax=20,
ymin=0,
xtick distance=1,
axis lines=left,
ymajorgrids=true,
title={Not a Histogram}, xlabel=points, ylabel=headcount,
]
\addplot+[raw gnuplot] gnuplot {
binwidth=1;
bin(x,bw)=bw*floor(x/bw);
plot "data.txt" using (bin($1,binwidth)):(1.0) smooth freq;
};
\end{axis}
\end{tikzpicture}
\end{document}

Bar plot of the cumulated data

0
  • We can prepare the data with Latex3 and a random selection.

    \intarray_new:Nn \g_HISTO_myarray_intarray {9}

to store number between 1 and 9 excluded(11, 12, ..., 19). We add 10 when writing to the file \jobname.data

  • If we already have a file ready or if we want to manually modify the data, we can modify this file and comment \histo[20].

  • with pgfplots

    bar width=0.5cm and enlarge x limits={auto},enlarge y limits={upper}, so as not to stick to the axes

the code

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\ExplSyntaxOn
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\sys_gset_rand_seed:n {240210}
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\int_new:N \l_HISTO_randominteger_int
\intarray_new:Nn \g_HISTO_myarray_intarray {9}
\iow_new:N \g_HISTO_iow
%
\tl_new:N \l_HISTO_table_tl
\NewDocumentCommand{\histo}{O{10}}% 10 by default
    {
        \__array_fillarray:n{#1}       
        \__array_table:       
    }

\cs_new_protected:Nn __array_fillarray:n { \int_step_inline:nnn {1} {#1} { \int_set:Nn \l_HISTO_randominteger_int {\int_rand:nn {1} {9}} \intarray_gset:Nnn \g_HISTO_myarray_intarray { \l_HISTO_randominteger_int } { \intarray_item:Nn \g_HISTO_myarray_intarray {\l_HISTO_randominteger_int} + 1 } %\int_use:N \l_HISTO_randominteger_int \quad % uncomment to see the numbers } %\intarray_log:N \g_HISTO_myarray_intarray% <-- to see the intarray in the log }

\cs_new_protected:Nn __array_table: { \iow_open:Nn \g_HISTO_iow {\jobname.data} \int_step_inline:nnn {1} {9} { \tl_clear:N \l_HISTO_table_tl \tl_put_right:Nn \l_HISTO_table_tl {\int_eval:n {10+##1}}%<-- between 11 and 19 \tl_put_right:Nn \l_HISTO_table_tl {~} \tl_put_right:Nn \l_HISTO_table_tl { \intarray_item:Nn \g_HISTO_myarray_intarray {##1}}
\iow_now:Nx \g_HISTO_iow { \l_HISTO_table_tl } } \iow_close:N \g_HISTO_iow } \ExplSyntaxOff \begin{document} \histo[20]

\begin{tikzpicture} \begin{axis}[ %width=8cm, height=8cm, axis lines=left, ybar, bar width=0.5cm, ymajorgrids=true, title={Histogram ?},%<-- ? % xlabel=points, ylabel=headcount, xticklabel style = {font=\small}, xtick=data, enlarge x limits={auto}, enlarge y limits={upper}, ] \addplot table[y index=1] {\jobname.data}; \end{axis} \end{tikzpicture} \end{document}

enter image description here

pascal974
  • 4,652
  • Thank you very much as well for your time and effort! I tested it, and it works. I marked hpekristiansen's answer because it is more concise. – Ribooko Feb 21 '24 at 07:40