六、图形
六、图形 返回目录页
1、图形基本元素
2、图形指令与图形选项
3、函数图与参数图
4、文本图形
5、数据图形
6、声音
7、互动栗子:随机漫步
+++++++++++++++++++++++++++++++++++++++++++
一切都是分层。
表作为基本的数据是分层的。
表达式,即程序,是分层的。
所以数据与程序,没有本质区别。从而把数据与程序统一到了一起。
MMA内部分层的具体结构,应该是树形结构。
从更抽象的角度说,从最抽象层到最具体层,都有分层结构。
然后从算法上说,规则编程作用在了分层结构上。
规则编程的变换方法,基于模式。模式又是分层的。模式先寻找最具体的匹配,再一层层向更抽象层搜索。
规则变换是变化,模式匹配是变化的原则和方法。
神奇的是,MMA的规则变换作用在分层结构上时,是动态的,即改变了分层结构。
从而把算法与数据结构统一到了一起。
结果是,MMA可以动态生成代码。
表面上,MMA是解释型语言,实际上,在解释(计算运行)时:
A代码动态生成B代码、B代码动态生成C代码...
代码的生成过程,又是分层的。
MMA可以分层动态生成代码的独特特性,使MMA功能强大而代码可以极短。
+++++++++++++++++++++++++++++++++++++++++++
-------------------------------------------------------------------------
1、图形基本元素
所有MMA绘制的图形,都是图形基本元素(graphics primitive)构造出来的。
MMA通过把各种图形元素(graphics element)拼合起来的方式绘制图形。
简短的代码背后,是长长的代码。
所以,我们可以把图形函数,理解为MMA分层动态生成代码这一独特功能的应用。
要是有能够智能性地生成代码的程序,该有多好啊?
不经意之间,MMA已经实现了(至少部分实现了)。
A:Hi,请给我画一个函数图?
B:What? 函数成千上万,要画哪一个?
A:画个正弦函数好了。
B:正弦函数的区域是无穷长,画不下的。
A:好吧,只画0到6Pi的好了。
B:OK,已经画好了。用:Plot[Sin[x], {x, 0, 6 Pi}]
这条语句,可以生成的代码,是可以看到的。只是太长,所以现在只看一部分(用Short函数):
sinplot=Plot[Sin[x], {x, 0, 6 Pi}];
Short[InputForm[sinplot], 14]
得:略。
如果你把14,改成140,可以看到更长的代码。
我们可以看到,正弦曲线,是通过很多个点,短线连接而成,肉眼看到的,是曲线。
----------------------------------------
图形基本元素,在帮助文档中,翻译成了图形基元。
图形基本元素有很多,图中的表中,只列举了一部分,一些点、线、矩形、多边形、圆、文字之类的。
----------------------------------------
Graphics
图形基本元素可以理解为一些图形的数据。它本身没有显示图形的功能。要显示,得调用其他函数。
Graphics[primitives,options]
表示一个二维图形
primitives 是图形元素。options 是图形选项,后面再讲。
line1 = Line[{{1, 0}, {2, 1}, {3, 0}, {4, 1}}]
Graphics[line1]
----------------------------------------
Show
Show函数,有两个功能:
Show[graphics,options] 按指定选项显示图形
Show[g1,g2,...] 同时显示几个图形
line1 = Line[{{1, 0}, {2, 1}, {3, 0}, {4, 1}}];
line2 = Line[{{1, 0}, {4, 1}}];
Show[Graphics[line1], Graphics[line2]]
这样,就把两个图形画到了一起。
----------------------------------------
Graphics绘制的是二维图形。Graphics3D可以绘制三维的。
Graphics3D[
Table[With[{p = {i, j, k}/5}, {RGBColor[p], Opacity[.75],
Cuboid[p, p + .15]}], {i, 5}, {j, 5}, {k, 5}]]
-------------------------------------------------------------------------
2、图形指令与图形选项
图形指令(graphics directive)写在图形元素语句之前,仅对它“管辖范围”内的对象产生作用。
{dir, prim1, prim2...}
prim可以是一个,也可以是多个。
line1 = Line[{{1, 0}, {2, 1}, {3, 0}, {4, 1}}];
line2 = Line[{{1, 0}, {4, 1}}];
Show[Graphics[{RGBColor[1, 0, 1], line1}],
Graphics[{RGBColor[0.3, 0.7, 0.1], line2}]]
这是分开“管辖”。
以下这样写,是统一“管辖”:
Show[Graphics[{RGBColor[1, 0, 1], line1, line2}]]
既然写一起,Show在这里是可有可无的。
经常要指定颜色,以下方式指定比较常用:
RGBColor[r,g,b] 用0和1之间的数,指定红、绿、蓝分量的颜色
图形指令有很多,可以指定点的大小、线的样式、透明度、线的宽度,颜色,等等,请查看函数Graphics的帮助文档,就可以看到各种指令的详细内容。
一般对于图形元素的具体属性,比如点或者线的颜色、大小等等,可以用图形指令来指定。而对于图形的总体属性,比如坐标啊、图形的填充啊、边框啊,这些则由选项(option)来指定,通过规则转换的符号:->
Table[Graphics[Circle[], AspectRatio -> 1/k], {k, 1, 5}]
AspectRatio用来指定图形高宽比。
Table[Graphics[Circle[], AspectRatio -> 1/k, Axes -> True], {k, 1, 5}]
Axes是加上坐标。
图形的选项也有很多,详细还是请查看函数Graphics的帮助文档。或者查看这个地址的帮助文档:
tutorial/Options
关于缺省选项,可以用Options函数来查阅:
Options[Graphics]
总结一下:指令在前,指定具体属性。选项在后,指定总体属性。
-------------------------------------------------------------------------
3、函数图与参数图
一个函数,当自变量只有一个的时候,可以画出平面曲线图,用Plot函数。
当自变量有两个的时候,可以画出立体图,用Plot3D函数。
参数图有点意思。当有一个自变量t的时候,两个函数(fx,fy)的返回值得出平面直角坐标系上点的坐标(x,y),从而得到平面曲线图。用ParametricPlot函数。
同理,参数图中函数有三个的时候,可以得到立体坐标上的点坐标(x,y,z),而到得立体图形。用ParametricPlot3D函数。
----------------------------------------
Plot
Plot[Sin[x], {x, 0, 6 Pi}]
在曲线下填充:
Plot[2 Sin[x] + x, {x, 0, 15}, Filling -> Bottom]
这功能有点被吓着了。点点曲线可以打开链接!
Plot[{Hyperlink[Sin[x], "http://mathworld.wolfram.com/Sine.html"],
Hyperlink[Cos[x], "http://www.cnblogs.com/xin-le/p/5990014.html"]}, {x, 0, 10}]
Plot具有Graphics的所有选项之外,还有其他选项,详细请看帮助文档。
----------------------------------------
Plot3D
Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}]
立体图形是可以有各种鼠标操作的。
按下鼠标左键,然后拖动(这个作为基本动作D),然后可以试一下:
鼠标在图形中间+D
鼠标在图形边框附近+D
Alt+D
Shift+D
Ctrl+D
都试一下就知道了。
Plot3D 具有同 Graphics3D 相同的属性外,并附加了一些值和变化,详细请看帮助文档。
----------------------------------------
ParametricPlot
ParametricPlot[{Sin[t], Sin[2 t]}, {t, 0, 2 Pi}]
----------------------------------------
ParametricPlot3D
ParametricPlot3D[{Cos[t] Cos[u], Sin[t] Cos[u], Sin[u]}, {t, 0, 2 Pi}, {u, -Pi/2, Pi/2}]
-------------------------------------------------------------------------
4、文本图形
用 Text 图形基元可以将文本插入二位或三维图形的任意位置。
在不使用 Style 明确指定字体风格时,该文本将使用图形的基础风格。
Show[Graphics[Table[Text[Expand[(a + b)^n], {n, n}], {n, 10}]],
PlotRange -> All]
有时候将文本转换成图形,很有意思。
-------------------------------------------------------------------------
5、数据图形
将数据以图形的方式呈现出来,方便分析数据。
非常多。这里摘录一些常用的、统计方面和金融方面的。
----------------------------------------
ListPlot
lis = RandomSample[Range[30], 30];
ListPlot[lis, Filling -> Axis]
ListLinePlot
lis = RandomSample[Range[30], 30];
ListLinePlot[lis, Filling -> Axis]
ListPolarPlot[{r1, r2, ...]}]
绘制点,它们以 ri 为半径等角度放置
ListPolarPlot[Table[Sqrt[n], {n, 100}]]
这个对理解极坐标很有好处。
----------------------------------------
BarChart
lis = RandomSample[Range[30], 10];
BarChart[lis]
PieChart
lis = RandomSample[Range[30], 10];
PieChart[lis]
BubbleChart
BubbleChart[RandomReal[1, {5, 7, 3}]]
BarChart3D
lis = RandomSample[Range[30], 10];
BarChart3D[lis]
PieChart3D
lis = RandomSample[Range[30], 10];
PieChart3D[lis]
PieChart3D[{{1, 2, 3, 4}, {1, 1, 1}, {1, 2, 1}}]
BubbleChart3D
BubbleChart3D[RandomReal[1, {5, 10, 4}]]
----------------------------------------
Histogram
lis = RandomSample[Range[300], 100];
Histogram[lis, 10]
Histogram3D
Histogram3D[RandomVariate[NormalDistribution[0, 1], {500, 2}]]
----------------------------------------
CandlestickChart
CandlestickChart["SP500"]
SP500指数的蜡烛图。
RenkoChart
RenkoChart["^GSPC"]
砖形图。显示出来要化点时间,数据要从服务器上自动下载。
-------------------------------------------------------------------------
6、声音
在MMA中,可以将数据用作声音来播放!
Play[Sin[2000 (1 + Round[2 t, 0.1]) t], {t, 0, 1}]
可以用MMA来作曲。
这方面的重要性不能低估,只是这里不展开了。
-------------------------------------------------------------------------
7、互动栗子:随机漫步
假如一个醉汉,在随机漫步的时候,只走四个方向:上下左右。
在走了n步之后,我们可以把他的足迹记录下来吗?
足迹的起始点,记为{0,0}。
上下左右随机走一步,相当于{0,0},加上
{0, 1}, {1, 0}, {0, -1}, {-1, 0} 中的任意一个(假如是第1个)。
然后把得到的数据,添加到表中:{{0,0},{0,1}}
不断随机漫步,结果表的数据就越来越多。
FoldList[Plus, {0, 0},
{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
[[ Table[RandomInteger[{1, 4}], {8}] ]]
]
得:{{0, 0}, {0, -1}, {1, -1}, {2, -1}, {2, 0}, {3, 0}, {3, -1}, {4, -1}, {5, -1}}
数据有了之后,就可以用Line来连线,然后用Graphics画出来,就可以了。
整合成自定义函数:
walk2D[n_]:=Module[{lis},
lis = FoldList[Plus, {0, 0},
{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
[[ Table[RandomInteger[{1, 4}], {n}] ]] ];
Graphics[Line[lis]] ];
Table[walk2D[200], {4}]
这样,一次就能看到多副图像。
同理,想像一个醉汉进行立体漫步,醉汉到太空中了,只进行上下左右前后六个方向漫步。
walk3D[n_]:=Module[{lis},
lis = FoldList[Plus, {0, 0, 0},
{{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}}
[[ Table[RandomInteger[{1, 6}], {n}] ]] ];
Graphics3D[Line[lis]] ];
Table[walk3D[200], {4}]
醉汉漫步的平面图与立体图都出来了。
但有个问题,回头路比较多,醉汉到底是怎么一步步走的呢?这个问题很容易解决:
用Manipulate函数,有动画功能,又可以用滑杆互动操作。
Manipulate[Plot[Sin[x + a], {x, 0, 6 Pi}], {a, 0, 6 Pi}]
对于函数Sin[x+a],把参数x作为自变量,把另一个参数a取出来,指定变动范围,就得到一个滑杆。
这个滑杆可以手动拖动,也可以自动拖动——就形成了动画。
当一个表达式有n个变量时,至多可以取出n个变量来分别制作滑杆。
Manipulate[a + b, {a, 0, 6}, {b, 0, 6}]
然后,我们把Manipulate的功能,整合到二维随机漫步程序中:
ManiWalk2D[n_]:=Module[{lis},
lis = FoldList[Plus, {0, 0},
{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
[[ Table[RandomInteger[{1, 4}], {n}] ]] ];
Manipulate[ Graphics[
{Blue, Line[lis], {PointSize[.02], Red, Point[lis[[i]]]}}],
{i, 1, n, 1}]]
ManiWalk2D[100]
为了使图像彩色些,用图形指令指定了蓝线红点。
这样我们就观察到了醉汉漫步的整个过程。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MMA中,绘图函数非常丰富,作出的图可以非常炫目。动画控制更是简便易用。
这里只介绍了一小部分。
+++++++++++++++++++++++++++++++
扩展阅读:民科狂人巨著——《A New Kind of Science》。
T o p