计算 XY 散点图轮廓的质心
Calculating Centroid of outline of XY scatter
我正在开展一个项目,使用 python 计算 state/country 的质心。
到目前为止我做了什么:
绘制状态轮廓并通过 ImageJ 运行 创建边框的 x、y 坐标的 csv。这给了我一个 .csv 文件,其中包含如下数据:
556,243
557,243
557,250
556,250
556,252
555,252
555,253
554,253
等等,等等,
大约 2500 个数据点。
将此列表导入 Python 脚本。
计算x和y坐标数组的平均值。这一点是质心。 (Idea similar to this)
使用 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 坐标中找到具有顶点的多边形的质心。
我的剧情是这样的:
如您所见,质心更倾向于密度更大的点部分。 (作为旁注,是的,那是俄罗斯。我对剧情倒退有疑问 stretched/squashed。)
换句话说,有没有更准确的获取质心的方法?
在此先感谢您的帮助。
您可以在维基百科上找到闭合多边形的正确公式:https://en.wikipedia.org/wiki/Centroid#Centroid_of_a_polygon
另一个公式有助于处理加里宁格勒州(飞地)和岛屿(如果你想非常精确的话):https://en.wikipedia.org/wiki/Centroid#By_geometric_decomposition
也就是说,这样的问题可能更适合 https://math.stackexchange.com
在我看来,您不希望在计算质心时考虑散射密度。
如果您只想使用表面积,那么我会消除包含在当前散点图轮廓内的任何点。一种稍微更准确的方法可能是假装最外面的点勾勒出一个框,然后检查所有点的 x 和 y 坐标并消除落在框内的任何点。落在当前轮廓内的任何点都不会影响形状,只会影响密度。
我认为最技术和最准确的方法会非常复杂,我认为它需要:根据彼此之间的最小距离和所有其他点之间的最远距离,让最外面的点连接起来点。 "connect" 我的意思是假装一条线穿过并终止于两个点。它应该在数学上定义。
然后,对于每个点,计算它是落在这个轮廓的内部还是外部,并消除所有落在内部的(它们是多余的,因为它们已经在形状内部)。
我正在开展一个项目,使用 python 计算 state/country 的质心。
到目前为止我做了什么:
绘制状态轮廓并通过 ImageJ 运行 创建边框的 x、y 坐标的 csv。这给了我一个 .csv 文件,其中包含如下数据:
556,243
557,243
557,250
556,250
556,252
555,252
555,253
554,253
等等,等等,
大约 2500 个数据点。
将此列表导入 Python 脚本。
计算x和y坐标数组的平均值。这一点是质心。 (Idea similar to this)
使用 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 坐标中找到具有顶点的多边形的质心。
我的剧情是这样的:
如您所见,质心更倾向于密度更大的点部分。 (作为旁注,是的,那是俄罗斯。我对剧情倒退有疑问 stretched/squashed。)
换句话说,有没有更准确的获取质心的方法?
在此先感谢您的帮助。
您可以在维基百科上找到闭合多边形的正确公式:https://en.wikipedia.org/wiki/Centroid#Centroid_of_a_polygon
另一个公式有助于处理加里宁格勒州(飞地)和岛屿(如果你想非常精确的话):https://en.wikipedia.org/wiki/Centroid#By_geometric_decomposition
也就是说,这样的问题可能更适合 https://math.stackexchange.com
在我看来,您不希望在计算质心时考虑散射密度。
如果您只想使用表面积,那么我会消除包含在当前散点图轮廓内的任何点。一种稍微更准确的方法可能是假装最外面的点勾勒出一个框,然后检查所有点的 x 和 y 坐标并消除落在框内的任何点。落在当前轮廓内的任何点都不会影响形状,只会影响密度。
我认为最技术和最准确的方法会非常复杂,我认为它需要:根据彼此之间的最小距离和所有其他点之间的最远距离,让最外面的点连接起来点。 "connect" 我的意思是假装一条线穿过并终止于两个点。它应该在数学上定义。 然后,对于每个点,计算它是落在这个轮廓的内部还是外部,并消除所有落在内部的(它们是多余的,因为它们已经在形状内部)。