How to delete a set of meshgrid points inside a circle?

前端 未结 3 614
[愿得一人]
[愿得一人] 2021-01-13 22:10

I am trying to create a meshgrid without some of the points that falls within the circle having specified coordinates and a radius. I am not able to subtract the grid points

相关标签:
3条回答
  • 2021-01-13 22:37

    One can not simply remove points from a meshgrid. Instead, you should create another array Z as

    Z = numpy.where((X-circle_x)**2+(Y-circle_y)**2>r**2,1,0)
    

    and plot it as

    plt.scatter(X,Y,Z)
    
    0 讨论(0)
  • 2021-01-13 22:41

    You cannot remove the points within the arrays x and y. It is a 2D problem and the values that need to be removed from x depend on y and inversely.

    What you can do is operate directly on the mesh you created (X and Y). For example,

    import math
    import numpy 
    import matplotlib.pyplot as plt
    
    
    N = 200
    x_start, x_end = -2.0, 2.0 
    y_start, y_end = -2.0, 2.0
    
    
    x = numpy.linspace(x_start, x_end, N)
    y = numpy.linspace(y_start, y_end, N)
    
    circle_x, circle_y, r= 0.0, 0.0, 0.4
    
    X, Y = numpy.meshgrid(x, y)
    
    ## Define points within circle
    pts = (X-circle_x)**2+(Y-circle_y)**2 <= r**2
    
    ## Create a constant mask over grid
    M = numpy.ones(X.shape)
    ## Assign 0 to mask for all points within circle
    M[pts] = 0
    
    size = 10
    fig = plt.figure()
    plt.imshow(M)
    plt.show()
    

    This does not remove any points from X or Y. If instead, you wish to only perform calculations on part of the points, you could do

    pts = (X-circle_x)**2+(Y-circle_y)**2 > r**2
    X = X[pts]
    Y = Y[pts]
    
    plt.scatter(X,Y)
    plt.show()
    
    0 讨论(0)
  • 2021-01-13 22:59

    If you'd like a scatter plot with just the points outside the circle, use boolean indexing to select only those points from your 2D "meshgridded" array:

    import numpy as np
    import matplotlib.pyplot as plt
    
    N = 50
    x_start, x_end = -2.0, 2.0
    y_start, y_end = -1.0, 1.0
    
    x = np.linspace(x_start, x_end, N)
    y = np.linspace(y_start, y_end, N)
    
    x0, y0, radius = 0.0, 0.0, 0.4
    
    x, y = np.meshgrid(x, y)
    r = np.sqrt((x - x0)**2 + (y - y0)**2)
    
    outside = r > radius
    
    fig, ax = plt.subplots()
    ax.set(xlabel='X', ylabel='Y', aspect=1.0)
    
    ax.scatter(x[outside], y[outside])
    
    plt.show()
    

    enter image description here


    On the other hand, if you were using something like imshow that requires 2D input, you'd need to either mask the values inside (as @JulienSpronck mentions, though it would be better to set them to np.nan or use a masked array than to set them to 0) or set a clip path on the image.

    For scatter, however, you don't need 2D input.


    Boolean indexing on a nD array will return a 1d result. For example:

    In [9]: x = np.arange(100).reshape(10, 10)
    
    In [10]: x
    Out[10]: 
    array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
           [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
           [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
           [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
           [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
           [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
           [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
           [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
           [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])
    
    In [11]: x[x > 75]
    Out[11]: 
    array([76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
           93, 94, 95, 96, 97, 98, 99])
    

    Because scatter is only plotting points, it doesn't care how they're connected, and we can easily use the 1D result of boolean indexing.

    On the other hand, if you wanted to plot an image, you'd need a 2D grid. In that case, you'd want to mask the values instead:

    In [12]: np.ma.masked_where(x <= 75, x)
    Out[12]: 
    masked_array(data =
     [[-- -- -- -- -- -- -- -- -- --]
     [-- -- -- -- -- -- -- -- -- --]
     [-- -- -- -- -- -- -- -- -- --]
     [-- -- -- -- -- -- -- -- -- --]
     [-- -- -- -- -- -- -- -- -- --]
     [-- -- -- -- -- -- -- -- -- --]
     [-- -- -- -- -- -- -- -- -- --]
     [-- -- -- -- -- -- 76 77 78 79]
     [80 81 82 83 84 85 86 87 88 89]
     [90 91 92 93 94 95 96 97 98 99]])
    

    Notice how this maintains the 2D structure of the input.

    On a side note, if this were a floating point array, you could just as easily set the values to np.nan instead of masking them. When plotted with imshow, the two will behave identically. I used a masked array in this case because x was an integer array and can't contain NaN's.

    0 讨论(0)
提交回复
热议问题