pgfplots fillbetween no funciona con un nuevo entorno

pgfplots fillbetween no funciona con un nuevo entorno

Aquí hay un ejemplo mínimo que no funciona:

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

\begin{document}

% quiere utilizar este entorno. No funciona con fill between.

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

% un comando de trazado trivial que es idéntico en todas partes

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

% esta foto está bien

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

% esto se extrae, pero no se llena.

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

% esta solución funciona

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

los resultados del relleno entre

Parece que pgfplots y mi entorno funcionan, el problema es solo con fillbetween.

Estoy usando pgfplots 1.12.

Mi pregunta principal es¿por qué sucede esto?¿Es solo un error o no entiendo algo profundo? He leído pgfplots recientesregistro de cambiossobre fillbetween, pero este problema no existe. No me sorprendería si se trata de un error, entonces sería bueno contárselo a los demás.

Sería interesante ver otras soluciones.

Mi intención original era crear varias tramas que varían en algunos parámetros y decoraciones, pero que tienen mucho en común que quería definir como un entorno (parece más (La)TeXnical que los comandos de apertura y cierre).

Respuesta1

Esto se debe a un par \begingroup/ adicional \endgroupque se introduce \newenvironmentcombinado con magia profunda que comunica el conjunto de capas gráficas desde el eje hasta la imagen tikz.

Básicamente hay tres formas de solucionarlo:

1]Activar gráficos en capasa manoantes de tu eje:

\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] Use magia profunda que depende de las partes internas de 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] uso

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

En lugar del entorno LaTeX (estas macros están definidas por \newenvironment).


Explicación: fill betweenactiva implícitamente gráficos en capas de modo que la región rellena seabajolas parcelas delimitadoras aunque haya sido definidadespuésellos en el código. Este conjunto de gráficos en capas debe comunicarse al tikzpicture adjunto, y eso (desafortunadamente) está sujeto a construcciones de agrupación TeX: cada \endgroupborra dichas listas. La solución de PGF/pgfplots parece funcionar en casos estándar, y falló en este caso.

Eso significa que la imagen también funcionaría si escribieras fill between[on layer={}]para desactivar la capa adicional (pero se vería diferente).

¿Es esto un error? No lo sé, sinceramente... quizás debería arreglarse de alguna manera.

información relacionada