Sage入门指南之二绘图

525 days ago by z295474566

 

数学软件Sage入门指南之二:

绘  图





Sage可进行二维和三维绘图

二维绘图

在二维绘图中,Sage可以画圆,线和多边形;在直角坐标和极坐标中画函数曲线,等高线和矢量场。这里提供一些实例。更多关于Sage的绘图输出实例请见求解微分方程Maxima及”Sage构建“文档。

下面的命令产生一个以原点为中心,半径为1的黄色圆:

sage: circle((0,0), 1, rgbcolor=(1,1,0)) 
       

也可以绘制填充圆:

sage: circle((0,0), 1, rgbcolor=(1,1,0), fill=True) 
       

还可以将产生的圆赋值给一个变量;此时图形不会绘制出来:

sage: c = circle((0,0), 1, rgbcolor=(1,1,0)) 
       

想要绘制,要用c.show()或show(c)命令,如下:

sage: c.show() 
       

相应地,执行c.save('文件名.png')会将绘制的图形保存到指定的文件。

现在因为各坐标缩放不同的缘故这些圆看起来更像椭圆,可以用下面代码修正:

sage: c.show(aspect_ratio=1) 
       

show(c, aspect_ratio=1)命令可实现同样目的,或者直接使用c.save('文件名.png', aspect_ratio=1)来保存文件。

绘制基本函数很容易:

sage: plot(cos, (-5,5)) 
       

指定变量后,可进行带参量绘图:

sage: x = var('x') sage: parametric_plot((cos(x),sin(x)^3),(x,0,2*pi),rgbcolor=hue(0.6)) 
       

可以用相加的方式将几个绘图结合:

sage: x = var('x') sage: p1 = parametric_plot((cos(x),sin(x)),(x,0,2*pi),rgbcolor=hue(0.2)) sage: p2 = parametric_plot((cos(x),sin(x)^2),(x,0,2*pi),rgbcolor=hue(0.4)) sage: p3 = parametric_plot((cos(x),sin(x)^3),(x,0,2*pi),rgbcolor=hue(0.6)) sage: show(p1+p2+p3, axes=false) 
       

先建立一系列点(下例中的L)并使用polygon命令以之为边界绘制填充图形是一个很好的方法。下例中绘制了一个绿色的三角形:

sage: L = [[-1+cos(pi*i/100)*(1+cos(pi*i/100)),\ ... 2*sin(pi*i/100)*(1-cos(pi*i/100))] for i in range(200)] sage: polygon(L, rgbcolor=(1/8,3/4,1/2)) 
       

输入show(p, axes=false)可查看没有坐标轴的结果。

可以在图形中加入文本:

sage: L = [[6*cos(pi*i/100)+5*cos((6/2)*pi*i/100),\ ... 6*sin(pi*i/100)-5*sin((6/2)*pi*i/100)] for i in range(200)] sage: p = polygon(L, rgbcolor=(1/8,1/4,1/2)) sage: t = text("hypotrochoid", (5,4), rgbcolor=(1,0,0)) sage: show(p+t) 
       

教微积分的老师经常在黑板上画这样的图形:绘制反正弦的不止一个周期:即,绘制x在-2pi到2pi之间的y=sin(x),翻转约45度的线。下面的Sage可以做到:

sage: v = [(sin(x),x) for x in srange(-2*float(pi),2*float(pi),0.1)] sage: line(v) 
       

(译注:此处用到了srange()函数,这是对应Python中的range()函数的,因为range()函数只支持整数列,而数学运算显然需要大量 用到创建浮点数列的情况,因此Sage中多了这与numpy中arange()功能类似的函数。相应的,对应于Python中在大量数据时使用的 xrange()迭代器的是xsrange()函数。)

由于正切函数的值域比正弦大,如果使用相同的手段绘制反正切函数则需要修正x轴的显示范围:

sage: v = [(tan(x),x) for x in srange(-2*float(pi),2*float(pi),0.01)] sage: show(line(v), xmin=-20, xmax=20) 
       

Sage同样可以绘制极坐标,等高线和矢量场图(针对特定类型的函数)。这里是一个绘制等高线的例子:

sage: f = lambda x,y: cos(x*y) sage: contour_plot(f, (-4, 4), (-4, 4)) 
       

绘制平面向量场:

var('x,y') plot_vector_field( (-sin(y),cos(x)), (x,-3,3), (y,-3,3), aspect_ratio=1) 
       
x, y =var('x y') field1plot = plot_vector_field(vector([-y, x])/(-sqrt(x^2 + y^2)^(3/2)), (x,-2, 2), (y,-2, 2)) field2plot = plot_vector_field(vector([x, y])/(-sqrt(x^2 + y^2)^(3/2)), (x,-2, 2), (y,-2, 2)) show(field1plot + field2plot, aspect_ratio=1) 
       
var('x y') f(x,y) = x^2 - y^2 # a scalar function of two variables, x and y print f.gradient() plot_vector_field(f.gradient(), (x,-3,3), (y,-3,3)).show() 
       
((x, y) |--> 2*x, (x, y) |--> -2*y)
((x, y) |--> 2*x, (x, y) |--> -2*y)

也可绘制三维向量场:

x,y,z=var('x,y,z') plot_vector_field3d((y,-x,z), (x, -3,3), (y,-3,3), (z,-3,3)) 
       

三维绘图

Sage采用一个叫做[Jmol]的开源包绘制三维图形。下面是一些实例:

黄色怀特尼伞

u, v = var('u,v') fx = u*v fy = u fz = v^2 a=parametric_plot3d([fx, fy, fz], (u, -1, 1), (v, -1, 1),frame=False, color="yellow") a.show(mesh=True) 
       

使用parametric_plot3d计算看到图形后就可以点击拖拉来旋转图形。

克莱因瓶:

u,v=var('u,v') bot=((2.5+1.5*cos(v))*cos(u), (2.5+1.5*cos(v))*sin(u), -2.5*sin(v)) mid=((2.5+1.5*cos(v))*cos(u), (2.5+1.5*cos(v))*sin(u), 3*v) han=(2-2*cos(v)+sin(u), cos(u), 3*v) top=(2+(2+cos(u))*cos(v), sin(u), 3*pi + (2+cos(u))*sin(v)) bottom=parametric_plot3d(bot,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=1) middle=parametric_plot3d(mid,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=1) topper=parametric_plot3d(top,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=1) handle=parametric_plot3d(han,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=1) all=show(handle+topper+middle+bottom,plot_points=30) 
       
u,v=var('u,v') bot=((2.5+1.5*cos(v))*cos(u), (2.5+1.5*cos(v))*sin(u), -2.5*sin(v)) mid=((2.5+1.5*cos(v))*cos(u), (2.5+1.5*cos(v))*sin(u), 3*v) #han=(2-2*cos(v)+sin(u), cos(u), 3*v) #top=(2+(2+cos(u))*cos(v), sin(u), 3*pi + (2+cos(u))*sin(v)) bottom=parametric_plot3d(bot,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=.5,color='red') middle=parametric_plot3d(mid,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=.5,color='blue') #topper=parametric_plot3d(top,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=.5,color='black') #handle=parametric_plot3d(han,(u,0,2*pi),(v,0,pi),plot_points=60,opacity=.5,color='yellow') #all=show(handle+topper+middle+bottom) show(bottom+middle) 
       

扭环:

sage: u, v = var('u,v') sage: fx = (3+sin(v)+cos(u))*cos(2*v) sage: fy = (3+sin(v)+cos(u))*sin(2*v) sage: fz = sin(u)+2*cos(v) sage: parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi), ... frame=False, color="red") 
       

Viewer参数

参数viewer可为"canvas3d"、"jmol"、"tachyon"等。

注意:Jmol是一个三维化学结构的开源Java查看器 http://www.jmol.org/

var('x,y') a=plot3d(x*sin(y), (x,-4,4),(y,-4,4)) a.show(viewer="canvas3d") 
       

 

 

path=[[(0,0,0),(1,0,0),(0,1,0),(0,1,1)]] curve=bezier3d(path, thickness=15, color='blue') curve 
       
t=var('t') parametric_plot3d([cos(t),sin(t),t],(t,0,4*pi),thickness=10) 
       
#A transparent thick green line and a little blue line: line3d([(0,0,0), (1,1,1), (1,0,2)], opacity=0.5, radius=0.1, color='green') \ + line3d([(0,1,0), (1,0,2)],thickness=10, color='blue') 
       
#A Dodecahedral complex of 5 tetrahedrons (a more elaborate examples from Peter Jipsen): def tetra(col): return line3d([(0,0,1), (2*sqrt(2.)/3,0,-1./3), \ (-sqrt(2.)/3, sqrt(6.)/3,-1./3), (-sqrt(2.)/3,-sqrt(6.)/3,-1./3), \ (0,0,1), (-sqrt(2.)/3, sqrt(6.)/3,-1./3), (-sqrt(2.)/3,-sqrt(6.)/3,-1./3),\ (2*sqrt(2.)/3,0,-1./3)], color=col, thickness=10, aspect_ratio=[1,1,1]) v = (sqrt(5.)/2-5/6, 5/6*sqrt(3.)-sqrt(15.)/2, sqrt(5.)/3) t = acos(sqrt(5.)/3)/2 t1 = tetra('blue').rotateZ(t) t2 = tetra('red').rotateZ(t).rotate(v,2*pi/5) t3 = tetra('green').rotateZ(t).rotate(v,4*pi/5) t4 = tetra('yellow').rotateZ(t).rotate(v,6*pi/5) t5 = tetra('orange').rotateZ(t).rotate(v,8*pi/5) show(t1+t2+t3+t4+t5, frame=False) 
       
sum([point3d((i,i^2,i^3),size=15,color=(cos(i),i/(1+i),sin(i))) for i in range(10)]) 
       
#We draw a multicolor spiral of numbers: sum([text3d('%.1f'%n, (cos(n),sin(n),n), color=(n/2,1-n/2,0)) for n in [0,0.2,..,8]]) 
       
sage: var('x,y,z') sage: implicit_plot3d(x^2+y^2+z^2==4, (x, -3, 3), (y, -3,3), (z, -3,3)) 
       
#A nested set of spheres with a hole cut out: var('x y z') implicit_plot3d((x^2 + y^2 + z^2), (x, -3, 3), (y, -3, 3), (z, -3, 3), \ plot_points=50, contour=[1,3,5,7], \ region=lambda x,y,z: x<=0.2 or y>=0.2 or z<=0.2).show() 
       
#As I write this (but probably not as you read it), it’s almost Valentine’s day, so let’s try a heart (from http://mathworld.wolfram.com/HeartSurface.html) var('x y z') p = (x^2+9/4*y^2+z^2-1)^3-x^2*z^3-9/(80)*y^2*z^3 r = 1.5 implicit_plot3d(p, (x,-r,r), (y,-r,r), (z,-r,r), \ plot_points=80, color='red',\ smooth=False).show(viewer='tachyon') 
       
#The same examples also work with the default Jmol viewer; for example: T=RDF(golden_ratio) #1.61803398875 p=2-(cos(x+T*y)+cos(x-T*y)+cos(y+T*z)+cos(y-T*z)+cos(z-T*x)+cos(z+T*x)) r=4.77 implicit_plot3d(p,(x,-r,r),(y,-r,r),(z,-r,r),plot_points=40).show() 
       
RDF(golden_ratio) 
       
1.61803398875
1.61803398875
sage: u, v = var('u,v') sage: f1 = (4+(3+cos(v))*sin(u), 4+(3+cos(v))*cos(u), 4+sin(v)) sage: f2 = (8+(3+cos(v))*cos(u), 3+sin(v), 4+(3+cos(v))*sin(u)) sage: p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), texture="red") sage: p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), texture="blue") sage: p1 + p2 
       

Green bowtie:

sage: u, v = var('u,v') sage: f_x = sin(u) / (sqrt(2) + sin(v)) sage: f_y = sin(u) / (sqrt(2) + cos(v)) sage: f_z = cos(u) / (1 + sqrt(2)) sage: parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, -pi, pi), frame=False, color="green") 
       
sage: u, v = var('u,v') sage: fx = 2/3* (cos(u)* cos(2*v) + sqrt(2)* sin(u)* cos(v))* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v)) sage: fy = 2/3* (cos(u)* sin(2*v) - sqrt(2)* sin(u)* sin(v))* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v)) sage: fz = sqrt(2)* cos(u)* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v)) sage: parametric_plot3d([fx, fy, fz], (u, -2*pi, 2*pi), (v, 0, pi), plot_points = [90,90], frame=False, color="orange") # long time -- about 30 seconds 
       

Maeder’s_Owl (pretty but can’t find an internet reference):

sage: u, v = var('u,v') sage: fx = v *cos(u) - 0.5* v^2 * cos(2* u) sage: fy = -v *sin(u) - 0.5* v^2 * sin(2* u) sage: fz = 4 *v^1.5 * cos(3 *u / 2) / 3 sage: parametric_plot3d([fx, fy, fz], (u, -2*pi, 2*pi), (v, 0, 1),plot_points = [90,90], frame=False, color="purple") 
       

Bracelet:

sage: u, v = var('u,v') sage: fx = (2 + 0.2*sin(2*pi*u))*sin(pi*v) sage: fy = 0.2*cos(2*pi*u) *3*cos(2*pi*v) sage: fz = (2 + 0.2*sin(2*pi*u))*cos(pi*v) sage: parametric_plot3d([fx, fy, fz], (u, 0, pi/2), (v, 0, 3*pi/4), frame=False)