制作三维旋转动图(以三维PCA图为例)| Python

问题:如何用python绘制能够旋转的三维动图

解决

Code

import matplotlib.pyplot as plt
from matplotlib import animation 
import numpy as np

def componential_plot_animated_3d(reduced_data, labels, pc, variable):
    """draw a animated componential plot in 3d for three principle components
    
    :param reduced_data: data processed by PCA
    :param labels: labels of original dataset 
    :param pc: all the principle components
    :param variable: the name of the variables of the data set
    """
    
    fig = plt.figure(1, figsize=(14, 12))
    ax = plt.axes(projection='3d')
    
    legend = []  # 
    classes = np.unique(labels)  # label type
    n = pc.shape[1]
    # colors = ['g', 'r', 'y']
    # markers = ['o', '^', 'x']
    
    x = reduced_data[:, 0]  # variable contributions for PC1
    y = reduced_data[:, 1]  # variable contributions for PC2 
    z = reduced_data[:, 2]  # variable contributions for PC3
    scalex = 1.0/(x.max() - x.min())
    scaley = 1.0/(y.max() - y.min())
    scalez = 1.0/(z.max() - z.min())
    
    def init():
        #  A function used to draw a clear and initial frame
        
        # draw a data point projection plot that is projected to 
        # a three-dimensional space using normal PCA
        for i, label in enumerate(classes):
            ax.scatter3D(x[labels==label] * scalex,
                         y[labels==label] * scaley,
                         z[labels==label] * scalez,
                         linewidth=0.01) 
            # hyperparameter in plt.scatter(): c=colors[i], marker=markers[i]
            legend.append("Label: {}".format(label))

        ax.legend(legend)

        # plot arrows as the variable contribution,
        # each variable has a score for PC1, for PC2 and for PC3 respectively
        for i in range(n):
            ax.quiver(0, 0, 0, pc[0, i], pc[1, i], pc[2, i], color='k', alpha=0.7,
                      linewidth=1, arrow_length_ratio=0.05)
            ax.text(pc[0, i]*1.1, pc[1, i]*1.1, pc[2, i]*1.1, variable[i],
                    ha='center', va='center', color='k', fontsize=12)

        ax.set_xlabel("$PC1$")
        ax.set_ylabel("$PC2$")
        ax.set_zlabel("$PC3$")
        plt.title("Compositional Plot in 3 Dimension")
        plt.grid()
    
    def rotate(angle): 
        ax.view_init(elev=10, azim=angle) 
    
    # animate, frames=values will be passed to rotate, interval means the the delay between frames in milliseconds
    rot_animation = animation.FuncAnimation(fig, rotate, init_func=init,
                                            frames=np.arange(0,362,2), interval=50) 
    # save the animat
    rot_animation.save('./images/animated_3d_composiontion_plot.gif', dpi=80, writer='imagemagick') 

在这里插入图片描述
在这里插入图片描述

  • 需要定义一个函数以获取特定的动画:
def rotate(angle): 
        ax.view_init(elev=10, azim=angle) 
  • 然后使用matplotlib动画,这将调用与frames参数作为角度和与50ms的间隔旋转功能
rot_animation = animation.FuncAnimation(fig, rotate, init_func=init,
                                            frames=np.arange(0,362,2), interval=50) 
  • 所以这将导致360°的轮换,其中2°步每个耗费时间50ms。将动画保存为gif文件:
rot_animation.save('./images/animated_3d_composiontion_plot.gif', dpi=80, writer='imagemagick') 

参考资料:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值