pgfplots fillbetween не работает с newenvironment

pgfplots fillbetween не работает с newenvironment

Вот минимальный нерабочий пример:

% preamble
\documentclass[class=minimal,border=0pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}
\usepgfplotslibrary{fillbetween}

\begin{document}

% хотят использовать эту среду. Не работает с fill between.

\newenvironment{myaxes}
{%
\begin{axis}[% here are many options in a real case
    ]
}
{%
\end{axis}
}

% тривиальная команда построения графика, которая везде одинакова

\newcommand{\myplot}{
    \addplot [domain=-1:1, name path = func] {- x*x + 1};
    \addplot [draw=none, name path = xaxis] {0};
    \addplot [red] fill between [of = xaxis and func ];
}

% эта картинка в порядке

\begin{tikzpicture}
\begin{axis}
\myplot
\end{axis}
\end{tikzpicture}

% это нарисовано, но не заполнено.

\begin{tikzpicture}
\begin{myaxes}
\myplot
\end{myaxes}
\end{tikzpicture}

% этот обходной путь работает

\newcommand{\beginmyaxis}{
\begin{axis}[% options here
    ]
}

% name 'endmyaxis' doesn't work, but it's not most important
\newcommand{\emyaxis}{
\end{axis}
}

\begin{tikzpicture}
\beginmyaxis
\myplot
\emyaxis
\end{tikzpicture}

\end{document}

результаты fillbetween

Похоже, pgfplots и моя среда работают, проблема только с fillbetween.

Я использую pgfplots 1.12.

Мой главный вопрос:почему это происходит?Это просто ошибка, или я не понимаю чего-то глубокого. Я прочитал последние pgfplotsжурнал измененийнасчет fillbetween, но там этой проблемы нет. Не удивлюсь, если это баг, тогда было бы неплохо рассказать об этом другим.

Было бы интересно увидеть другие обходные пути.

Моим первоначальным намерением было создать несколько участков, различающихся по некоторым параметрам и декорациям, но имеющих много общего, что я хотел определить как среду (кажется, более (La)TeXnical, чем команды открытия и закрытия).

решение1

Это происходит из-за дополнительной пары \begingroup/ \endgroup, которая вводится в \newenvironmentсочетании с глубокой магией, которая передает набор графических слоев от оси к tikzpicture.

По сути, есть три способа решения этой проблемы:

1] Активировать многослойную графикувручнуюперед вашей осью:

\documentclass[class=minimal,border=0pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}
\usepgfplotslibrary{fillbetween}

\newenvironment{myaxes}
{%
    \begin{axis}[% here are many options in a real case
        ]
}
{%
    \end{axis}%
}

\newcommand{\myplot}{
    \addplot [domain=-1:1, name path = func] {- x*x + 1};
    \addplot [draw=none, name path = xaxis] {0};
    \addplot [red] fill between [of = xaxis and func ];
}
\begin{document}
\begin{tikzpicture}
\pgfplotsset{set layers}
\begin{myaxes}
\myplot
\end{myaxes}
\end{tikzpicture}

\end{document}

2] Использовать глубокую магию, которая зависит от внутренних компонентов PGF/pgfplots:

\documentclass[class=minimal,border=0pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}
\usepgfplotslibrary{fillbetween}

\newenvironment{myaxes}
{%
    \begin{axis}[% here are many options in a real case
        ]
}
{%
    \end{axis}%
    \expandafter\aftergroup\csname pgf@restore@layerlist@from@global\endcsname
}

\newcommand{\myplot}{
    \addplot [domain=-1:1, name path = func] {- x*x + 1};
    \addplot [draw=none, name path = xaxis] {0};
    \addplot [red] fill between [of = xaxis and func ];
}
\begin{document}
\begin{tikzpicture}
\begin{myaxes}
\myplot
\end{myaxes}
\end{tikzpicture}

\end{document}

3] использование

\begin{tikzpicture}
\myaxes
\myplot
\endmyaxes
\end{tikzpicture}

Вместо среды LaTeX (эти макросы определяются \newenvironment).


Объяснение:fill between неявно активирует многослойную графику таким образом, что заполненная областьподразграничительные участки, хотя это было определенопослеих в коде. Этот набор многослойной графики необходимо передать вложенному tikzpicture, и это (к сожалению) зависит от группирующих конструкций TeX: каждый \endgroupочищает такие списки. Решение PGF/pgfplots, похоже, работает для стандартных случаев — и не работает в этом случае.

Это значит, что картинка также будет работать, если вы напишете, fill between[on layer={}]чтобы отключить дополнительный слой (но она будет выглядеть по-другому).

Это баг? Честно говоря, не знаю... Может, это как-то исправить.

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