Contorno parcialmente oculto por uma superfície em pgfplots

Contorno parcialmente oculto por uma superfície em pgfplots

Obrigado à SE (e particularmente a estas duas perguntas:Desenhe uma distribuição normal bivariada em TikZeComo corrigir um gráfico de contorno no topo de uma caixa 3D), consegui desenhar o que procurava com o pgfplots, exceto por um detalhe.

Nesta imagem:

esta imagem

Gostaria que as linhas de contorno desenhadas na superfície fossem ocultadas pela superfície em primeiro plano, mas não no fundo (como seria se você estivesse realmente olhando para esse "vale"). É possível fazer isso?

Aqui está o código (eu fiz downgrade da amostragem para fazê-la rodar mais rápido e não se esqueça da -shell-escapeopção de fazê-la rodar com LaTeX).

\documentclass{standalone}

\usepackage{pgfplots}

\usepackage{amsmath}

\begin{document}

\pgfplotsset{
colormap={whitered}{color(0cm)=(white); color(1cm)=(orange!75!red)}
}

\begin{tikzpicture}
  \begin{axis}[
    colormap name=whitered,
    3d box,
    width=15cm,
    view={25}{25},
    enlargelimits=false,
    grid=major,
    domain=-0.5:4.7,
    y domain=-2:2,
    samples=21,
    xlabel=$x$,
    ylabel=$\dot{x}$,
    zlabel={$\text{E}_{\text{m}}$},
    colorbar,
    colorbar style={
        at={(1,0)},
        anchor=south west,
        height=0.1*\pgfkeysvalueof{/pgfplots/parent axis height},
        title={$\text{E}_{\text{m}}(x,\dot{x})$}
        }
    ]
\addplot3 [surf] {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};
\addplot3 [contour gnuplot={number=14,labels={false},draw color=black},
    samples=21,
    ] {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};
\addplot3 [domain=-0.5:4.7,samples=31, samples y=0, thick, smooth]
    (x,-2,{-0.6+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi))});
\addplot3 [contour gnuplot={number=14,labels={false},draw color=black},
    samples=21,
    z filter/.code={\def\pgfmathresult{20}},
    ] {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};

  \end{axis}
\end{tikzpicture}
\end{document}

Responder1

Isto é muito difícil com a versão atual dopgfplots. A simples razão é que o z-buffering não está totalmente implementado.

Na verdade, estou um pouco inseguro sobre isso, pois não segui essa parte do pgfplots.

Portanto, você deve fazer seu próprio buffer z (que pode ser bastante complicado). Isso significa que você tem que desenhar as peças em termos de sua aparência na tela e, portanto, muitos desenhos duplos.

Aqui está um começo:

\addplot3 [y domain=0:2,surf]
    {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};

\addplot3 [y domain=0:2,contour gnuplot={number=14,labels={false},draw color=black},samples=21, ] 
    {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};

\addplot3 [domain=-0.5:4.7,samples=31, samples y=0, thick, smooth]
    (x,-2,{-0.6+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi))});
\addplot3 [contour gnuplot={number=14,labels={false},draw color=black},
    samples=21,z filter/.code={\def\pgfmathresult{20}}]
    {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};
\addplot3 [y domain=-2:0,surf] {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};
\addplot3 [domain=0:.25,contour gnuplot={number=14,labels={false},draw color=black},
    samples=21,
    ] {-0.7+4*exp(-0.5*(x+3))*(3*cos(4*x*180/pi)+2.5*cos(2*x*180/pi)) + 0.5*y*y*4};

que produz:

insira a descrição da imagem aqui

Como você pode ver, há algumas partes que precisam ser ajustadas, mas a ideia é óbvia. Desenhe ovoltarparte, depois os contornos, depois ofrenteparte e, em seguida, ajuste todos os pequenos detalhes no posicionamento através dos domínios até que resultados satisfatórios sejam alcançados.

Sim, isso não é viável com vários pontos de sela de grande magnitude, caso em que seria melhor exportar do Octave e plotar através da opção gráfica.

informação relacionada