Проблема с pgfplots и гистограммами

Проблема с pgfplots и гистограммами

Я только что поигрался с биномиальными примерами @Jakes pgfplots изhttps://tex.stackexchange.com/a/198575/4011, однако гистограмма, кажется, смещена влево или вправо в зависимости от всего графика (например, посмотрите на значение k=50 ниже). Есть идеи, что здесь не так? Может быть, это из-за числовых ошибок от pgfplots? Как это исправить?

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

Выход:

Диаграмма 1

Диаграмма 2

Диаграмма 3

решение1

Короткий ответ: При использовании ybarв axisпараметрах PGFPlots будет сдвигать разные серии, чтобы избежать перекрытия столбцов. Если вы хотите, чтобы столбцы не сдвигались, установите bar shift=0pt.


ybarв axisопциях, одиночная серия

Если вы используете ybarклавишу в axisпараметрах и строите график только одной серии, вы получите столбцы, центрированные по указанным позициям x:

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


ybarв axisопциях две серии

Если вы добавите еще одну серию, PGFPlots сместит первую серию влево, а вторую серию вправо, чтобы столбцы не перекрывались. По умолчанию 2pt между столбцами с одинаковой координатой x есть зазор:

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


ybar=0ptв axisопциях две серии

Вы можете настроить ширину зазора между сериями, используя необязательный аргумент стиля ybarв axisпараметрах. Если вы установите ybar=0pt, полосы будут выровнены друг с другом:

\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в axisопциях две серии

Если вы не хотите, чтобы полосы были смещены в разных направлениях, вы можете установить bar shift=0pt. Таким образом, полосы с одинаковой x-координатой будут нарисованы в одном месте, что приведет к перекрывающимся полосам:

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

В руководстве PGFPlots говорится, что bar shift"настраивает сдвиг для xbarи ybar", и что значение по умолчанию для этого стиля равно 0pt. Почему же тогда вы получаете разные результаты при включении или исключении bar shift=0pt? Это потому, что вызов ybarпараметров axisперезаписывает значение по умолчанию для bar shiftи заменяет его математическим выражением:

/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)}

Это выражение приводит к сдвигу, который мы видели в примерах 2 и 3. Параметром #1является зазор между столбцами ( 2ptпо умолчанию).


ybarв \addplotопциях, bar shift=5ptв axisопциях, две серии

Вы можете проверить, что значение по умолчанию для bar shiftдействительно, как сказано в руководстве, 0pt, переместив ybarключ из axisпараметров в \addplotпараметры и установив другое значение для bar shiftв axisпараметрах. Теперь все полосы смещены вправо на 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}

Связанный контент