一、绘制马鞍面(双曲抛物面)

       定义函数saddle_surface(),用来绘制马鞍面,为方便代码的编写和调试,给定了函数参数的初始值,后续可根据不同的需要来调整函数中的参数。

       首先,使用matplotlib库来定义绘图窗口的大小和格式,然后使用numpy库下的linspace获取相对应的数值,对于获取到的数值,需要进一步使用numpy.meshgrid()函数来进行处理,将其转化为相对应的二维矩阵网格,然后利用马鞍面(双曲抛物面)方程:\frac{x^{2}}{a^2} - \frac{y^2}{b^2} = z 计算z的相关数值并使用ax.plot_surface()函数将其绘制成相对应的曲面,运行结果请见图1-1。

       在plot_surface()函数中,可以使用matplotlib.cm.模块来为曲面添加颜色映射,具体有

matplotlib.cm.viridis:从深蓝色到黄色

matplotlib.cm.plasma:从暗紫色到亮黄色

matplotlib.cm.coolwarm:从红褐色到蓝色

matplotlib.cm.magma:从黑色到浅棕色

matplotlib.cm.cividis:从深蓝色到浅黄色

matplotlib.cm.jet:从深蓝色到深红色

matplotlib.cm.rainbow:从浅蓝色到浅红色

matplotlib.cm.Greys:从白色到黑色

matplotlib.cm.Blues:从白色到蓝色

matplotlib.cm.Greens:从白色到绿色

matplotlib.cm.Oranges:从白色到橙色

matplotlib.cm.Reds:从白色到红色

matplotlib.cm.inferno:从黑色到亮橙色

def saddle_surface(a=2, b=1, left_x=-15, right_x=15, left_y=-10, right_y=10):
    """绘制双曲抛物面(马鞍面)
       参数含义:
             ① a,b为常数,且均大于0
             ② left_x表示横坐标区间的左端点
             ③ right_x表示横坐标区间的右端点
             ④ left_y表示纵坐标区间的左端点
             ⑤ right_y表示纵坐标区间的右端点"""
    # 设定画布的尺寸与格式
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111,projection='3d')

    # 获取数值
    x = numpy.linspace(left_x,right_x,100)
    y = numpy.linspace(left_y,right_y,100)

    # 将x与y的值转换为二维网格矩阵,用以计算z的值
    X, Y = numpy.meshgrid(x,y)

    # 利用马鞍面(双曲抛物面)的公式计算z的值
    z = ((X**2)/(a**2)) - ((Y**2)/(b**2))

    # 绘制马鞍面(双曲抛物面),同时为曲面添加颜色映射
    ax.plot_surface(X, Y, z, cmap=matplotlib.cm.coolwarm)

    # 为图片设置标题
    ax.set_title(' (x²/{}²) - (y²/{}²) = z'.format(a,b))

    # 设置x轴名称
    ax.set_xlabel('values of x')
    # 设置y轴名称
    ax.set_ylabel('values of y')
    # 设置z轴名称
    ax.set_zlabel('values of z')

    matplotlib.pyplot.show()

图1-1

   二、绘制椭圆抛物面

绘制原理与马鞍面(双曲抛物面)一样,只是需要将马鞍面方程改写为椭圆抛物面方程:\frac{x^2}{a^2} + \frac{y^2}{b^2} = z   ,运行结果请见图2-1。

def ellipsoidal_paraboloid(a=10, b=10, left_x=-2, right_x=2, left_y=-2, right_y=2):
    """绘制椭圆抛物面
       参数含义:
             ① a,b为常数,且均大于0
             ② left_x表示横坐标区间的左端点
             ③ right_x表示横坐标区间的右端点
             ④ left_y表示纵坐标区间的左端点
             ⑤ right_y表示纵坐标区间的右端点"""
    # 设定画布的尺寸与格式
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111,projection='3d')

    # 获取数值
    x = numpy.linspace(left_x,right_x,100)
    y = numpy.linspace(left_y,right_y,100)

    # 将x与y的值转换为二维网格矩阵,用以计算z的值
    X,Y = numpy.meshgrid(x,y)

    # 利用椭圆抛物面的公式计算z的值
    z = ((X**2)/(a**2)) + ((Y**2)/(b**2))

    # 绘制椭圆抛物面
    ax.plot_surface(X, Y, z, cmap = matplotlib.cm.coolwarm)

    # 为图片设置标题
    ax.set_title(' (x²/{}²) + (y²/{}²) = z'.format(a,b))

    # 设置x轴名称
    ax.set_xlabel('values of x')
    # 设置y轴名称
    ax.set_ylabel('values of y')
    # 设置z轴名称
    ax.set_zlabel('values of z')

    matplotlib.pyplot.show()

图2-1

三、绘制双叶双曲面

双叶双曲面方程:\frac{x^2}{a^2} + \frac{y^2}{b^2} - \frac{z^2}{c^2} = -1

特别注意:由于双叶双曲面分上下两部分,所以在代码中,应该绘制两次,绘制一次上半部分,再绘制一次下半部分,运行结果请见图3-1。

def hyperboloid_of_two_sheets(a=1,b=1,c=1,left_x=-2, right_x=2, left_y=-2, right_y=2):
    """绘制双叶双曲面
       参数含义:
             ① a,b,c为常数,且均大于0
             ② left_x表示横坐标区间的左端点
             ③ right_x表示横坐标区间的右端点
             ④ left_y表示纵坐标区间的左端点
             ⑤ right_y表示纵坐标区间的右端点 """
    # 设定画布的尺寸与格式
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111, projection='3d')

    # 获取数值
    x = numpy.linspace(left_x, right_x, 100)
    y = numpy.linspace(left_y, right_y, 100)

    # 将x与y的值转换为二维网格矩阵,用以计算z的值
    X, Y = numpy.meshgrid(x, y)

    # 利用双叶双曲面公式来计算z的数值
    z = numpy.sqrt((X ** 2 / a ** 2 + Y ** 2 / b ** 2 + 1) * (c ** 2))

    # 双叶双曲面分正半叶和负半叶,所以要绘制两次
    ax.plot_surface(X, Y, z, cmap = matplotlib.cm.coolwarm)
    ax.plot_surface(X, Y, -z, cmap = matplotlib.cm.coolwarm)

    # 为图片设置标题
    ax.set_title(' (x²/{}²) + (y²/{}²) - (z²/{}²) = -1'.format(a,b,c))

    # 设置x轴名称
    ax.set_xlabel('values of x')
    # 设置y轴名称
    ax.set_ylabel('values of y')
    # 设置z轴名称
    ax.set_zlabel('values of z')

    matplotlib.pyplot.show()

图3-1

四、绘制二次锥面

二次锥面方程:\frac{x^2}{a^2} + \frac{y^2}{b^2} - \frac{z^2}{c^2} = 0

二次锥面也分为上下两部分,所以也应该绘制两次,运行结果请见图4-1.

def secondary_cone_surface(a=1,b=1,c=2,left_x=-3, right_x=3, left_y=-3, right_y=3):
    """绘制二次锥面
       参数含义:
              ① a,b,c为常数,且均大于0
              ② left_x表示横坐标区间的左端点
              ③ right_x表示横坐标区间的右端点
              ④ left_y表示纵坐标区间的左端点
              ⑤ right_y表示纵坐标区间的右端点 """
    # 设定画布的尺寸与格式
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111, projection='3d')

    # 获取数值
    x = numpy.linspace(left_x, right_x, 100)
    y = numpy.linspace(left_y, right_y, 100)

    # 将x与y的值转换为二维网格矩阵,用以计算z的值
    X, Y = numpy.meshgrid(x, y)

    # 利用二次锥面公式来计算z的数值
    z = c ** 2 * ((X ** 2 / a ** 2) + (Y ** 2 / b ** 2))

    # 二次锥面分正半轴锥面与负半轴锥面,所以应当分别进行绘制
    z_upper = numpy.sqrt(z)
    z_lower = -numpy.sqrt(z)
    ax.plot_surface(X, Y, z_upper, cmap=matplotlib.cm.plasma)
    ax.plot_surface(X, Y, z_lower, cmap=matplotlib.cm.plasma)

    # 设置图片标题为二次锥面的方程
    ax.set_title(' (x²/{}²) + (y²/{}²) - (z²/{}²) = 0'.format(a,b,c))

    # 设置x轴名称
    ax.set_xlabel('values of x')
    # 设置y轴名称
    ax.set_ylabel('values of y')
    # 设置z轴名称
    ax.set_zlabel('values of z')

    # 调整坐标轴比例,防止变形
    ax.set_box_aspect([a, b, c])

    matplotlib.pyplot.show()

图4-1

五、绘制单叶双曲面

单叶双曲面方程:\frac{x^2}{a^2} + \frac{y^2}{b^2} - \frac{z^2}{c^2} = 1

特别注意,单叶双曲面在某些区间处没有实数解,所以在绘制之前,应当先排除没有实数解的区域,再进行绘制,运行结果请见图5-1.

def hyperboloid_of_one_sheet(a=2,b=2,c=1,left_x=-4, right_x=4, left_y=-4, right_y=4):
    """绘制单叶双曲面
           参数含义:
                 ① a,b,c为常数,且均大于0
                 ② left_x表示横坐标区间的左端点
                 ③ right_x表示横坐标区间的右端点
                 ④ left_y表示纵坐标区间的左端点
                 ⑤ right_y表示纵坐标区间的右端点 """
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111,projection='3d')

    x = numpy.linspace(left_x, right_x, 100)
    y = numpy.linspace(left_y, right_y, 100)

    X,Y = numpy.meshgrid(x,y)

    # 利用单叶双曲面公式计算z的数值
    z = c ** 2 * ((X ** 2 / a ** 2) + (Y ** 2 / b ** 2) - 1)

    # 过滤没有实数解的区域
    z = numpy.where(z>=0,z,numpy.nan)

    z_upper = numpy.sqrt(z)
    z_lower = -numpy.sqrt(z)
    ax.plot_surface(X,Y,z_upper,cmap=matplotlib.cm.plasma)
    ax.plot_surface(X,Y,z_lower,cmap=matplotlib.cm.plasma)

    ax.set_title(' (x²/{}²) + (y²/{}²) - (z²/{}²) = 1'.format(a,b,c))
    ax.set_xlabel('values of x')
    ax.set_ylabel('values of y')
    ax.set_zlabel('values of z')

    ax.set_box_aspect([a, b, c])
    matplotlib.pyplot.show()

图5-1

六、绘制双曲柱面

双曲柱面方程:\frac{x^2}{a^2} -\frac{y^2}{b^2} = 1

运行结果请见图6-1,(注意,本运行结果绘制的是平行于z轴的双曲柱面,如需绘制平行于其他轴的双曲柱面,请更改方程)

def hyperbolic_cylinder(a=2,b=1,left_x=-5, right_x=5, left_z=-3, right_z=3):
    """绘制双曲柱面
               参数含义:
                     ① a,b为常数,且均大于0
                     ② left_x表示横坐标区间的左端点
                     ③ right_x表示横坐标区间的右端点
                     ④ left_z表示高坐标区间的左端点
                     ⑤ right_z表示高坐标区间的右端点 """
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111, projection='3d')

    x = numpy.linspace(left_x, right_x, 100)
    z = numpy.linspace(left_z, right_z, 100)

    X, Z = numpy.meshgrid(x, z)

    y = b**2 * (X**2 / a**2 - 1)

    # 过滤没有实数解的区域
    y = numpy.where(y >= 0, y, numpy.nan)

    y_right = numpy.sqrt(y)
    y_left = -numpy.sqrt(y)
    ax.plot_surface(X, y_right, Z, cmap=matplotlib.cm.turbo)
    ax.plot_surface(X, y_left, Z, cmap=matplotlib.cm.turbo)

    ax.set_title(' (x²/{}²) - (y²/{}²) = 1'.format(a,b))
    ax.set_xlabel('values of x')
    ax.set_ylabel('values of y')
    ax.set_zlabel('values of z')

    # 调整视角,参数elev表示天顶角(球坐标系中的fai),参数azim表示方位角(球坐标系中的cita)
    ax.view_init(elev=35, azim=45)

    ax.set_box_aspect([a, b, (left_z - right_z)/2])

    matplotlib.pyplot.show()

图6-1

七、绘制椭圆柱面

椭圆柱面方程:\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1

运行结果请见图7-1,(注意,本运行结果绘制的是平行于z轴的椭圆柱面,如需绘制平行于其他轴的椭圆柱面,请更改方程)

def elliptic_cylinder(a=2,b=1,left_x=-5, right_x=5, left_z=-3, right_z=3):
    """绘制椭圆柱面
       参数含义:
             ① a,b为常数,且均大于0
             ② left_x表示横坐标区间的左端点
             ③ right_x表示横坐标区间的右端点
             ④ left_z表示高坐标区间的左端点
             ⑤ right_z表示高坐标区间的右端点 """
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111, projection='3d')

    x = numpy.linspace(left_x, right_x, 100)
    z = numpy.linspace(left_z, right_z, 100)

    X, Z = numpy.meshgrid(x, z)

    y = b ** 2 * (1 - (X ** 2 / a ** 2))

    # 过滤没有实数解的区域
    y = numpy.where(y >= 0, y, numpy.nan)

    y_right = numpy.sqrt(y)
    y_left = -numpy.sqrt(y)
    ax.plot_surface(X, y_right, Z, cmap=matplotlib.cm.turbo)
    ax.plot_surface(X, y_left, Z, cmap=matplotlib.cm.turbo)

    ax.set_title(' (x²/{}²) + (y²/{}²) = 1'.format(a,b))
    ax.set_xlabel('values of x')
    ax.set_ylabel('values of y')
    ax.set_zlabel('values of z')

    # 调整视角,参数elev表示天顶角(球坐标系中的fai),参数azim表示方位角(球坐标系中的cita)
    ax.view_init(elev=35, azim=45)

    ax.set_box_aspect([a, b, (left_z - right_z)/2])

    matplotlib.pyplot.show()

图7-1

八、绘制抛物柱面

双曲柱面方程:y^{2} = 2ax

运行结果请见图8-1,(注意,本运行结果绘制的是平行于z轴的抛物柱面,如需绘制平行于其他轴的抛物柱面,请更改方程)

def parabolic_cylinder(a=1, left_y=-5, right_y=5, left_z=-3, right_z=3):
    """绘制抛物柱面
           参数含义:
                 ① a为常数,大于0
                 ② left_y表示纵坐标区间的左端点
                 ③ right_y表示纵坐标区间的右端点
                 ④ left_z表示高坐标区间的左端点
                 ⑤ right_z表示高坐标区间的右端点 """
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111, projection='3d')

    y = numpy.linspace(left_y, right_y, 100)
    z = numpy.linspace(left_z, right_z, 100)

    Y, Z = numpy.meshgrid(y, z)

    # 抛物柱面公式
    x = Y**2 / (2*a)

    ax.plot_surface(x, Y, Z, cmap=matplotlib.cm.turbo)

    ax.set_title('y²={}x'.format(2*a))
    ax.set_xlabel('values of x')
    ax.set_ylabel('values of y')
    ax.set_zlabel('values of z')
    # 调整视角,参数elev表示天顶角(球坐标系中的fai),参数azim表示方位角(球坐标系中的cita)
    ax.view_init(elev=30, azim=45)
    matplotlib.pyplot.show()

图8-1

九、绘制椭球

椭球方程:\frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} = 1

运行结果请见图9-1。

def ellipsoid(a=2, b=3, c=1, left_x=-2, right_x=2, left_y=-3, right_y=3):
    """绘制椭球面
           参数含义:
                 ① a,b,c为常数,且均大于0
                 ② left_x表示横坐标区间的左端点
                 ③ right_x表示横坐标区间的右端点
                 ④ left_y表示纵坐标区间的左端点
                 ⑤ right_y表示纵坐标区间的右端点 """
    fig = matplotlib.pyplot.figure(figsize=(10,10))
    ax = fig.add_subplot(111,projection='3d')
    x = numpy.linspace(left_x, right_x, 100)
    y = numpy.linspace(left_y, right_y, 100)
    X,Y = numpy.meshgrid(x,y)

    # 椭球面公式
    z = c ** 2 * (1 - X ** 2 / a ** 2 - Y ** 2 / b ** 2)

    # 过滤没有实数解的区域
    z = numpy.where(z>=0,z,numpy.nan)

    z_upper = numpy.sqrt(z)
    z_lower = -numpy.sqrt(z)
    ax.plot_surface(X,Y,z_upper,cmap=matplotlib.cm.plasma)
    ax.plot_surface(X,Y,z_lower,cmap=matplotlib.cm.plasma)

    ax.set_title(' (x²/{}²) + (y²/{}²) + (z²/{}²) = 1'.format(a,b,c))
    ax.set_xlabel('values of x')
    ax.set_ylabel('values of y')
    ax.set_zlabel('values of z')

    # 保持坐标轴比例一致
    ax.set_box_aspect([a, b, c])

    matplotlib.pyplot.show()

图9-1

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐