zoukankan      html  css  js  c++  java
  • matplotlib---8.3D绘图

    一、直线、散点图、插值

    1.3D绘图与2D绘图区别

    3D绘图与2D绘图的调用方法几乎相同,除了增加一个 projection='3d'的关键字参数。

    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    fig=plt.figure()
    ax=fig.add_subplot(111,projection='3d') # 旧式写法
    ax=Axes3D(fig) #新式写法
    

    2.插值画3D图

    (1)载入数据

    # 载入模块
    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    import pandas as pd
    import seaborn as sns
    from scipy import interpolate
    
    df_epsilon_alpha = pd.read_excel('实验记录_超参数.xlsx',sheet_name='epsilon_alpha')
    #生成数据
    epsilon = np.array(df_epsilon_alpha['epsilon'].values)
    alpha = np.array(df_epsilon_alpha['alpha'].values)
    Precision = np.array(df_epsilon_alpha['Precision'].values) 

    (2)将x和y扩充到想要的大小

    xnew = np.arange(0.1, 1, 0.09) #左闭右闭每0.09间隔生成一个数
    ynew = np.arange(0.1, 1, 0.09)  
    或者
    x = np.linspace(0.1,0.9,9)#0.1到0.9生成9个数
    y = np.linspace(0.1,0.9,9)

    (3)对z插值

    x,y原数据:

    x = np.linspace(0.1,0.9,9)
    y = np.linspace(0.1,0.9,9)
    z = Precision

    采用 scipy.interpolate.interp2d函数进行插值

    f = interpolate.interp2d(x, y, z, kind='cubic')

    x,y扩充数据:

    xnew = np.arange(0.1, 1, 0.03)#(31,)
    ynew = np.arange(0.1, 1, 0.03)#(31,)
    znew = f(xnew, ynew)#(31,31) 

    znew为插值后的z

    (4)画图

    采用  from mpl_toolkits.mplot3d import Axes3D进行画三维图

    Axes3D简单用法:

    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    比如采用plot_trisurf画三维图:

    plot_trisurf(x,y,z)

    plot_trisurf对数据要求是:x.shape = y.shape = z.shape,所以x和y的shape需要修改,采用np.meshgrid,且都为一维数据

    修改x,y,z输入画图函数前的shape

    xx1, yy1 = np.meshgrid(xnew, ynew)#执行之后,xx1.shape=(31,31),yy1.shape=(31,31)
    newshape = (xx1.shape[0])*(xx1.shape[0])
    y_input = xx1.reshape(newshape)
    x_input = yy1.reshape(newshape)
    z_input = znew.reshape(newshape)

    x_input.shape,y_input.shape,z_input.shape=((961,), (961,), (961,))

    #画图
    sns.set(style='ticks')
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_trisurf(x_input,y_input,z_input,cmap=cm.coolwarm)
    
    plt.xlim((0.1,0.9))
    plt.xticks([0.1,0.3,0.5,0.7,0.9])
    plt.yticks([0.1,0.3,0.5,0.7,0.9])
    ax.set_xlabel(r'$alpha$',fontdict={'color': 'black',
                                 'family': 'Times New Roman',
                                 'weight': 'normal',
                                 'size': 18})
    ax.set_ylabel(r'$epsilon$',fontdict={'color': 'black',
                                 'family': 'Times New Roman',
                                 'weight': 'normal',
                                 'size': 18})
    ax.set_zlabel('precision',fontdict={'color': 'black',
                                 'family': 'Times New Roman',
                                 'weight': 'normal',
                                 'size': 18})
    
    plt.tight_layout()
    # plt.savefig('loc_svg/alpha_epsilon2.svg',dpi=600) #指定分辨率保存
    plt.show()
    插值前 插值后
     

    3.绘制直线

    Axes3D.plot(xs, ys, *args, **kwargs)
    

    参数: 

    1. xs,ys点的 x,y坐标
    2. zs点的z坐标。该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值
    3. zdir指定那个是z轴。其值可以是'x'或者'y'或者'z'
    4. 剩下的关键字参数与Axes.plot()相同

    4.绘制散点图

    Axes3D.scatter(xs, ys, zs=0, zdir=’z’, s=20, c=’b’, depthshade=True, *args, **kwargs)
    

    参数:

    1. xs,ys点的 x,y坐标
    2. zs点的z坐标。该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值
    3. zdir指定那个是z轴。其值可以是'x'或者'y'或者'z'
    4. s散点的大小(单位为 point^2).该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值
    5. c散点的颜色。你可以将它设为一个颜色字符串,表示所有的点都是一个颜色。或者是个 cmap,指定颜色图
    6. depthshade一个布尔值。如果为True,则通过对marker设置阴影来展示层次关系
    7. 剩下的关键字参数与Axes.scatter()相同

    5.绘制线框 

    Axes3D.plot_wireframe(X, Y, Z, *args, **kwargs)
    

    参数:

    • X,Y点的 x,y坐标
    • Z点的z坐标。该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值
    • rstride行的步长
    • cstride列的步长
    • 剩下的关键字传递给LineCollection

    二、修改X,Y,Z轴的刻度值

    1.修改X,Y,Z轴的刻度值

    from matplotlib.ticker import MultipleLocator,FuncFormatter
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    from matplotlib import cm
    from matplotlib import colors
    from matplotlib.ticker import LinearLocator, FormatStrFormatter
    import numpy as np
    import matplotlib.ticker as ticker
    
    def fun(x):
        if x >= 1:
            return 1
        return x
    
    def to_percent(temp, position):
        return '%1.0f'%(100*temp)
    
    x = np.arange(0, 0.5, 0.001)
    y = np.arange(0, 0.05, 0.001)
    x, y = np.meshgrid(x, y)
    z = (3*x+y-x*x-np.sqrt(2*x*x*x-3*x*x*x*x+x*x+22*x*x*y-22*x*y-12*x*x*x*y-8*x*x*y*y+12*x*y*y-7*y*y))/(2*x+2*y)
    
    for row in range(len(z)):
        for col in range(len(z[0])):
            z[row][col] = fun(z[row][col])
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.set_zlim3d(0.6,1.0)
    ax.zaxis.set_major_locator(LinearLocator(5))#Z轴显示5个刻度值
    
    norm = colors.Normalize(vmin=0.6,vmax=1.0)
    ax.xaxis.set_major_formatter(FuncFormatter(to_percent))#将X,Y,Z轴的坐标轴放大100倍
    ax.yaxis.set_major_formatter(FuncFormatter(to_percent))
    ax.zaxis.set_major_formatter(FuncFormatter(to_percent))
    
    ax.set_xlabel(r'$alpha$(%)')
    ax.set_ylabel(r'$	heta$(%)')
    ax.set_zlabel(r'$gamma^{*}$(%)')#坐标轴
    
    surf = ax.plot_surface(x, y, z,
                           cmap=cm.coolwarm,
                           linewidth=0,
                           norm=norm,
                           antialiased=False,
                           edgecolor='none')
    ax.contourf(x,y,z,zdir='z',offset=-2,cmap='rainbow')

    修改colorbar的刻度为百分的形式

    def fmt(x,pos):
        print(x)
        # a, b = '{:2.2e}'.format(x).split('e')
        # b = int(b)
        return r'${}$%'.format(int(x*100))
    cbar = plt.colorbar(surf,shrink=0.5, aspect=5,format=ticker.FuncFormatter(fmt))#format用来修改调色板的刻度值
    cbar.set_ticks([.6,.7,.8,.9,1.0]) plt.tight_layout() 
    plt.savefig('实验图.svg',dpi=600) #指定分辨率保存 
    plt.show()  
    未修改前 修改后
     

    alpha:0.0-0.5

    theta:0.00-0.05

    gamma:0.60-1.00

    colorbar:0.60-1.00

    alpha:0:50(每个乘以100)

    theta:0-5(每个乘以100)

    gamma:60-100(每个乘以100)

    colorbar:60%-100%(每个乘以100)

    参考文献:

    【1】matplotlib 修改坐标轴刻度值,刻度个数

    【2】解决python画图中colorbar设置刻度和标签字体大小

    【3】Matplotlib:给子图添加colorbar(颜色条或渐变色条)

  • 相关阅读:
    【BZOJ 1007】【HNOI 2008】水平可见直线 解析几何
    【POJ 2653】Pick-up sticks 判断线段相交
    【NOIP 2004】虫食算
    【TYVJ 1463】智商问题 (闲得无聊)
    【BZOJ 2599】【IOI 2011】Race 点分治
    【BZOJ 3050】【USACO2013 Jan】Seating 线段树
    【BZOJ 3048】【USACO2013 Jan】Cow Lineup 滑块思想
    【BZOJ 1758】【WC 2010】重建计划 分数规划+点分治+单调队列
    【BZOJ 3049】【USACO2013 Jan】Island Travels BFS+状压DP
    【BZOJ 1468】Tree 点分治
  • 原文地址:https://www.cnblogs.com/nxf-rabbit75/p/12099140.html
Copyright © 2011-2022 走看看