搜索

查看: 3110|回复: 11

[Python] Python利用plotly绘制正二十面体详解

[复制链接]
发表于 2023-5-4 17:19:23 | 显示全部楼层 |阅读模式
Editor 2023-5-4 17:19:23 3110 11 看全部
目录
  • 顶点
  • 实现正二十面体plotly 的 Python 软件包是一个开源的代码库,它基于 plot.js,而后者基于 d3.js。我们实际使用的则是一个对 plotly 进行封装的库,名叫 cufflinks,能让你更方便地使用 plotly 和 Pandas 数据表协同工作。
    一言以蔽之,plotly是一款擅长交互的Python绘图库,下面就初步使用一下这个库的三维绘图功能。此前曾经用matplotlib画了正二十面体和足球:Python绘制正二十面体画足球,这次用plotly复现一下正二十面体的绘制过程,也体验一下这两个绘图包的差异。
    来绘制一个正二十面体。

    顶点
    正20面体的12个顶点刚好可以分为三组,每一组都是一个符合黄金分割比例的长方形,而且这三个长方形是互相正交的。
    所以,想绘制一个正二十面体是比较容易的
    import plotly
    import plotly.express as px
    import numpy as np
    from itertools import product
    G = (np.sqrt(5)-1)/2
    def getVertex():
        pt2 =  [(a,b) for a,b in product([1,-1], [G, -G])]
        pts =  [(a,b,0) for a,b in pt2]
        pts += [(0,a,b) for a,b in pt2]
        pts += [(b,0,a) for a,b in pt2]
        return np.array(pts)
    xs, ys, zs = getVertex().T
    fig = px.scatter_3d(x=xs, y=ys, z=zs,
        size=np.ones_like(xs)*0.5)
    fig.show()
    得到顶点

    2023022416542059.png

    2023022416542059.png



    接下来连接这12个顶点,由于点数较少,所以直接遍历也不至于运算量爆炸。另一方面,正二十面体边长相同,而这些相同的边连接的也必然是最近的点,所以接下来只需建立顶点之间的距离矩阵,并抽取出距离最短的线。
    def getDisMat(pts):
        N = len(pts)
        dMat = np.ones([N,N])*np.inf
        for i in range(N):
            for j in range(i):
                dMat[i,j] = np.linalg.norm([pts-pts[j]])
        return dMat
    pts = getVertex()
    dMat = getDisMat(pts)
    # 由于存在舍入误差,所以得到的边的数值可能不唯一
    ix, jx = np.where((dMat-np.min(dMat))
    接下来,绘制正二十面体的棱
    edges = []
    for k in range(len(ix)):
        edges.append(pts[ix[k]].tolist() + [k])
        edges.append(pts[jx[k]].tolist() + [k])
    edges = np.array(edges)
    fig = px.line_3d(edges, x=0, y=1, z=2, color=3)
    fig.show()
    效果如图所示

    2023022416542060.png

    2023022416542060.png


    实现正二十面体
    接下来要对面上色。由于三棱成个面,所以只需得到所有三条棱的组合,只要这三条棱可以组成三角形,就能获取所有的三角面。当然,这一切的前提是,正二十面体只有30个棱,即使遍历多次,也无非27k的计算量,是完全没问题的。
    def isFace(e1, e2, e3):
        pts = np.vstack([e1, e2, e3])
        pts = np.unique(pts, axis=0)
        return len(pts)==3
    edges = [pts[[i,j]] for i,j in zip(ix, jx)]
    from itertools import combinations
    faces = [es for es in combinations(edges, 3)
        if isFace(*es)]
    最后得到的faces有20个元素,每个元素由3条棱组成,每条棱有两个顶点,故而可以缩减为三个顶点。
    ptFace = [np.unique(np.vstack(f),axis=0) for f in faces]
    ptFace = np.vstack(ptFace)   
    接下来绘制一下,plotly绘制三角面的逻辑是,除了需要指定三角面的三个坐标之外,还需指定三角面的顶点序号
    import plotly.figure_factory as ff
    simplices = np.arange(len(ptFace)).reshape(-1,3)
    fig = ff.create_trisurf(x=ptFace[:,0],
        y=ptFace[:,1], z=ptFace[:,2],
        simplices=simplices)
    fig.show()
    效果如下

    2023022416542061.png

    2023022416542061.png


    以上就是Python利用plotly绘制正二十面体详解的详细内容,更多关于Python plotly绘制正二十面体的资料请关注知鸟论坛其它相关文章!
  • 回复

    使用道具 举报

    发表于 2023-6-28 19:54:19 | 显示全部楼层
    123456865 2023-6-28 19:54:19 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-6-28 20:30:59 | 显示全部楼层
    我是的十八簿 2023-6-28 20:30:59 看全部
    楼主太厉害了!楼主,I*老*虎*U!我觉得知鸟论坛真是个好地方!
    回复

    使用道具 举报

    发表于 2023-6-28 22:06:19 | 显示全部楼层
    123456809 2023-6-28 22:06:19 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-6-29 16:53:04 | 显示全部楼层
    xinting_6ym 2023-6-29 16:53:04 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-30 03:30:28 | 显示全部楼层
    无人岛屿颈 2023-6-30 03:30:28 看全部
    既然你诚信诚意的推荐了,那我就勉为其难的看看吧!知鸟论坛不走平凡路。
    回复

    使用道具 举报

    发表于 2023-6-30 08:51:29 | 显示全部楼层
    计划你大爷计j 2023-6-30 08:51:29 看全部
    感谢楼主的无私分享!要想知鸟论坛好 就靠你我他
    回复

    使用道具 举报

    发表于 2023-6-30 19:32:58 | 显示全部楼层
    丁侦球 2023-6-30 19:32:58 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-30 21:41:04 | 显示全部楼层
    我的苦恼冉 2023-6-30 21:41:04 看全部
    论坛不能没有像楼主这样的人才啊!我会一直支持知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-3 06:47:04 | 显示全部楼层
    十二音阶囤 2023-7-3 06:47:04 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表