在Mathematica中绘制一个复杂函数

22
我该如何制作一个Mathematica图形,以复制sage中complex_plot的行为?即

...取一个单变量的复杂函数,并将函数的输出绘制在指定的xrange和yrange上,如下所示。输出的大小由亮度表示(零为黑色,无穷为白色),而参数则由色调表示(红色为正实数,随着参数的增加而逐渐增加,从橙色、黄色等颜色开始)。

这里是一个例子(从Neutral Drifts的M. Hampton中窃取)zeta函数的绝对值轮廓叠加:

zeta function complex_plot

在Mathematica文档页面复变函数中,它说你可以使用ContourPlotDensityPlot "潜在地通过相位着色"来可视化复杂函数。但问题是在这两种类型的图中,ColorFunction只接受一个变量等于该点处的轮廓或密度 - 因此似乎不可能在绘制绝对值时将其着色为相位/参数。请注意,这不是Plot3D的问题,其中所有3个参数(x,y,z)都传递给ColorFunction
我知道有其他方法来可视化复杂函数 - 比如Plot3D文档中的“整洁示例”,但那不是我想要的。
此外,我确实有下面的一种解决方案(实际上已用于生成一些在维基百科中使用的图形),但它定义了一个相当低级的函数,我认为应该可以使用高级函数如ContourPlotDensityPlot来实现。不过这并不妨碍您提供使用较低级别构造的最喜欢的方法!

编辑:Mathematica杂志上有一些Michael Trott写的好文章,涉及以下内容:
可视化代数函数的黎曼曲面IIaIIbIIcIId
可视化黎曼曲面演示
黎曼曲面重返(针对Mma v6的更新)

当然,Michael Trott也写了Mathematica指南书,其中包含许多精美的图形,但似乎已经落后于加速的Mathematica发布计划!


我还没有看问题,但是因为美丽的情节+1 :) - Dr. belisarius
@belisarius:这不是我的情节,但谢谢! - Simon
@MikeBantegui:请注意,您函数中只能使用 x 参数,并且对应于每个点的密度。请参阅 ColorFunction 文档中“更多信息”部分的第一个条目。奇怪的是它没有产生警告... - Simon
@Mike,只有x给出了任何信息,如果您使用ColorFunction->Function[{x,y,z}, Hue@(y/maxy)],您只会得到灰色。但是,使用x/maxx会给你带来一些东西。 - rcollyer
应该将此内容迁移到http://mathematica.stackexchange.com。 - user719662
显示剩余2条评论
4个回答

20
这是我的尝试,我稍微调整了颜色函数。
ParametricPlot[
 (*just need a vis function that will allow x and y to be in the color function*)
 {x, y}, {x, -6, 3}, {y, -3, 3},

 (*color and mesh functions don't trigger refinement, so just use a big grid*)
 PlotPoints -> 50, MaxRecursion -> 0, Mesh -> 50,

 (*turn off scaling so we can do computations with the actual complex values*)
 ColorFunctionScaling -> False,

 ColorFunction -> (Hue[
     (*hue according to argument, with shift so arg(z)==0 is red*)
     Rescale[Arg[Zeta[# + I #2]], {-Pi, Pi}, {0, 1} + 0.5], 1,

     (*fudge brightness a bit: 
       0.1 keeps things from getting too dark, 
       2 forces some actual bright areas*)
     Rescale[Log[Abs[Zeta[# + I #2]]], {-Infinity, Infinity}, {0.1, 2}]] &),

 (*mesh lines according to magnitude, scaled to avoid the pole at z=1*)
 MeshFunctions -> {Log[Abs[Zeta[#1 + I #2]]] &},

 (*turn off axes, because I don't like them with frames*)
 Axes -> False
 ]

复杂图形

我还没有想到一种好的方法来使网格线的颜色变化。 最简单的方法可能是使用ContourPlot生成它们,而不是使用MeshFunctions


1
不错!这非常接近我看到的解决方案,它使用RegionPlot[True, {x, xmin, xmax}, {y, ymin, ymax}, opts...]作为基本的Graphics对象。 - Simon
@BrettChampion 不错的图表!有没有一种简单的方法可以包含某种图例,其中色调从 -pi 到 pi? - Nick

15

以下是我对Axel Boldt提供的函数的变化版本,他受到Jan Homann的启发。这两个链接页面都具有一些不错的图形。

ComplexGraph[f_, {xmin_, xmax_}, {ymin_, ymax_}, opts:OptionsPattern[]] := 
 RegionPlot[True, {x, xmin, xmax}, {y, ymin, ymax}, opts, 
  PlotPoints -> 100, ColorFunctionScaling -> False,
  ColorFunction -> Function[{x, y}, With[{ff = f[x + I y]}, 
    Hue[(2. Pi)^-1 Mod[Arg[ff], 2 Pi], 1, 1 - (1.2 + 10 Log[Abs[ff] + 1])^-1]]]
 ]

然后我们可以通过运行以下命令来制作没有等高线的图表

ComplexGraph[Zeta, {-7, 3}, {-3, 3}]

没有轮廓的Zeta函数

我们可以通过在ComplexGraph中使用特定的绘图网格,像Brett所做的那样,添加轮廓:

ComplexGraph[Zeta, {-7, 3}, {-3, 3}, Mesh -> 30, 
 MeshFunctions -> {Log[Abs[Zeta[#1 + I #2]]] &},
 MeshStyle -> {{Thin, Black}, None}, MaxRecursion -> 0]

或者通过与等高线图结合使用,例如

ContourPlot[Abs[Zeta[x + I y]], {x, -7, 3}, {y, -3, 3}, PlotPoints -> 100,
 Contours -> Exp@Range[-7, 1, .25], ContourShading -> None];
Show[{ComplexGraph[Zeta, {-7, 3}, {-3, 3}],%}]

带轮廓的图像


8

这不是一个恰当的答案,有两个原因:

  • 这不是你所问的内容
  • 我在无耻地使用Brett的代码

无论如何,对我来说以下内容更容易解释(亮度只是…好吧,只是亮度):

enter image description here

Brett的代码几乎完整保留:

Plot3D[
 Log[Abs[Zeta[x + I y]]], {x, -6, 3}, {y, -3, 3},
 (*color and mesh functions don't trigger refinement,so just use a big grid*)
 PlotPoints -> 50, MaxRecursion -> 0, 
 Mesh -> 50, 
 (*turn off scaling so we can do computations with the actual complex values*)
 ColorFunctionScaling -> False, 
 ColorFunction -> (Hue[
     (*hue according to argument,with shift so arg(z)==0 is red*)
     Rescale[Arg[Zeta[# + I #2]], {-Pi, Pi}, {0, 1} + 0.5], 
     1,(*fudge brightness a bit:
     0.1 keeps things from getting too dark,
     2 forces some actual bright areas*)
     Rescale[Log[Abs[Zeta[# + I #2]]], {-Infinity, Infinity}, {0.1, 2}]] &),
     (*mesh lines according to magnitude,scaled to avoid the pole at z=1*)
     MeshFunctions -> {Log[Abs[Zeta[#1 + I #2]]] &},
     (*turn off axes,because I don't like them with frames*)
     Axes -> False]

不是一个恰当的答案,但我同意 - 它确实使某些方面更清晰,而且很漂亮!+1 - Simon

1

对于所有想要在Python中实现此目标的人,我创建了cplot。安装方式如下:

pip install cplot

这段文字描述了对exp的6次泰勒多项式进行域着色绘图:
import cplot


def exp_taylor(z):
    s = 1.0
    t = 1.0
    for k in range(1, 7):
        t *= z / k
        s += t
    return s

plt = cplot.plot(
    exp_taylor,
    # or something simpler
    # lambda z: z ** 6 + 1,
    (-5, +5, 400),
    (-5, +5, 400),
)
plt.show()

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接