我正在尝试绘制复平面中平方根的分支/黎曼曲面(例如维基百科)。为了对平方根的虚部进行编码,我尝试使用颜色wave
输入格式为颜色提供具体的值。
我使用极坐标 (x cos(y), x sin(y)),平方根的实部应该是 sqrt(x) cos(y/2),而颜色的虚部是 sqrt(x) sin(y/2)。
考虑以下代码:
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot3 [
surf,
domain=0:4,
domain y=-pi:3*pi,
mesh/color input=explicit mathparse,
point meta={symbolic={wave=363+(2+sqrt(x)*sin(deg(y/2)))/4*(814-363)}}
]
(x,y,0); % This works just fine
% ({x*cos(deg(y))}, {x*sin(deg(y))}, {sqrt(x)*cos(deg(y/2))}); % This breaks!
\end{axis}
\end{tikzpicture}
\end{document}
绘制水平面不会产生任何问题。但使用实际绘图时,我收到以下错误消息:
Package pgfplots Error: Sorry, the color component value nan (no. 0) is out of range. The allowed range is 0 <= value <= 1. The error occured near `point meta 'wave=363+(2+sqrt(x)*sin(deg(y/2)))/4*(814-363)' of coord no 6 (2Y9.99975739e-1],2Y3.141592654e0],0Y0.0e0])'.
这也发生在其他坐标上。
编辑:我把它归结为第一个论点,这cos(deg(y))
似乎是问题所在。
编辑:它看起来应该是这样的:
此图片取自维基百科注意颜色分布。例如,黄色、绿色和青色出现了两次,而蓝色和红色只出现了一次。更准确地说,两个黄色部分并不是精确地位于另一个之上,而是沿着实线反射。
编辑:只是写下我写的评论:更不用说这个代码,它与官方文档,第 151 页,经过一些修改后失败。
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot3 [
surf,
domain=0:1,
domain y=0:1,
mesh/color input=explicit mathparse,
point meta={symbolic={wave=363+x*(814-363)}}
]
(x,y,0); % This works just fine
% (y,x,0); % This breaks!
\end{axis}
\end{tikzpicture}
\end{document}
答案1
我不熟悉如何定义颜色图,但你的绘图问题可以通过使用精确的引擎来计算点来解决。总是有选择(Asymptote、lua 等)。我推荐智者有几个原因。首先,它是一个 CAS(计算机代数系统),因此它是提供精确计算的最高级别的数学软件。其次,作为 CAS,您可以使用其他程序无法访问的内置功能(导数、矩阵、图论、微分方程等)。第三,您可以使用 Python,这允许您绕过 LaTeX 编程。第四,SAGE 单元服务器(或 Sagemath 应用程序)可以帮助您轻松地从平板电脑上进行修改。以下是使用sagetex
和jet
颜色图的解决方案:
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{sagetex}
\pgfplotsset{compat=1.15}
\begin{document}
\begin{sagesilent}
var('x,y')
xcoords = [i for i in srange(0,4,.2)]
ycoords = [i for i in srange(-3.14,9.52,.2)]
output = ""
output += r"\begin{tikzpicture}[scale=1.0]"
output += r"\begin{axis}[view={-10}{-40},xmin=%d, xmax=%d, ymin=%d, ymax=%d]"%(-4,4,-4,4)
output += r"\addplot3[colormap/jet,surf,opacity=0.5,mesh/rows=%d] coordinates {"%(len(ycoords))
# the length of ycoords is the number of y values
for y in ycoords:
for x in xcoords:
output += r"(%f, %f, %f) "%(x*cos(y),x*sin(y),sqrt(x)*cos(y/2))
output += r"};"
output += r"\end{axis}"
output += r"\end{tikzpicture}"
\end{sagesilent}
\sagestr{output}
\end{document}
Cocalc 中的结果是:
我已经设置了opacity=0.5
,您可能想试验一下该值。
该行在xcoords = [i for i in srange(0,4,.2)]
Python 中创建了我的 x 值列表,范围从 0、.2、.4 到 3.8,y 值由 SAGE 创建,这提供了我们期望的精度。sagetex
在 Python 的帮助下,需要 3 个步骤才能将我的代码创建为字符串。将for-loop
坐标放入字符串中,最终使用 将其放入文档中\sagestr{output}
。
SAGE 不是 LaTeX 发行版的一部分。最简单的试用方法是获取免费的Cocalc 账户。您也可以将 SAGE 下载到您的计算机并使其与您的 LaTeX 发行版配合使用,但这是一个更长且更困难的过程。搜索此网站以获取有关如何sagetex
使用该软件包的更多示例。
编辑:我认为你的方法的问题在于这x
不是我们想要的。我们认为x
是非负的,因为你将其定义为介于 0 和 4 之间,但根据绘图程序,
x
的值是。我注意到,如果我使用 sqrt(abs(x)),程序运行良好:
x
x*cos(y)
如果我删除绝对值那么它根本无法编译:
请注意错误消息告诉我该值需要介于 0 和 1 之间。当我检查我的数据文件时,它显示许多为负的 x 值:
在我看来,这wave=363+(2+sqrt(x)*sin(deg(y/2)))/4*(814-363)
是在计算 x 值的平方根:{x*cos(deg(y))}
而不是x
您定义的 0 到 4 之间的值。由于{x*cos(deg(y))}
是负数,平方根给出的是一个虚数,不在 [0,1] 内。我不知道在这种情况下如何使wave
颜色图工作。
答案2
这不是一个令人满意的答案,因为这不会解决这个错误,但是我今天用渐近线弄脏了我的手,我很高兴(虽然渐近线并不总是能很好地将 3d 图形渲染为矢量图形)。
\documentclass[convert]{standalone}
\usepackage{asymptote}
\begin{document}
\begin{asy}
settings.prc = false;
settings.render = 0;
unitsize(1cm);
fontsize(11pt);
size(5cm);
import graph3;
import palette;
currentprojection=orthographic(-0.8,-1.1,0.8);
int angles = 60;
int radii = 15;
triple f(pair z) { // using polar coordinates
return (z.x * cos(z.y), z.x * sin(z.y), sqrt(z.x) * cos(z.y/2));
}
triple c(pair z) { // using polar coordinates
return (z.x * cos(z.y), z.x * sin(z.y), sqrt(z.x) * sin(z.y/2));
}
surface s = surface(f, (0,-pi), (1,3pi), nu=radii, nv=angles, Spline);
pen[][] p = palette(surface(c, (0,-pi), (1,3pi), nu=radii, nv=angles).map(zpart), Wheel());
draw(s, mean(p), meshpen=black+linewidth(0.2pt));
xaxis3(Bounds(Min, Min), -1, 1, OutTicks(2,2));
yaxis3(Bounds(Min, Min), -1, 1, OutTicks(2,2));
zaxis3(Bounds(Min, Max), -1, 1, OutTicks(2,2));
\end{asy}
\end{document}