Контур, частично скрытый поверхностью в pgfplots

Контур, частично скрытый поверхностью в pgfplots

Спасибо SE (и особенно за эти два вопроса:Нарисуйте двумерное нормальное распределение в TikZиКак исправить контурную диаграмму в верхней части 3D-блока), мне удалось нарисовать то, что я искал, с помощью pgfplots, за исключением одной детали.

На этом изображении:

это изображение

Я бы хотел, чтобы контурные линии, нарисованные на поверхности, были скрыты поверхностью на переднем плане, но не на заднем (как если бы вы действительно смотрели на такую ​​"долину"). Возможно ли это сделать?

Вот код (я понизил качество выборки, чтобы ускорить ее выполнение, и не забудьте о -shell-escapeвозможности запустить ее с помощью 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}

решение1

Это очень сложно сделать с текущей версиейpgfplots. Причина проста: z-буферизация реализована не полностью.

На самом деле я немного в этом не уверен, так как не следил за этой частью pgfplots.

Следовательно, вам следует сделать собственную z-буферизацию (что может быть довольно обременительно). Это означает, что вам придется рисовать детали в соответствии с их внешним видом на экране, и, следовательно, много двойных отрисовок.

Вот начало:

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

который производит:

введите описание изображения здесь

Как вы видите, есть некоторые детали, которые нужно доработать, но идея очевидна. Нарисуйтеназадчасть, затем контуры, затемпереднийчасть, а затем дорабатываем все мелкие детали размещения через домены до тех пор, пока не достигнем удовлетворительных результатов.

Да, это невозможно при наличии нескольких седловых точек большой величины, в этом случае лучше экспортировать данные из Octave и построить график с помощью графической опции.

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