我一直想知道像mathematica 和mathlab 之类的程序是如何如此优雅而快速地绘制函数图的。谁能向我解释他们是如何做到这一点的,此外,我该如何做到这一点?它与计算机编程或数学的某个方面或课程有关吗?那是哪个?
4 回答
好吧,在 belisarius 的鼓励下,这是我的评论作为答案:尝试查看matplotlib。从主页:
matplotlib 是一个 python 2D 绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量数据。matplotlib 可用于 python 脚本、python 和 ipython shell(ala MATLAB®* 或 Mathematica®†)、Web 应用程序服务器和六个图形用户界面工具包。
它最初的灵感来自 MATLAB 的绘图功能,尽管从那时起它已经发展了很多。它是可靠的软件——它是开源的,在 BSD 许可下,所以你不仅可以阅读源代码,还可以破解它并在任何你喜欢的地方使用它。
您可以查看的另一个地方是gnuplot。它不是常见的开源许可证之一,但它肯定是开源的,具有一些修改权限等。
Gnuplot 是一个便携式命令行驱动的绘图实用程序,适用于 linux、OS/2、MS Windows、OSX、VMS 和许多其他平台。源代码受版权保护,但可免费分发(即,您不必为此付费)。它最初是为了让科学家和学生以交互方式可视化数学函数和数据而创建的,但已经发展到支持许多非交互用途,例如 Web 脚本。它还被 Octave 等第三方应用程序用作绘图引擎。自 1986 年以来,Gnuplot 一直受到支持并正在积极开发中。
它也可以进行 3D 绘图,而 matplotlib 没有,而且它的存在时间要长得多。我首先想到 matplotlib 的原因是它旨在作为高级语言的库,而不是独立的应用程序,所以我猜它可能更容易阅读。
另一个建议,只是为了了解 Mathematica 在幕后所做的各种事情,是查看Plot 的文档。特别是,如果您查看可用选项,您可以推断出一些事情。
MaxRecursion
Automatic
递归细分的最大数量允许Method
Automatic
该方法用于细化曲线PerformanceGoal
$PerformanceGoal
方面的性能以尝试优化PlotPoints
Automatic
样本点的初始数量
从MaxRecursion
和PlotPoints
中,您可以看到它正在进行初始采样,然后以某种方式决定需要细分(重新采样)哪些区域以获得准确的绘图视图。从那里开始,这就是魔法:有一些Method
为此,还有一个PerformanceGoal
指导它......
基本上大多数绘制任何类型图形(尤其是任何合理复杂的图形)的程序都会使用某种类型的第三方库。
使用的特定库将取决于正在使用的编程语言。例如:
对于 .Net 应用程序,您可以使用 Crystal 报表。http://en.wikipedia.org/wiki/Crystal_Reports
对于 Java,您可以使用 JFreeChart。http://www.jfree.org/jfreechart/ 等等……
无论您决定使用哪种语言编写代码,您都可能会找到大量的库。
如果您想在您的特定项目中完成此功能,我建议您使用库,特别是如果您是初学者。由于许多问题,例如跨平台兼容性、图形渲染优化(即:确保图形快速且“漂亮”地渲染)、与元素在图表等等。
最后,我怀疑您是否会找到该主题的特定课程(或需要它们),因为再次排除非常特定的情况,程序员将始终使用已经存在的库。
既然有人已经为您解决了问题,为什么还要自己编写代码呢?
一个好的起点是了解图形有一个语法,并且在接收到绘图命令时要构建的是图形的符号表示。对于 Mathematica,您可以执行类似的操作
FullForm[Plot[Sin[x], {x, 0, 2 Pi}]]
查看 Mathematica 使用的内部表示。基本上,您需要根据颜色和坐标来描述要绘制的线段 (2D) 或网格 (3D)。此外,还需要有关图形比例以及如何绘制刻度线、标签轴等的信息。
这就引出了问题的核心,如何确定要从函数和范围中绘制的线段?如果您在绘图的帮助文件中四处寻找,您会看到一些东西。首先有一个绘图点选项和一个 MaxRecursion 选项。这让我相信(这只是一个有根据的猜测,但我会这样做)Mathematica 在该范围内的偶数间隔上绘制初始点数以获得起始值。下一部分是识别变化超过某个阈值的区域,然后对更多点进行采样,直到线段中任意两个点之间的“变化”低于阈值。Mathematica 以递归方式执行此操作,因此使用 MaxRecursion 选项。
到目前为止,我对定义变化率一直很模糊。描述变化的更有用的方法是在你的线段上取 3 分。假设第 1 点和第 3 点之间存在线性关系,并假设这种线性关系,预测第 2 点将是什么。如果这个预测的误差足够低,那么考虑下一组三点。如果误差高于阈值,则应在该区域中采样更多点,直到达到阈值。通过这种方式,您将需要相对较少的曲线相对笔直的点,而在新方向弯曲的“有趣”部分需要更多点。您绘制的曲线的平滑度将与您愿意在点的线性预测中容忍的误差成正比。