为什么图表在这里上移了?

为什么图表在这里上移了?

我想在下图中添加一个半透明的垂直红色分隔线,其中方程式为 x+y-30。它应该将曲线分成两部分。

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

当我运行代码时,我得到了这个奇怪的结果

我不明白为什么原来的曲线会向上移动。

这就是我想看到的

(另外,我想知道改变视图的最佳方法是什么。我想从查看框左角的角度查看图表。)

答案1

不幸的是,这种叠加在 中还不可用pgfplots。唯一的解决方案是分别绘制表面的不同部分,在本例中是相交平面,以正确​​的顺序绘制,以便它们正确重叠。要在非矩形域上绘制函数,必须对要使用的域进行参数化。在这种情况下,从上方看,我们将得到一个三角形和一个多边形。

在此处输入图片描述

根据顶点对三角形进行参数化很简单,但对于多边形来说,这可能很复杂。我认为最简单的解决方案是将多边形划分为额外的三角形。 在此处输入图片描述

要参数化一个三角形,给定三个顶点p1p2p3,您可以使用以下参数化:

等值1

等值2

获得这些值后,我们现在可以绘制所有表面以获得完整的表面。此外,必须设置较高的采样率,否则,由于低质量渲染导致的边缘不规则会导致部分表面连接处出现间隙。这是一个非常苛刻的解决方案,因此下面是使用选项的代码和结果shell-escapegnuplot

仅使用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}

在此处输入图片描述

使用pgfplotsgnuplot

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

在此处输入图片描述

要更改视图,您可以使用该view/h= angle选项,记住相应地调整表面的顺序以实现正确的重叠。

两种方法的渲染效果有些不同。我还没有找到更好的效果,不过你可以随意调整采样,看看能否找到更好的组合。

相关内容