mplot3d是matplotlib里用于绘制3D图形的一个模块。关于mplot3d 绘图模块的介绍请见:https://blog.csdn.net/dahunihao/article/details/77833877

莫比乌斯环(mobius strip)是一种只有一个曲面的拓扑结构。把一个纸条扭转180°后,两头再粘接起来,这样的纸带只有一个面(即单侧曲面),一只小虫可以爬遍整个曲面而不必跨过它的边缘。

莫比乌斯环是一个二维的紧致流形 (即一个有边界的面),可以嵌入到三维或更高维的流形中 。那么如何在3D空间上画莫比乌斯环呢?可以利用现有的方程式,将莫比乌斯环的两个参数(角度,宽度)映射到三维空间中。以下摘自维基百科(https://en.wikipedia.org/wiki/M%C3%B6bius_strip):

"""

One way to represent the Möbius strip as a subset of three-dimensional Euclidean space is using the parametrization:

where 0 ≤ u < 2π and −1 ≤ v ≤ 1. This creates a Möbius strip of width 1 whose center circle has radius 1, lies in the xyplane and is centered at (0, 0, 0). The parameter u runs around the strip while v moves from one edge to the other.

"""

大概的意思就是:这个方程组可以创造一个宽度为1,中心圆半径为1的莫比乌斯环,其所处位置为x-y平面,中心为(0,0,0)。参数u绕整个环转圈,参数v则从一个边缘移动到另一个边缘。

下面让我们一步一步来画莫比乌斯环。首先导入numpy,matplotlib和其3D模块,创建一个图形和一个三维坐标轴:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = plt.axes(projection='3d')

其次,定义u,v参数(u为绕环一圈的角度,v为环的宽度):

u = np.linspace(0, 2*np.pi, endpoint=True, num=50)
v = np.linspace(-1, 1, endpoint=True, num=10)

然后,按照方程式,将u,v参数映射到三维空间(x轴,y轴和z轴):

u,v=np.meshgrid(u,v)
u=u.flatten()
v=v.flatten()
x = (1 + 0.5 * v * np.cos(u / 2.0)) * np.cos(u)
y = (1 + 0.5 * v * np.cos(u / 2.0)) * np.sin(u)
z = 0.5 * v * np.sin(u / 2.0)

最后,选一个好看的配色方案,画出图像:

ax.plot_trisurf(x,y,z,cmap="cool")

此时图像如下:

可以看出图像已基本成型,但是部分地方还有缺角。这是因为三角剖分还不正确。可以使用matplotlib现成的方法定义三角剖分:

import matplotlib.tri as mtri
tri = mtri.Triangulation(u, v)

最后的最后,把图像变大一点,把x轴,y轴和z轴的上下限修改一下,这样图像看起来更好一些。

完整代码如下:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10,6))
ax = plt.axes(projection='3d') # u, v are parameterisation variables
u = np.linspace(0, 2*np.pi, endpoint=True, num=50)
v = np.linspace(-1, 1, endpoint=True, num=10) # This is the Mobius mapping, taking a u, v pair and returning an x, y, z
# triple
u,v=np.meshgrid(u,v) #用meshgrid函数来产生三维绘图时的矩阵
u=u.flatten() #把u展开,变成一维数组
v=v.flatten() #把v展开,变成一维数组
x = (1 + 0.5 * v * np.cos(u / 2.0)) * np.cos(u)
y = (1 + 0.5 * v * np.cos(u / 2.0)) * np.sin(u)
z = 0.5 * v * np.sin(u / 2.0) # Triangulate parameter space to determine the triangles
import matplotlib.tri as mtri
tri = mtri.Triangulation(u, v) # Plot the surface. The triangles in parameter space determine which x, y, z
# points are connected by an edge.
ax.plot_trisurf(x,y,z,cmap="cool",triangles=tri.triangles)
ax.set_xlim(-1.1, 1.1)
ax.set_ylim(-1.1, 1.1)
ax.set_zlim(-1, 1) plt.show()

图像如下:

参考:https://matplotlib.org/gallery/mplot3d/trisurf3d_2.html?highlight=mobius

Matplotlib学习---用mplot3d画莫比乌斯环(Mobius strip)的更多相关文章

  1. Matplotlib学习---用seaborn画联合分布图(joint plot)

    有时我们不仅需要查看单个变量的分布,同时也需要查看变量之间的联系,这时就需要用到联合分布图. 这里利用Jake Vanderplas所著的<Python数据科学手册>一书中的数据,学习画图 ...

  2. Matplotlib学习---用wordcloud画词云(Word Cloud)

    画词云首先需要安装wordcloud(生成词云)和jieba(中文分词). 先来说说wordcloud的安装吧,真是一波三折.首先用pip install wordcloud出现错误,说需要安装Vis ...

  3. Matplotlib学习---用seaborn画矩阵图(pair plot)

    矩阵图非常有用,人们经常用它来查看多个变量之间的联系. 下面用著名的鸢尾花数据来画一个矩阵图.从sklearn导入鸢尾花数据,然后将其转换成pandas的DataFrame类型,最后用seaborn画 ...

  4. Matplotlib学习---用seaborn画直方图,核密度图(histogram, kdeplot)

    由于直方图受组距(bin size)影响很大,设置不同的组距可能会产生完全不同的可视化结果.因此我们可以用密度平滑估计来更好地反映数据的真实特征.具体可参见这篇文章:https://blog.csdn ...

  5. Matplotlib学习---用matplotlib画直方图/密度图(histogram, density plot)

    直方图用于展示数据的分布情况,x轴是一个连续变量,y轴是该变量的频次. 下面利用Nathan Yau所著的<鲜活的数据:数据可视化指南>一书中的数据,学习画图. 数据地址:http://d ...

  6. Matplotlib学习---用matplotlib画箱线图(boxplot)

    箱线图通过数据的四分位数来展示数据的分布情况.例如:数据的中心位置,数据间的离散程度,是否有异常值等. 把数据从小到大进行排列并等分成四份,第一分位数(Q1),第二分位数(Q2)和第三分位数(Q3)分 ...

  7. Matplotlib学习---matplotlib的一些基本用法

    Matplotlib有两种接口,一种是matlab风格接口,一种是面向对象接口.在这里,统一使用面向对象接口.因为面向对象接口可以适应更复杂的场景,在多图之间进行切换将变得非常容易. 首先导入matp ...

  8. 数学图形之莫比乌斯带(mobius)

    莫比乌斯带,又被译作:莫比斯环,梅比斯環或麦比乌斯带.是一种拓扑学结构,它只有一个面(表面),和一个边界.即它的正反两面在同一个曲面上,左右两个边在同一条曲线上.看它的名字很洋气,听它的特征很玄乎,实 ...

  9. 神奇的莫比乌斯带(mobius)

    1.禅师和青年之间的对话 2.制作一个莫比乌斯带 3.神奇的莫比乌斯带 4.对莫比乌斯带进行简单的数学建模 1.禅师和青年之间的对话 青年问禅师:“大师,我很爱我的女朋友,她也有很多优点,但是总有几个 ...

随机推荐

  1. navicat 和 pymysql

    ---------------------------------------------------相信时间的力量,单每月经过努力的时间,一切的安排都是懊脑的安排. # # ------------ ...

  2. Spring基于AspectJ的AOP的开发——注解

    源码:https://gitee.com/kszsa/dchart 一, AspectJ的概述: AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法所以它有一个专 ...

  3. 用Flask+Redis维护代理池

    GitHub:https://github.com/LXL-YAN/ProxyPool 视频讲解:https://www.bilibili.com/video/av19057145/?p=17

  4. java中的代码块是什么意思,怎么用

    代码块是一种常见的代码形式.他用大括号“{}”将多行代码封装在一起,形成一个独立的代码区,这就构成了代码块.代码块的格式如下:   方法/步骤     普通代码块:是最常见的代码块,在方法里用一对“{ ...

  5. Python_匿名函数

    匿名函数:为了解决那些功能很简单的需求而设计的一句话函数. 代码如下: 1 正常函数: 2 3 def calc(n): 4 5 return n ** n 6 7 print(calc(10)) 8 ...

  6. mac下的快捷键

    功能 快捷键 通用 打开新窗口 command + n 打开新标签 command + t 关闭标签 command + w 缩小 command - 放大 command + 全屏.取消全屏 com ...

  7. tomcat7 server.xml max thread

    java - Tomcat - maxThreads vs maxConnections - Stack Overflowhttps://stackoverflow.com/questions/246 ...

  8. vue实现双向数据绑定之Object.defineProperty()篇

    前言 vue.js中使用ES5的Object.defineProperty()实现数据的双向绑定 Object.defineProperty()原理 Object.defineProperty()可以 ...

  9. [转帖]Huge Page 是否是拯救性能的万能良药?

    Huge Page 是否是拯救性能的万能良药? 本文将分析是否Huge Page在任何条件下(特别是NUMA架构下)都能带来性能提升. 文章欢迎转载,但转载时请保留本段文字,并置于文章的顶部 作者:卢 ...

  10. MyBatis映射文件4(参数获取#{}和${}/select标签详解[返回类型为list])

    参数获取 之前我们都是采用#{}的方式进行参数传递,其实MyBatis还有另外的参数传递方式${} 使用方法相同,但是还是有很大区别的 这里做一个测试: <select id="get ...