
Quiero agregar un divisor rojo vertical translúcido con la ecuación x+y-30 al siguiente gráfico. Debería cortar la curva en dos secciones.
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.17}
\begin{document}
\begin{tikzpicture}
\begin{axis} [
xtick = {0,20,...,100},
ytick = {0,20,...,60},
ztick = {0,40,...,120},
xlabel = $U_A$, ylabel = $U_B$, zlabel = $S$,
zlabel style={rotate=-90},
ticklabel style = {font = \scriptsize},
colormap/cool
]
\addplot3[name path=toppath, domain=0:30, fill=blue, opacity=0.1, fill opacity=0.4,samples=30] (x,30-x,120);
\addplot3[name path=botpath, domain=0:30, fill=blue, opacity=0.1, fill opacity=0.4,samples=30] (x,30-x,0);
\addplot [red] fill between[of=toppath and botpath];
\addplot3 [surf, shader=interp, domain=0:100, domain y=0:60, samples=56]
{ ln((100!/(x!*(100-x)!))*(60!/(y!*(60-y)!))) };
\end{axis}
\end{tikzpicture}
\end{document}
Cuando ejecuto el código, obtuve este resultado extraño.
No entiendo por qué la curva original se desplaza hacia arriba.
esto es lo que quiero ver
(Además, me pregunto cuál es la mejor manera de cambiar la vista. Quiero ver el gráfico desde la perspectiva de la esquina izquierda del cuadro de visualización).
Respuesta1
Lamentablemente, este tipo de superposición aún no está disponible en formato pgfplots
. La única solución es trazar diferentes partes de la superficie por separado, y en este caso del plano de intersección, en el orden correcto para que se superpongan correctamente. Para trazar una función en un dominio no rectangular, es necesario parametrizar el dominio que desea utilizar. En este caso, mirando desde arriba, tendremos un triángulo y un polígono.
Parametrizar triángulos teniendo en cuenta sus vértices es sencillo, pero para polígonos puede resultar complicado. Creo que la solución más sencilla es dividir el polígono en triángulos adicionales.
Para parametrizar un triángulo, dados tres vértices y
,
puede utilizar la siguiente parametrización:
Obtenidos los valores, ahora podemos trazar todas las superficies para obtener la completa. Además, es necesario establecer una frecuencia de muestreo alta; de lo contrario, las irregularidades en los bordes debido a un renderizado de baja calidad provocarán espacios entre las uniones de las superficies parciales. Esta es una solución muy exigente, por lo que a continuación está el código y el gráfico resultante usando shell-escape
la opción with gnuplot
too.
Usando solo pgfplots
:
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
\begin{axis} [
xtick = {0,20,...,100},
ytick = {0,20,...,60},
ztick = {0,40,...,120},
xlabel = $U_A$, ylabel = $U_B$, zlabel = $S$,
zlabel style={rotate=-90},
ticklabel style = {font = \scriptsize},
colormap/cool,
variable=s,
variable y=t,
domain=0:1,
view/h=15,
]
\addplot3 [surf, shader=interp, samples=80, samples y=80] ({100-100*s},{-30*s-30*t*s+60},{ ln((100!/(x!*(100-x)!))*(60!/(y!*(60-y)!))) }); %B
\addplot3 [surf,shader=interp, samples=30, samples y=30,] ({100*t*s+30-30*s},{30*s+30*t*s},{ ln((100!/(x!*(100-x)!))*(60!/(y!*(60-y)!))) }); %C
\addplot3 [surf, shader=interp, samples=30, samples y=30,] ({100+70*t*s-70*s},{60*t*s},{ ln((100!/(x!*(100-x)!))*(60!/(y!*(60-y)!))) }); %D
\addplot3 [patch, fill=red, patch type=rectangle] coordinates {(0,30,120) (30,0,120) (30,0,0) (0,30,0)};
\addplot3 [surf, shader=interp, samples=30, samples y=30] ({30-30*s},{30*s*t},{ ln((100!/(x!*(100-x)!))*(60!/(y!*(60-y)!))) }); %A
\end{axis}
\end{tikzpicture}
\end{document}
Usando pgfplots
y gnuplot
:
\documentclass[border=10pt, convert={true}]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
\begin{axis} [
xtick = {0,20,...,100},
ytick = {0,20,...,60},
ztick = {0,40,...,120},
xlabel = $U_A$, ylabel = $U_B$, zlabel = $S$,
zlabel style={rotate=-90},
ticklabel style = {font = \scriptsize},
colormap/cool,
view/h=15,
]
\addplot3[surf, shader=interp, thick ] gnuplot [ raw gnuplot, id=B ] {
set samples 60,60;
set isosamples 60,60;
set parametric;
fx(u,v)=100-100*u;
fy(u,v)=-30*u-30*v*u+60;
fz(u,v)= log((100!/((int((100-100*u)))!*(100-int((100-100*u)))!))*(60!/((int((-30*u-30*v*u+60)))!*(60-int((-30*u-30*v*u+60)))!)));
splot [0:1][0:1] fx(u,v), fy(u,v), fz(u,v)}; %B
\addplot3[surf, shader=interp] gnuplot [ raw gnuplot, id=C] {
set samples 60,60;
set isosamples 60,60;
set parametric;
gx(u,v)=100*v*u+30-30*u;
gy(u,v)=30*u+30*v*u;
gz(u,v)= log((100!/((int(100*v*u+30-30*u))!*(100-int(100*v*u+30-30*u))!))*(60!/((int(30*u+30*v*u))!*(60-int(30*u+30*v*u))!)));
splot [0:1][0:1] gx(u,v), gy(u,v), gz(u,v) }; %C
\addplot3[surf, shader=interp] gnuplot [ raw gnuplot, id=D] {
set samples 60,60;
set isosamples 60,60;
set parametric;
hx(u,v)=100+70*v*u-70*u;
hy(u,v)= 60*v*u;
hz(u,v)=log((100!/((int(100+70*v*u-70*u))!*(100-int(100+70*v*u-70*u))!))*(60!/((int(60*v*u))!*(60-int(60*v*u))!)));
splot [0:1][0:1] hx(u,v), hy(u,v), hz(u,v) }; %D
\addplot3 [patch, fill=red, patch type=rectangle] coordinates {(0,30,120) (30,0,120) (30,0,0) (0,30,0)};
\addplot3[surf, shader=interp] gnuplot [raw gnuplot, id=A ] {
set samples 60,60;
set isosamples 60,60;
set parametric;
splot [0:1][0:1] 30-30*u,30*u*v,log((100!/((int(30-30*u))!*(100-int(30-30*u))!))*(60!/((int(30*u*v))!*(60-int(30*u*v))!))) }; %A
\end{axis}
\end{tikzpicture}
\end{document}
Para cambiar la vista, puede utilizar la view/h= angle
opción, recordando ajustar el orden de las superficies en consecuencia para lograr la superposición correcta.
Existen algunas diferencias en la representación de los dos métodos. No he podido lograr mejores resultados, pero siéntete libre de ajustar el muestreo para ver si puedes encontrar una mejor combinación.