绘制按值分组的德莱尼三角剖分
Plot Delaney triangulation grouped by value
我正在尝试从 pandas df 绘制 delaunay 三角剖分。我希望按 Time
对这些点进行分组。目前,我在尝试从第一个时间点开始绘制点时遇到错误。
QhullError: QH6214 qhull input error: not enough points(2) to construct initial simplex (need 6)
While executing: | qhull d Q12 Qt Qc Qz Qbb
Options selected for Qhull 2019.1.r 2019/06/21:
run-id 768388270 delaunay Q12-allow-wide Qtriangulate Qcoplanar-keep
Qz-infinity-point Qbbound-last _pre-merge _zero-centrum Qinterior-keep
_maxoutside 0
它似乎只是将这两个数组作为一个点传递。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
df = pd.DataFrame({
'Time' : [1,1,1,1,2,2,2,2],
'A_X' : [5, 5, 6, 6, 4, 3, 3, 4],
'A_Y' : [5, 6, 6, 5, 5, 6, 5, 6],
})
fig, ax = plt.subplots(figsize = (6,6))
ax.set_xlim(0,10)
ax.set_ylim(0,10)
ax.grid(False)
points_x1 = df.groupby("Time")["A_X"].agg(list).tolist()
points_y1 = df.groupby("Time")["A_Y"].agg(list).tolist()
points = list(zip(points_x1, points_y1))
tri = Delaunay(points[0])
#plot triangulation
plt.triplot(points[:,0], points[:,1], tri.simplices)
plt.plot(points[:,0], points[:,1], 'o')
您可以利用允许对 Series 执行操作的 apply 方法。
def make_points(x):
return np.array(list(zip(x['A_X'], x['A_Y'])))
c = df.groupby("Time").apply(make_points)
结果是每个时间桶形状正确的点数组:
Time
1 [[5, 5], [5, 6], [6, 6], [6, 5]]
2 [[4, 5], [3, 6], [3, 5], [4, 6]]
dtype: object
最后,计算每个时间段的 Delaunay triangulation 并绘制它就足够了:
fig, axe = plt.subplots()
for p in c:
tri = Delaunay(p)
axe.triplot(*p.T, tri.simplices)
您甚至可以一次调用完成:
def make_triangulation(x):
return Delaunay(np.array(list(zip(x['A_X'], x['A_Y']))))
c = df.groupby("Time").apply(make_triangulation)
fig, axe = plt.subplots()
for tri in c:
axe.triplot(*tri.points.T, tri.simplices)
我正在尝试从 pandas df 绘制 delaunay 三角剖分。我希望按 Time
对这些点进行分组。目前,我在尝试从第一个时间点开始绘制点时遇到错误。
QhullError: QH6214 qhull input error: not enough points(2) to construct initial simplex (need 6)
While executing: | qhull d Q12 Qt Qc Qz Qbb
Options selected for Qhull 2019.1.r 2019/06/21:
run-id 768388270 delaunay Q12-allow-wide Qtriangulate Qcoplanar-keep
Qz-infinity-point Qbbound-last _pre-merge _zero-centrum Qinterior-keep
_maxoutside 0
它似乎只是将这两个数组作为一个点传递。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
df = pd.DataFrame({
'Time' : [1,1,1,1,2,2,2,2],
'A_X' : [5, 5, 6, 6, 4, 3, 3, 4],
'A_Y' : [5, 6, 6, 5, 5, 6, 5, 6],
})
fig, ax = plt.subplots(figsize = (6,6))
ax.set_xlim(0,10)
ax.set_ylim(0,10)
ax.grid(False)
points_x1 = df.groupby("Time")["A_X"].agg(list).tolist()
points_y1 = df.groupby("Time")["A_Y"].agg(list).tolist()
points = list(zip(points_x1, points_y1))
tri = Delaunay(points[0])
#plot triangulation
plt.triplot(points[:,0], points[:,1], tri.simplices)
plt.plot(points[:,0], points[:,1], 'o')
您可以利用允许对 Series 执行操作的 apply 方法。
def make_points(x):
return np.array(list(zip(x['A_X'], x['A_Y'])))
c = df.groupby("Time").apply(make_points)
结果是每个时间桶形状正确的点数组:
Time
1 [[5, 5], [5, 6], [6, 6], [6, 5]]
2 [[4, 5], [3, 6], [3, 5], [4, 6]]
dtype: object
最后,计算每个时间段的 Delaunay triangulation 并绘制它就足够了:
fig, axe = plt.subplots()
for p in c:
tri = Delaunay(p)
axe.triplot(*p.T, tri.simplices)
您甚至可以一次调用完成:
def make_triangulation(x):
return Delaunay(np.array(list(zip(x['A_X'], x['A_Y']))))
c = df.groupby("Time").apply(make_triangulation)
fig, axe = plt.subplots()
for tri in c:
axe.triplot(*tri.points.T, tri.simplices)