You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中等高线内多多边形面积计算的错误修复方案

多等高线多边形场景下动物家域面积计算报错修复方案

问题背景

我有一个记录动物活动区域所有(X,Y)位置的DataFrame,需要计算研究期间动物占领区域的面积。部分原始数据如下:

X                  Y
5508.695055    5000.133944  
5509.405078    5000.794318
5509.399589    5000.608576
5508.822574    5000.658109
5508.752179    5000.757261  
5514.831466    4989.379770
5514.388758    4989.025955
5515.196170    4989.357183
5515.755913    4989.102731
5515.098742    4988.847782

参考建议后,我使用格林定理计算多边形等高线包围面积,并用seaborn的kdeplot绘制等高线多边形,单多边形场景下代码运行正常:

import numpy as np
import matplotlib.pylab as plt
import seaborn as sns

# 用格林定理计算等高线包围的面积
def area(vs):
    a = 0
    x0,y0 = vs[0]
    for [x1,y1] in vs[1:]:
        dx = x1-x0
        dy = y1-y0
        a += 0.5*(y0*dx - x0*dy)
        x0 = x1
        y0 = y1
    return a

# 绘制核密度估计等高线多边形
fig,ax=plt.subplots()
levels = [0.05, 1]  # 提前定义levels变量
kde = sns.kdeplot(data=DfHR, x='X', y='Y', shade=True, ax=ax, levels=levels, cmap="Reds", alpha=0.9)

# 计算单多边形面积
for i in range(len(levels)):
    contour = kde.collections[0]
    vs = contour.get_paths()[0].vertices
    # 计算顶点包围的面积
    a = area(vs)
    print(f"r = {levels[i]}: a = {np.abs(a)}")

plt.show()

但在多多边形场景下修改代码后,出现TypeError: 'int' object is not callable错误,修改后的代码如下:

fig,ax=plt.subplots()
kde = sns.kdeplot(data=DfHR, x='X', y='Y', shade=True, ax=ax, levels=[0.05,1], cmap="Reds", alpha=0.9)

for i in range(len(levels)):
    contour = kde.collections[i]
    vs = contour.get_paths()
    area = 0  # 这里的变量名覆盖了自定义的area函数
    for island in vs:
        ai = np.abs(area(island.vertices))  # 此时area是整数,无法调用
        area += ai
    print("r = " + str(levels[i]) + ": a =" + str(area))
plt.show()

错误原因

报错的核心原因是变量名冲突:在循环中定义了area = 0,这个变量覆盖了之前自定义的area()函数。当后续执行area(island.vertices)时,Python会把area当成整数变量,而非可调用的函数,因此抛出类型错误。

修复方案

将循环中的面积累加变量重命名,避免与自定义函数名冲突,同时优化代码细节:

import numpy as np
import matplotlib.pylab as plt
import seaborn as sns

# 用格林定理计算等高线包围的面积
def polygon_area(vs):  # 也可以直接保留area,只要不重名覆盖即可
    a = 0
    x0,y0 = vs[0]
    for x1,y1 in vs[1:]:
        dx = x1 - x0
        dy = y1 - y0
        a += 0.5 * (y0 * dx - x0 * dy)
        x0, y0 = x1, y1
    return np.abs(a)  # 直接在函数内取绝对值,简化后续代码

# 绘制核密度估计等高线多边形
fig, ax = plt.subplots()
levels = [0.05, 1]
kde = sns.kdeplot(data=DfHR, x='X', y='Y', shade=True, ax=ax, levels=levels, cmap="Reds", alpha=0.9)

# 遍历每个等高线层级,计算多多边形总面积
for idx, level in enumerate(levels):
    contour = kde.collections[idx]
    paths = contour.get_paths()
    total_area = 0  # 重命名累加变量,避免覆盖函数
    for path in paths:
        poly_area = polygon_area(path.vertices)
        total_area += poly_area
    print(f"r = {level}: a = {total_area:.2f}")

plt.show()

关键修改点

  1. 变量名冲突解决:将循环中的累加变量从area改为total_area,或者将自定义函数重命名为polygon_area,避免命名冲突。
  2. 简化绝对值处理:在自定义面积计算函数内直接取绝对值,避免重复编写np.abs()。
  3. 代码可读性优化:使用enumerate遍历levels,同时获取索引和层级值,代码更简洁。
  4. 明确变量定义:提前明确定义levels变量,避免潜在的未定义错误。

内容的提问来源于stack exchange,提问作者kokovado00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:57:08