2

I just played with @Jakes pgfplots binomial examples from https://tex.stackexchange.com/a/198575/4011, however the histogram seems to be shifted to the left or to the right depending on the whole plot (look for example at the k=50 value below). Any idea what's wrong here? Might it be because of numerical errors from pgfplots? How to fix it?

\documentclass[tikz,convert]{standalone}

\usepackage{pgfplots}
\usetikzlibrary{patterns}
\pgfplotsset{compat=1.13}


\begin{document}

\begin{tikzpicture}[%
  declare
  function={binom(\k,\n,\p)=
    (\k <= \n)*\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k) 
    ;}%
  ]
  \begin{axis}[%
    axis lines=center,%
    ymax=0.25,%
    ymin=0,%
    xmax=60,%
    samples at={0,1,...,50},%
    yticklabel style={%
      /pgf/number format/fixed,%
      /pgf/number format/fixed zerofill,%
      /pgf/number format/precision=1,%
      /pgf/number format/use comma },%
    ybar=0pt,bar width=0.5,%
    xlabel=$k$,%
    ylabel=$B_{n,p}(k)$, minor x tick num=0, ymajorgrids,
    width=15cm, height=6cm]
    \addplot [fill=gray!50, fill opacity=0.5]
    {binom(x,50,0.9)};%
  \end{axis}
\end{tikzpicture}
\begin{tikzpicture}[%
  declare
  function={binom(\k,\n,\p)=
    (\k <= \n)*\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k) 
    ;}%
  ]
  \begin{axis}[%
    axis lines=center,%
    ymax=0.25,%
    ymin=0,%
    xmax=60,%
    samples at={0,1,...,50},%
    yticklabel style={%
      /pgf/number format/fixed,%
      /pgf/number format/fixed zerofill,%
      /pgf/number format/precision=1,%
      /pgf/number format/use comma },%
    ybar=0pt,bar width=0.5,%
    xlabel=$k$,%
    ylabel=$B_{n,p}(k)$, minor x tick num=0, ymajorgrids,
    width=15cm, height=6cm]
    \addplot [fill=black, fill opacity=0.5] {binom(x,50,0.7)};%
    \addplot [fill=gray!50, fill opacity=0.5]
    {binom(x,50,0.9)};%
  \end{axis}
\end{tikzpicture}

\begin{tikzpicture}[%
  declare
  function={binom(\k,\n,\p)=
    (\k <= \n)*\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k) 
    ;}%
  ]
  \begin{axis}[%
    axis lines=center,%
    ymax=0.25,%
    ymin=0,%
    xmax=60,%
    samples at={0,1,...,50},%
    yticklabel style={%
      /pgf/number format/fixed,%
      /pgf/number format/fixed zerofill,%
      /pgf/number format/precision=1,%
      /pgf/number format/use comma },%
    ybar=0pt,bar width=0.5,%
    xlabel=$k$,%
    ylabel=$B_{n,p}(k)$, minor x tick num=0, ymajorgrids,
    width=15cm, height=6cm]

    \addplot [fill=gray!50, fill opacity=0.5]
    {binom(x,50,0.9)};%
    \addplot [fill=black, fill opacity=0.5] {binom(x,50,0.7)};%
  \end{axis}
\end{tikzpicture}
\end{center}

\end{document}

Output:

Diagram 1

Diagram 2

Diagram 3

  • 3
    When you're plotting more than one series using the bar style, PGFPlots offsets the series so they don't overlap. If you don't want that, set bar shift=0pt. – Jake Feb 10 '16 at 22:11
  • 1
    @Jake, please convert your comment to answer. – Zarko Feb 11 '16 at 0:16
  • @Jake Thanks that works. But then I don't really understand the syntax, the manual says /pgfplots/ybar={<shift for multiple plots>} and ybar is set to zero. Furthermore the manual says that bar shift is initially zero. Perhaps you can also explain this if you turn your commaent to an answer. – student Feb 11 '16 at 12:20
2

Short answer: When using ybar in the axis options, PGFPlots will shift the different series to avoid overlapping bars. If you want the bars not to be shifted, set bar shift=0pt.


ybar in the axis options, single series

If you use the ybar key in the axis options and plot just a single series, you'll get bars centered over the specified x positions:

\begin{axis}[
    ybar,
    ymin=0
]
    \addplot +[samples at={1,...,5}] {x};
\end{axis}


ybar in the axis options, two series

If you add another series, PGFPlots will offset the first series to the left and the second series to the right, so the bars don't overlap. By default, there's a 2pt gap between bars with the same x-coordinate:

\begin{axis}[
    ybar,
    ymin=0
]
    \addplot +[samples at={1,...,5}] {x};
    \addplot +[samples at={1,...,5}] {5-x};
\end{axis}


ybar=0pt in the axis options, two series

You can adjust the width of the gap between the series by using the optional argument to the ybar style in the axis options. If you set ybar=0pt, the bars will be flush with each other:

\begin{axis}[
    ybar=0pt,
    ymin=0
]
    \addplot +[samples at={1,...,5}] {x};
    \addplot +[samples at={1,...,5}] {5-x};
\end{axis}


ybar, bar shift=0pt in the axis options, two series

If you don't want the bars to be shifted in different directions, you can set bar shift=0pt. That way, bars with the same x-coordinate will be drawn in the same location, leading to overlapping bars:

\begin{axis}[
    ybar,
    bar shift=0pt,
    ymin=0
]
    \addplot +[samples at={1,...,5}] {x};
    \addplot +[samples at={1,...,5}] {5-x};
\end{axis}

In the PGFPlots manual, it says that bar shift "configures a shift for xbar and ybar", and that the default value for this style is 0pt. Why then do you get different results when including or omitting bar shift=0pt? That's because calling ybar in the axis options overwrites the default value for bar shift and replaces it with a mathematical expression:

/pgf/bar shift={%
        % total width = n*w + (n-1)*skip
        % -> subtract half for centering
        -0.5*(\numplotsofactualtype*\pgfplotbarwidth + (\numplotsofactualtype-1)*(#1))  + 
        % the '0.5*w' is for centering
        (.5+\plotnumofactualtype)*\pgfplotbarwidth + \plotnumofactualtype*(#1)}

That expression leads to the shift we saw in examples 2 and 3. The #1 parameter is the gap between the bars (2pt by default).


ybar in the \addplot options, bar shift=5pt in the axis options, two series

You can check that the default value for bar shift is indeed, as the manual says, 0pt, by moving the ybar key from the axis options to the \addplot options and setting a different value for bar shift in the axis options. Now all the bars are shifted to the right by 5pt:

\begin{axis}[
    bar shift=5pt,
    ymin=0
]
    \addplot +[ybar, mark=none, fill=blue!30!white, samples at={1,...,5}] {x};
    \addplot +[ybar, mark=none, fill=red!30!white, samples at={1,...,5}] {5-x};
\end{axis}

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.