Спасибо 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 и построить график с помощью графической опции.