如何使用 pgfplots 绘制特定的 Weierstrass 函数并获得良好的分辨率?

如何使用 pgfplots 绘制特定的 Weierstrass 函数并获得良好的分辨率?

我正在尝试绘制《小鲁丁》中描述的魏尔斯特拉斯函数。我并不是想绘制整个系列的图表——即使我能很好地绘制出它的第四或第五部分和,我也相对满意了。对于那些不熟悉鲁丁构造的人来说,它是这样的:

Define $g(x)=2|\frac{x}{2}-\lfloor\frac{x+1}{2}\rfloor|$ and $g_n(x)=(\frac{3}{4})^n g(4^n x)$。则 Weierstrass 函数为$\sum_{n=0}^\infty g_n(x)$.

我已经设法绘制了第四个部分和的图形,但我对其分辨率并不满意。我的函数与魏尔斯特拉斯函数不同,这个旧的 TeX SE 问题,但如果可能的话,我希望我的看起来更像那样。(我相信外观上的大部分差异仅仅是因为鲁丁的构造比经典的魏尔斯特拉斯函数定义更粗糙。)我创建的第四个部分和的图形在外观上相当参差不齐,看起来像这样:

鲁丁魏尔斯特拉斯函数的四次部分和

我希望在 pgfplots 中仍然可以做一些事情来改善它的外观。(我已经将图中的样本数量推到了一个非常大的值,但我不确定这是否真的有很大帮助。)这是我的代码:

    \documentclass[12pt]{article}
    \usepackage{tikz}
    \usepackage{pgfplots}
    \usepackage{pgfplotstable}
    \pgfplotsset{compat=1.13}
    \usepgfplotslibrary{fillbetween}
    
    \begin{document}
    \begin{tikzpicture}
    \begin{axis}
    [
      axis line style=ultra thick,
      axis x line=center,
      axis y line=center,
      grid=none,
      unit vector ratio=1 1,
      width=3.5in,
      xmin=-1.25, xmax=2.25,
      ymin=-.25, ymax=2.5,
      xtick={-1,0,...,2},
      ytick={-2,-1,...,2},
    ]
    \addplot[black, domain=-1.3:2.3, samples=30000] {2*abs(x/2-floor(x/2+.5))+3/4*2*abs(4*x/2-floor(4*x/2+.5))+9/16*2*abs(16*x/2-floor(16*x/2+.5))+27/64*2*abs(64*x/2-floor(64*x/2+.5))+81/256*2*abs(256*x/2-floor(256*x/2+.5))};
    \end{axis}
    \end{tikzpicture}
    \end{document}

答案1

首先,你说,“我相信外观上的差异很大程度上只是因为鲁丁的构造比经典的魏尔斯特拉斯函数定义更粗糙。)我创建的第四部分和的图形在外观上相当参差不齐......”。你存在的不确定性可以通过弄清楚函数应该是什么样子来解决。如果你去Sage 单元服务器并复制/粘贴代码:

var('i,n,t')
g(x)=2*abs(x/2-floor((x+1)/2))
g(n,x)=(3/4)^n*g(4^n*x)
f=sum(g(i,x),i,0,10)
plot(f,(x,-1,2))

然后按Evaluate,你会得到 在此处输入图片描述

n=40 之后。这基本上就是 n=4 之后的图表。这告诉我,基本图不会发生太大变化。

其次,您还说过,“我希望在 pgfplots 中仍然可以做一些事情来改善它的外观。(我已经将图中的样本数量推到一个非常大的值,但我不确定这是否真的有很大帮助。)”。增加样本量samples=30000是个坏主意。这是您使用的 x 值的数量。-1 和 2 之间的 30,000 个样本是绘制在两个连续整数之间的 10,000 个点。通常,连续整数之间的 100 个 x 值应该是不错的。如果您查看链接到的 Weierstrass 图的许多响应并希望您的图表看起来更像,则样本数量相当低。例如,Jake 的答案有samples=301

第三,除了使用 Sage 对您的工作进行快速健全性检查外,鼠尾草包将其与 LaTeX 和 Python 链接起来,以准确处理更多迭代。这对于像您这样的复杂函数来说至关重要,因为pgfplots 的精度有限。在这些情况下,Sage 可以成为生成准确绘图数据的引擎。以下是 n=10 的 Weierstrass 函数的实现。

\documentclass[11pt,border=1mm]{standalone}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tikz,pgfplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{sagesilent}
y=var('y')
LowerX = -1.3
UpperX = 2.31
LowerY = 0
UpperY = 3
var('i,n,t')
g(x)=2*abs(x/2-floor((x+1)/2))
g(n,x)=(3/4)^n*g(4^n*x)
f(x)=sum(g(i,x),i,0,10)

x_coords = [t for t in srange(LowerX,UpperX,.01)]
y_coords = [f(x=t).n(digits=4) for t in x_coords]

output = r""
output += r"\begin{tikzpicture}[scale=1.0]"
output += r"\begin{axis}[xmin=%f,xmax=%f,ymin= %f,ymax=%f,width=10cm]"%(LowerX,UpperX,LowerY, UpperY)
output += r"\addplot[thin, blue, unbounded coords=jump] coordinates {"
for i in range(0,len(x_coords)-1):
    if (y_coords[i])<LowerY or (y_coords[i])>UpperY:
        output += r"(%f , inf) "%(x_coords[i])
    else:
        output += r"(%f , %f) "%(x_coords[i],y_coords[i])
output += r"};"
output += r"\end{axis}"
output += r"\end{tikzpicture}"
\end{sagesilent}
\sagestr{output}
\end{document} 

在 Cocalc 中运行代码可得到

在此处输入图片描述

如果您想要 x/y 轴,请添加axis lines=middlewhere \begin{axis},如下所示。我不喜欢该函数覆盖 y 轴数字 在此处输入图片描述

在此过程中,我注意到我对函数的绘图使用的是细线(thin, blue)。运行代码,使用samples=300细线绘图会使您的原始绘图(n = 4)看起来更好。

最后,Sage 不是 LaTeX 发行版的一部分。该网站是这里; Sage 可以免费下载到您的计算机并链接到您的 LaTeX 程序,但根据计算机和计算机技能,这可能会有问题。使用 Sage 进行实验的最简单方法sagetex是获取免费的可钙帐户并将上面提供的代码复制/粘贴到 LaTeX 文档中。

相关内容