我正在使用该pgfplots
包尝试绘制函数s(p0) = sign(Re p0) sign(Im p0)
,其中p0
是复数。到目前为止,我得到的是
\documentclass[svgnames]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
ticks=none,
xlabel=$\mathrm{Re}(p_0)$,
ylabel=$\mathrm{Im}(p_0)$,
zlabel=$s(p_0)$]
\addplot3[surf,domain=-1:1,color=DarkBlue!20]{x/abs(x)*y/abs(y)};
\addplot3[mesh,domain=-1:1,color=black,samples=10]{0};% complex plane
\end{axis}
\end{tikzpicture}
\end{document}
这就产生了这个相当丑陋的情节。
我想要的是类似这样的东西:
所以我的问题是,我该怎么做
- 消除那些令人厌烦的“悬崖”,
- 为复杂平面添加低不透明度颜色,即网格
z = 0
- 添加适当的深度感知,
- 在轴上少量添加数字但不添加标记,即仅添加 -1、0 和 1,并且
- 不仅对网格而且对绘图的实际表面应用更漂亮的颜色。
答案1
- 消除那些令人厌烦的“悬崖”
Pgfplots 允许使用两种不同的方式排除表面的部分:通过为特定数据点分配“无界坐标”(如 z=nan)或使用“无界颜色数据”(点 meta=nan)。
下面我选择使用“无界颜色数据”,通过 的方式添加了一个合适的颜色数据point meta={abs(x) < 1e-3 || abs(y) < 1e-3 ? nan : z}
。这意味着 colordata 是一个标量nan
当x ~ 0 和 y ~0 时为值z
,否则为 值。这意味着中间的轴变得不可见(即相邻的表面段被省略)。
详细信息:请参阅手册中的“4.5.14 中断图”部分。
- “向复杂平面添加低不透明度颜色”
我将其添加opacity=0.7
到其选项列表中。可以添加任何类型的 tikz 绘图选项,这就是配置不透明度的方式。请参阅 tikz 手册以获取图形状态选项的完整列表(pgfmanual.pdf)
- “添加适当的深度感知”
在撰写本文时,pgfplots 根本无法做到这一点。为了组合多个重叠表面,您有两种选择:求助于另一个 3D 可视化工具或手动重新排序表面段。
由于这个问题是关于 pgfplots 的,所以我采用了第二种方法。在我的例子中,结果是二跳跃图的表面:一个在复平面上方,一个在复平面下方。为此,我简单地修改了现有的过滤器,分别point meta
添加了z>0
或z<0
。见下文。
- “添加数字但不添加标记”
我使用了以下xtick distance
组合tickwidth
- “应用更漂亮的颜色”
“更漂亮”是什么意思?就我个人而言,我喜欢网格颜色“接近”表面颜色;pgfplots
默认情况下就是这样的。因此,我只是将您的颜色覆盖恢复为默认值。默认是将标量颜色数据映射到colormap
。有关此内容的详细信息可以在 pgfplots 手册中找到,或者可能是后续问题的主题。
我明确选择了复杂平面的颜色,因为它的色图映射很难控制(没有最小值/最大值)。当然,您可以轻松地将其推广到其他两个部分。
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xlabel=$\mathrm{Re}(p_0)$,
ylabel=$\mathrm{Im}(p_0)$,
zlabel=$s(p_0)$,
xtick distance=1,
ytick distance=1,
ztick distance=1,
tickwidth=0pt,
]
\addplot3[
surf,domain=-1:1,%color=DarkBlue!20,
point meta={abs(x) < 1e-3 || abs(y) < 1e-3 || z > 0 ? nan : z},
] {x/abs(x)*y/abs(y)};
\addplot3[
%mesh,
surf,
domain=-1:1,
opacity=0.7,
blue!50!white,faceted color={blue},
%color=black,
samples=10,
]{0};% complex plane
\addplot3[
surf,domain=-1:1,%color=DarkBlue!20,
point meta={abs(x) < 1e-3 || abs(y) < 1e-3 || z < 0 ? nan : z},
] {x/abs(x)*y/abs(y)};
\end{axis}
\end{tikzpicture}
\end{document}
答案2
过了一段时间再回过头来看这个问题,我觉得最简单的解决办法可能就是指定坐标而不是绘制实际函数。这种方法既能缩短编译时间,又能减小文件大小。
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xlabel=$\Re(p_0)$,
ylabel=$\Im(p_0)$,
zlabel=$s(p_0)$,
domain=-1:1,
surf,shader=flat,
xtick distance=1,
ytick distance=1,
ztick distance=1,
tickwidth=0pt
]
\addplot3[blue!20] coordinates {
(-1,1,-1) (0,1,-1)
(-1,0,-1) (0,0,-1)
};
\addplot3[blue!20] coordinates {
(1,-1,-1) (0,-1,-1)
(1,0,-1) (0,0,-1)
};
% Zero plane
\addplot3[
gray,opacity=0.1,
samples=2,
]{0};
\addplot3[orange!80] coordinates {
(0,0,1) (1,0,1)
(0,1,1) (1,1,1)
};
\addplot3[orange!80] coordinates {
(0,0,1) (-1,0,1)
(0,-1,1) (-1,-1,1)
};
\end{axis}
\end{tikzpicture}
\end{document}