python莫比乌斯_用python绘出一个莫比乌斯环

这篇博客讲述了作者如何使用Python和numpy高效地绘制出一个莫比乌斯环的过程,包括利用numpy进行数值运算,定义函数计算X、Y、Z坐标,并使用matplotlib的Axes3D模块进行3D绘图,通过调整色彩、线条宽度和透明度等参数优化图像效果。
摘要由CSDN通过智能技术生成

昨天写了一篇subplot的练习放到微信公众账号中,想用一个莫比乌斯环的图片作为封面图片,就去维基百科上扒了一个。但是分辨率很低,就想自己绘出一个来。没想到越陷越深,就一起把3D绘图给学习了一遍。

(我昨天在CSDN发表了这篇文章,今天竟然找不到了!)

源代码:https://github.com/gt11799/mobiusband

有关莫比乌斯带,请戳维基百科http://zh.wikipedia.org/wiki/%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%B8%A6

函数已经给出,剩下的就是取值,绘图。要绘3D图,X,Y,Z都得是矩阵。平常的做法就是遍历,给矩阵中的每一个元素赋值,如果取样点为100,那么计算X的赋值次数就是100*100,每次赋值还要计算两次cos()。

0818b9ca8b590ca3270a3433284dd417.png

这就要请出今天的明星-numpy。

numpy是python中的高效数值运算模块。其中包含了各种数学运算,以及array数据类型,这些都是用C写的,如果只是进行少量数值的运算,numpy的性能是低于math的,但是大批量的数值运算,numpy的优势就体现出来了。

首先介绍的是array数据类型,很像list,但是可以不用迭代,直接运算。

>>> from numpy import *

>>> a = array([1,2,3,4])

>>> a * 3

array([ 3,  6,  9, 12]) 这样就可以直接把取样点直接投到函数中得到X的值。

取样也很方便,比如在这个例子中,我们可以这么取v和u:

v = linspace(-1.0, 1.0, num=500, endpoint=True)

u = linspace(0, 2*pi, num=500, endpoint=True) 参数分别是(start,stop,number of sample, 是否包含终止数值)

但是array没有append或者add方法,而且,我试了很久,也没有办法把数据一行一行的添加到一个array中,于是我找了list当作中间人。

把运算复杂度高的u迭代,每次计算出全部的v。

for value_u in u:

answer.append((1. + v / 2. * cos(value_u/2.)) * cos(value_u)) 要提前把v和u取成array类型,要提前定义answer是list。更高效的是直接在list中迭代,我们可以为X,Y,Z分别建立函数,返回数值array。

def func_x(v, u):

answer = [((1. + v / 2. * cos(value_u/2.)) * cos(value_u)) for value_u in u]

return array(answer) 其他坐标轴依此类推。

我们已经准备好了所需要材料,就等着下锅了。3Dplot我用的是mpl_toolkits.mplot中的Axes3D模块,这是matplotlib中的一部分。绘图也很简单,我用的是其中的surface方法。

fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')

surf = ax.plot_surface(X, Y, Z)

0818b9ca8b590ca3270a3433284dd417.png 先新建一个figure(为了设置dpi),然后以添加子图的形式添加进去就行。这样就已经成型了,提高下dpi

fig = plt.figure(dpi=150) 增加点色彩变化

surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm) 需要从matplotlib中倒入cm,cm模块很有趣,有着很多的色彩变化,可以参考官方文档。我尝试了多种,最后选择是YlOrBr,是yellow or brand,效果图最后会贴出来。

0818b9ca8b590ca3270a3433284dd417.png

去掉那些黑色曲线

surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0) 然后还玩了一把透明度alpha,最后发现透明度低一点的好(alpha越小,透明度越高)

surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, alpha=0.9) 现在的图z轴太高,造成立体感不明显,于是我们拉长z轴,让图扁平一点。

ax.set_zlim(-2., 2.)

0818b9ca8b590ca3270a3433284dd417.png

然后去掉坐标轴

plt.axis('off') 如果用show()方法显示图表,然后保存,背景不是透明的,我们可以用figure.save()取保存

fig.savefig('mobiusband.png', transparent=True) 发现图不够清晰,增加dpi

fig.savefig('mobiusband.png', transparent=True, dpi=600) 然后就得到了最终的图了

0818b9ca8b590ca3270a3433284dd417.png

——————————————

github主页:https://github.com/gt11799

E-mail:gting405@163.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值