【问题标题】:Plot a triangle contour/surface matplotlib python: tricontourf/meshgrid绘制三角形轮廓/曲面 matplotlib python: tricontourf/meshgrid
【发布时间】:2021-10-26 03:58:49
【问题描述】:

鉴于下图,plt.Polygon 用于创建三角形,plt.contourf 用于创建轮廓,我想“切断”在 X 中标记的区域,以便仅获得三角形内部的轮廓。我该怎么做?

我尝试在上述区域中放置NaN 值,但边缘是方形的,因此需要一个大的网格来在不需要的区域和想要的区域之间生成“干净”的切割。使用plt.tricontourf 更合适吗?如果是这样,应该如何处理它?

【问题讨论】:

    标签: python numpy matplotlib plot contour


    【解决方案1】:

    感谢@Zephyr 提供tricontourf 解决方案,这是我在不使用tricontourf 和简单meshgrid 的情况下解决它的方法

    # =============== Define Points =============== #
    left_point = np.array([8, 1])
    top_point = np.array([10.75, 3.75])
    right_point = np.array([13.5, 1])
    
    # =============== Define Left Line Eq: y = mx+c =============== #
    left_m = (top_point[-1] - left_point[-1]) / (top_point[0] - left_point[0])
    left_c = left_point[-1] - left_m*left_point[0]
    # =============== Define Right Line Eq: y = mx+c =============== #
    right_m = (right_point[-1] - top_point[-1]) / (right_point[0] - top_point[0])
    right_c = right_point[-1] - right_m*right_point[0]
    
    # =============== Generate Spaced Points on Both Lines =============== #
    n_points = 100
    
    # x-coordinates on left line
    X_left = np.linspace(left_point[0], top_point[0], n_points)
    # y-coordinates on left line
    Y_left = left_m * X_left + left_c
    
    # x-coordinates on right line
    X_right = np.linspace(right_point[0], top_point[0], n_points)
    # y-coordinates on right line
    Y_right = right_m * X_right + right_c
    
    # Concatenate Left line X and Right line X: [X_left, X_right]
    LR_X = np.hstack([X_left[:, None], X_right[:, None]])
    
    
    # =============== Generate Spaced Points IN BETWEEN points on both lines =============== #
    
    """
    # We can use lists to generate points between each adjacent points on the left/right line
    # Then turn them into arrays
    # NOTE: Y_left and Y_right are essentially equal so we could just use one of them
    
    # XX = []
    # YY = []
    # for ii in range(n_points):
    #     XX.append(np.linspace(LR_X[ii, 0], LR_X[ii, 1], n_points).reshape(1, -1))
    #     YY.append(Y_left[ii]*np.ones(n_points).reshape(1, -1))
    # XX = np.vstack(XX)
    # YY = np.vstack(YY)
    
    """
    
    # Or We could do this (Same thing)
    XX = np.meshgrid(np.linspace(LR_X[:, 0], LR_X[:, 1], n_points))[0].reshape(n_points, n_points).T
    YY = np.meshgrid([Y_left*np.ones(n_points)]*n_points)[0].reshape(n_points, n_points).T
    
    # Im using a model to predict each point, so i had to flatten it out first
    # i.e. XX.shape = (100, 100); YY.shape = (100, 100), WW.shape = (100*100, 2)
    WW = np.c_[XX.ravel(), YY.ravel()]
    ZZ = model.predict(WW).reshape(XX.shape)
    
    # =============== Contour/Surface Plots =============== #
    # Contour plot
    fig1 = plt.figure(1, figsize=(8, 6))
    ax1 = fig1.add_subplot(111)
    levels = np.arange(Y.min(), Y.max())
    contour_map = ax1.contourf(XX, YY, ZZ, cmap='viridis')
    contour = ax1.contour(XX, YY, ZZ)
    cbar = fig1.colorbar(contour_map, )
    
    # Surface Plot
    fig2 = plt.figure(2, figsize=(10, 6))
    ax2 = fig2.add_subplot(projection='3d')
    ax2.plot_surface(XX, YY, ZZ, cmap='viridis')
    

    【讨论】:

      【解决方案2】:

      您可以使用 matplotlib.pyplot.tricontourf 进行操作,但这取决于您存储数据的方式。
      你应该有 4 个数组:

      • x 数组 (1, N) 带 x 坐标
      • y 数组 (1, N) 带 y 坐标
      • z 数组 (1, N) 带 z 值
      • triangles xy 点的索引列表,它们是剪切三角形的顶点
      x = np.asarray([8, 10, 8, 14, 9, 11, 13, 10, 12, 11])
      y = np.asarray([2, 2, 2, 2, 2.56666667, 2.56666667, 2.56666667, 3.13333333, 3.13333333, 3.7])
      z = np.cos(2.5*x*x)*np.cos(1.5*y*x)
      triangles = [[0, 3, 9]]
      

      然后您可以执行三角测量:

      triang = mtri.Triangulation(x, y, triangles)
      

      完整代码

      import matplotlib.pyplot as plt
      import matplotlib.tri as mtri
      import numpy as np
      
      
      x = np.asarray([8, 10, 8, 14, 9, 11, 13, 10, 12, 11])
      y = np.asarray([2, 2, 2, 2, 2.56666667, 2.56666667, 2.56666667, 3.13333333, 3.13333333, 3.7])
      z = np.cos(2.5*x*x)*np.cos(1.5*y*x)
      triangles = [[0, 3, 9]]
      
      triang = mtri.Triangulation(x, y, triangles)
      
      
      fig, ax = plt.subplots()
      
      t = ax.tricontourf(triang, z)
      plt.colorbar(t)
      
      plt.show()
      

      如果您的数据不是这种形状,您应该重新调整您的数组,以便如上所述获得xyz,并计算triangles 索引列表。如果您需要帮助,请提供您的数据。

      【讨论】:

        猜你喜欢
        • 2020-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-28
        • 2021-02-14
        • 1970-01-01
        相关资源
        最近更新 更多