仅在选择多边形条件下将函数应用于网格?

问题描述

我的问题类似于这篇文章,但我在调整它时遇到了一些麻烦: Ambiguous truth value for meshgrid and user-defined functions using if-statement

本质上,我希望条件语句看起来不像这样:

import numpy as np

def test(x,y):
    a = 1.0/(1+x*x)
    b = np.ones(y.shape)
    mask = (y!=0)
    b[mask] = np.sin(y[mask])/y[mask]
    return a*b

相反,“掩码”取决于 x,y 是否位于某个多边形内。因此,结果数组中的每个值都是 1,但生成了 4 个值之间的多边形。我只希望该函数应用于来自位于多边形内的 2 个网格输入 (X,Y) 的点

x 和 y 是可以为负的实数。

我不确定如何将数组项作为奇异值传入。

我最终想在颜色图上绘制 Z 谢谢

即多边形内的点进行变换,多边形外的点保持为 1 例如,我希望我的函数看起来像这样

from shapely.geometry import Point
from shapely.geometry.polygon import polygon
def f(x,y,poly):
    a = 1.0/(1+x*x)
    b = np.ones(y.shape)
    mask = (Point(x,y).within(poly) == True)
    b[mask] = a*b
    return b 

x 和 y 是任意维度的网格

我应该补充一点,我收到以下错误: “只有大小为 1 的数组可以转换为 Python 标量”

生成 X 和 Y 并通过调用函数

coords = [(0,0),(4,4),(0,4)]
poly = polygon(coords)
x = np.linspace(0,10,11,endpoint = True) # x intervals
y = np.linspace(0,endpoint = True) # y intervals
X,Y = np.meshgrid(x,y)

Z = f(X,Y,poly)

谢谢!

错误信息:

Traceback (most recent call last):
  File "meshgrid_understanding.py",line 28,in <module>
    Z = f(X,poly)
  File "meshgrid_understanding.py",line 16,in f
    mask = (Point(x,y).within(poly) != True)
  File "C:\Users\Nick\AppData\Local\Programs\Python\python37\lib\site-packages\shapely\geometry\point.py",line 48,in __init__
    self._set_coords(*args)
  File "C:\Users\Nick\AppData\Local\Programs\Python\python37\lib\site-packages\shapely\geometry\point.py",line 137,in _set_coords
    self._geom,self._ndim = geos_point_from_py(tuple(args))
  File "C:\Users\Nick\AppData\Local\Programs\Python\python37\lib\site-packages\shapely\geometry\point.py",line 214,in geos_point_from_py
    dx = c_double(coords[0])
TypeError: only size-1 arrays can be converted to Python scalars

解决方法

您将一个数组传递给接受单个值的函数 Point

,

Matplotlib 有一个接受点数组的函数。演示:

import numpy as np
from matplotlib.path import Path

coords = [(0,0),(4,4),(0,4)]

x = np.linspace(0,10,11,endpoint=True)
y = np.linspace(0,endpoint=True)
X,Y = np.meshgrid(x,y)

points = np.c_[X.ravel(),Y.ravel()]
mask = Path(coords).contains_points(points).reshape(X.shape)