【问题标题】:Calculating Centroid of outline of XY scatter计算XY散点轮廓的重心
【发布时间】:2017-10-01 17:27:59
【问题描述】:

我正在做一个项目来使用 python 计算州/国家的质心。

到目前为止我做了什么:

  1. 绘制状态轮廓并通过 ImageJ 运行它以创建边界 x、y 坐标的 csv。这给了我一个 .csv 文件,其中包含如下数据:

    556,243

    557,243

    557,250

    556,250

    556,252

    555,252

    555,253

    554,253

    等等等等

大约 2500 个数据点。

  1. 将此列表导入 Python 脚本。

  2. 计算 x 和 y 坐标数组的平均值。这个点就是质心。 (Idea similar to this)

  3. 使用 matplotlib 绘制点和质心。

这是我的代码:

#####################################################
#                     Imports                       #
#####################################################
import csv
import matplotlib.pyplot as plt
import numpy as np
import pylab


#####################################################
#                       Setup                       #
#####################################################

#Set empty list for coordinates
x,y =[],[]

#Importing csv data 
with open("russiadata.csv", "r") as russiadataFile:
    russiadataReader = csv.reader(russiadataFile)

    #Create list of points
    russiadatalist = []

    #Import data
    for row in russiadataReader:
        #While the rows have data, AKA length not equal to zero. 
        if len(row) != 0: 
            #Append data to arrays created above
            x.append(float(row[0]))
            y.append(float(row[1]))

#Close file as importing is done
russiadataFile.closejust flipped around the 




#####################################################
#                  Data Analysis                    #
#####################################################

#Convert list to array for computations
x=np.array(x)
y=np.array(y)


#Calculate number of data points
x_len=len(x)just flipped around the 
y_len=len(y)

#Set sum of points equal to x_sum and y_sum
x_sum=np.sum(x)
y_sum=np.sum(y)

#Calculate centroid of points
x_centroid=x_sum/x_len
y_centroid=y_sum/y_len



#####################################################
#                     Plotting                      #
#####################################################


#Plot all points in data
plt.xkcd()
plt.plot(x,y, "-.")

#Plot centroid and label it
plt.plot(x_centroid,y_centroid,'^')


plt.ymax=max(x)
#Add axis labels
plt.xlabel("X")
plt.ylabel("Y")
plt.title("russia")

#Show the plot
plt.show()

我遇到的问题是该州的某些方面比其他方面有更多的点,因此质心被加权到具有更多点的区域。这不是我想要的。我试图找到具有 x,y 坐标顶点的多边形的质心。

这就是我的情节:

https://imgur.com/a/ZdukA

如您所见,质心更偏向密度更高的点部分。 (作为旁注,是的,那是俄罗斯。我遇到了情节倒退和拉伸/压扁的问题。)

也就是说,有没有更准确的方法来获取质心?

提前感谢您的帮助。

【问题讨论】:

  • 听起来你想计算凸包的质心。我认为 scipy 可以为您提供凸包。然后匀称可以得到你的质心。
  • 我认为甚至不需要凸包,形状应该像 Polygon().centroid 一样简单

标签: python python-2.7 centroid


【解决方案1】:

在我看来,您不希望在计算质心时考虑到散射的密度。

如果您只想使用表面积,那么我会消除散点图当前轮廓内包含的任何点。一种稍微更准确的方法可能是假装有一个由最外面的点勾勒出的框,然后检查所有点的 x 和 y 坐标并消除任何落在框内的点。落在当前轮廓内的任何点都不会影响形状,只会影响密度。

我认为最技术和最准确的方法会非常复杂,这就是我认为它需要的:根据彼此之间的最短距离和与所有其他点的最远距离来连接最外层的点。通过“连接”,我的意思是假装一条线穿过并终止于两个点。它应该在数学上定义。 然后,对于每个点,计算它是否落在该轮廓的内部或外部,并消除所有落在该轮廓内的点(它们是多余的,因为它们已经在形状内)。

【讨论】:

  • 从头开始,是的,这很复杂。但是使用现有的库来计算凸包的质心会非常简单。
  • @Colin Hancey,这是解决问题的一种更合乎逻辑的方式。有没有我可以在 python 2.7 中查看的包可以帮助我解决这个问题/
  • 我最终重写了我的代码,使用蒙特卡罗来计算形状内的所有点。
【解决方案2】:

您可以在 Wikipedia 上找到闭合多边形的正确公式:https://en.wikipedia.org/wiki/Centroid#Centroid_of_a_polygon

另一个公式有助于处理加里宁格勒州(飞地)和岛屿(如果你想非常精确的话):https://en.wikipedia.org/wiki/Centroid#By_geometric_decomposition

也就是说,这样的问题可能更适合https://math.stackexchange.com

【讨论】:

  • 感谢您的链接。我现在正在尝试使用该等式。
猜你喜欢
  • 2010-11-01
  • 2020-05-08
  • 2021-07-03
  • 2013-10-23
  • 2021-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多