动画 Delaunay 三角剖分 - Python
Animate Delaunay triangulation - Python
是否可以使用 Matplotlib 为 Delaunay 三角剖分制作动画?下面绘制按 Item
和 Time
分组的顶点。我希望为它制作动画而不是绘制每次迭代。
我也可能有时间点不包含足够的点来充分绘制三角测量。对于这些时间点,我只是希望能度过那段时间,然后进入下一个时间点。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import matplotlib.animation as animation
import matplotlib.gridspec as gridspec
# data frame containing time points without adequate points (3)
#df = pd.DataFrame({
# 'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3],
# 'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B','A','B'],
# 'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5, 1, 2],
# 'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5, 6],
# })
fig = plt.figure(figsize = (8,10))
grid = gridspec.GridSpec(1, 2)
gridsize = (1, 2)
ax = plt.subplot2grid(gridsize, (0, 0))
ax2 = plt.subplot2grid(gridsize, (0, 1))
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
for p in A_points:
tri = Delaunay(p)
a_del = ax.triplot(*p.T, tri.simplices, color = 'orange')
for p in B_points:
tri = Delaunay(p)
b_del = ax.triplot(*p.T, tri.simplices, color = 'purple')
#def animate(i) :
#a_del.set_data#()
#b_del.set_data#()
#ani = animation.FuncAnimation(fig, animate, blit = False)
编辑 2:
我希望在绘制其他对象时保持图形和轴稳定。因此,我只想动画化三角剖分的变化。
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2],
'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B'],
'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5],
'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4],
})
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
A_points = A_points.values
B_points = B_points.values
fig = plt.figure(figsize = (8,10))
grid = gridspec.GridSpec(2, 2)
gridsize = (2, 2)
ax = plt.subplot2grid(gridsize, (0, 0), colspan = 2)
ax.set_xlim(0, 20)
ax.set_ylim(0, 20)
ax2 = plt.subplot2grid(gridsize, (1, 0))
ax3 = plt.subplot2grid(gridsize, (1, 1))
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(12,8))
def one_frame(i):
ax[0].clear();ax[1].clear()
try:
a_points = np.unique(A_points[i],axis=0)
tri_a = Delaunay(a_points)
ax[0].triplot(*a_points.T, tri_a.simplices, color = 'orange')
except Exception:
pass
try:
b_points = np.unique(B_points[i],axis=0)
tri_b = Delaunay(b_points)
ax[1].triplot(*b_points.T, tri_b.simplices, color = 'purple')
except Exception:
pass
ani = animation.FuncAnimation(fig,one_frame, blit = False)
有可能,伙计,试试这个代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import matplotlib.animation as animation
# data frame containing time points without adequate points (3)
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3],
'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B','A','B'],
'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5, 1, 2],
'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5, 6],
})
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
A_points = A_points.values
B_points = B_points.values
fig, ax = plt.subplots(nrows=1,ncols=2,figsize=(12,8))
def one_frame(i):
ax[0].clear();ax[1].clear()
try:
a_points = np.unique(A_points[i],axis=0)
tri_a = Delaunay(a_points)
ax[0].triplot(*a_points.T, tri_a.simplices, color = 'orange')
except Exception as e:
print("frame %i, point a can't print because of \n%s" % (i,e))
try:
b_points = np.unique(B_points[i],axis=0)
tri_b = Delaunay(b_points)
ax[1].triplot(*b_points.T, tri_b.simplices, color = 'purple')
except Exception as e:
print("frame %i, point b can't print because of \n%s" % (i,e))
ani = animation.FuncAnimation(fig,one_frame,range(3), blit = False)
ani.save('test.gif', writer='pillow', fps=1)
输出为
更新
可以保留fig
和ax
,思路是通过
for item in triangles_a:
try:
item.remove()
except Exception as e:
continue
for item in triangles_b:
try:
item.remove()
except Exception as e:
continue
删除三角形不会影响fig
和ax
的其他部分。 例如,在下面的例子中,两个圆在动画过程中不会受到影响。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import matplotlib.animation as animation
# data frame containing time points without adequate points (3)
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3],
'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B','A','B'],
'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5, 1, 2],
'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5, 6],
})
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
A_points = A_points.values
B_points = B_points.values
fig = plt.figure(figsize = (8,10))
grid = gridspec.GridSpec(2, 2)
gridsize = (2, 2)
ax0 = plt.subplot2grid(gridsize, (0, 0), colspan = 2)
ax1 = plt.subplot2grid(gridsize, (1, 0), colspan = 1)
ax2 = plt.subplot2grid(gridsize, (1, 1), colspan = 1)
ax1.set_xlim(0,8);ax1.set_ylim(0,8)
ax2.set_xlim(0,8);ax2.set_ylim(0,8)
# things that won't be affected
circle_0 = plt.Circle((4,4), 2, color='violet',fill=False)
ax1.add_artist(circle_0)
circle_1 = plt.Circle((5,4), 2, color='deepskyblue',fill=False)
ax2.add_artist(circle_1)
triangles_a,triangles_b = [],[]
def one_frame(i):
global triangles_a,triangles_b
for item in triangles_a:
try:
item.remove()
except Exception as e:
continue
for item in triangles_b:
try:
item.remove()
except Exception as e:
continue
try:
a_points = np.unique(A_points[i],axis=0)
tri_a = Delaunay(a_points)
obj_a = ax1.triplot(*a_points.T, tri_a.simplices, color = 'orange')
triangles_a.extend(obj_a)
except Exception as e:
print("frame %i, point a can't print because of \n%s" % (i,e))
try:
b_points = np.unique(B_points[i],axis=0)
tri_b = Delaunay(b_points)
obj_b = ax2.triplot(*b_points.T, tri_b.simplices, color = 'purple')
triangles_b.extend(obj_b)
except Exception as e:
print("frame %i, point b can't print because of \n%s" % (i,e))
ani = animation.FuncAnimation(fig,one_frame,range(3), blit = False)
ani.save('test.gif', writer='pillow', fps=1)
输出
是否可以使用 Matplotlib 为 Delaunay 三角剖分制作动画?下面绘制按 Item
和 Time
分组的顶点。我希望为它制作动画而不是绘制每次迭代。
我也可能有时间点不包含足够的点来充分绘制三角测量。对于这些时间点,我只是希望能度过那段时间,然后进入下一个时间点。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import matplotlib.animation as animation
import matplotlib.gridspec as gridspec
# data frame containing time points without adequate points (3)
#df = pd.DataFrame({
# 'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3],
# 'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B','A','B'],
# 'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5, 1, 2],
# 'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5, 6],
# })
fig = plt.figure(figsize = (8,10))
grid = gridspec.GridSpec(1, 2)
gridsize = (1, 2)
ax = plt.subplot2grid(gridsize, (0, 0))
ax2 = plt.subplot2grid(gridsize, (0, 1))
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
for p in A_points:
tri = Delaunay(p)
a_del = ax.triplot(*p.T, tri.simplices, color = 'orange')
for p in B_points:
tri = Delaunay(p)
b_del = ax.triplot(*p.T, tri.simplices, color = 'purple')
#def animate(i) :
#a_del.set_data#()
#b_del.set_data#()
#ani = animation.FuncAnimation(fig, animate, blit = False)
编辑 2:
我希望在绘制其他对象时保持图形和轴稳定。因此,我只想动画化三角剖分的变化。
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2],
'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B'],
'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5],
'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4],
})
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
A_points = A_points.values
B_points = B_points.values
fig = plt.figure(figsize = (8,10))
grid = gridspec.GridSpec(2, 2)
gridsize = (2, 2)
ax = plt.subplot2grid(gridsize, (0, 0), colspan = 2)
ax.set_xlim(0, 20)
ax.set_ylim(0, 20)
ax2 = plt.subplot2grid(gridsize, (1, 0))
ax3 = plt.subplot2grid(gridsize, (1, 1))
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(12,8))
def one_frame(i):
ax[0].clear();ax[1].clear()
try:
a_points = np.unique(A_points[i],axis=0)
tri_a = Delaunay(a_points)
ax[0].triplot(*a_points.T, tri_a.simplices, color = 'orange')
except Exception:
pass
try:
b_points = np.unique(B_points[i],axis=0)
tri_b = Delaunay(b_points)
ax[1].triplot(*b_points.T, tri_b.simplices, color = 'purple')
except Exception:
pass
ani = animation.FuncAnimation(fig,one_frame, blit = False)
有可能,伙计,试试这个代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import matplotlib.animation as animation
# data frame containing time points without adequate points (3)
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3],
'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B','A','B'],
'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5, 1, 2],
'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5, 6],
})
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
A_points = A_points.values
B_points = B_points.values
fig, ax = plt.subplots(nrows=1,ncols=2,figsize=(12,8))
def one_frame(i):
ax[0].clear();ax[1].clear()
try:
a_points = np.unique(A_points[i],axis=0)
tri_a = Delaunay(a_points)
ax[0].triplot(*a_points.T, tri_a.simplices, color = 'orange')
except Exception as e:
print("frame %i, point a can't print because of \n%s" % (i,e))
try:
b_points = np.unique(B_points[i],axis=0)
tri_b = Delaunay(b_points)
ax[1].triplot(*b_points.T, tri_b.simplices, color = 'purple')
except Exception as e:
print("frame %i, point b can't print because of \n%s" % (i,e))
ani = animation.FuncAnimation(fig,one_frame,range(3), blit = False)
ani.save('test.gif', writer='pillow', fps=1)
输出为
更新
可以保留fig
和ax
,思路是通过
for item in triangles_a:
try:
item.remove()
except Exception as e:
continue
for item in triangles_b:
try:
item.remove()
except Exception as e:
continue
删除三角形不会影响fig
和ax
的其他部分。 例如,在下面的例子中,两个圆在动画过程中不会受到影响。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
import matplotlib.animation as animation
# data frame containing time points without adequate points (3)
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3],
'Item' : ['A','B','A','B','A','B','A','A','B','A','B','A','B','B','A','B'],
'X' : [5, 5, 6, 6, 4, 3, 3, 4, 4, 3, 2, 5, 4, 5, 1, 2],
'Y' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5, 6],
})
A_coord = df.loc[df['Item'] == 'A']
B_coord = df.loc[df['Item'] == 'B']
def make_points(x):
return np.array(list(zip(x['X'], x['Y'])))
A_points = A_coord.groupby(['Time']).apply(make_points)
B_points = B_coord.groupby(['Time']).apply(make_points)
A_points = A_points.values
B_points = B_points.values
fig = plt.figure(figsize = (8,10))
grid = gridspec.GridSpec(2, 2)
gridsize = (2, 2)
ax0 = plt.subplot2grid(gridsize, (0, 0), colspan = 2)
ax1 = plt.subplot2grid(gridsize, (1, 0), colspan = 1)
ax2 = plt.subplot2grid(gridsize, (1, 1), colspan = 1)
ax1.set_xlim(0,8);ax1.set_ylim(0,8)
ax2.set_xlim(0,8);ax2.set_ylim(0,8)
# things that won't be affected
circle_0 = plt.Circle((4,4), 2, color='violet',fill=False)
ax1.add_artist(circle_0)
circle_1 = plt.Circle((5,4), 2, color='deepskyblue',fill=False)
ax2.add_artist(circle_1)
triangles_a,triangles_b = [],[]
def one_frame(i):
global triangles_a,triangles_b
for item in triangles_a:
try:
item.remove()
except Exception as e:
continue
for item in triangles_b:
try:
item.remove()
except Exception as e:
continue
try:
a_points = np.unique(A_points[i],axis=0)
tri_a = Delaunay(a_points)
obj_a = ax1.triplot(*a_points.T, tri_a.simplices, color = 'orange')
triangles_a.extend(obj_a)
except Exception as e:
print("frame %i, point a can't print because of \n%s" % (i,e))
try:
b_points = np.unique(B_points[i],axis=0)
tri_b = Delaunay(b_points)
obj_b = ax2.triplot(*b_points.T, tri_b.simplices, color = 'purple')
triangles_b.extend(obj_b)
except Exception as e:
print("frame %i, point b can't print because of \n%s" % (i,e))
ani = animation.FuncAnimation(fig,one_frame,range(3), blit = False)
ani.save('test.gif', writer='pillow', fps=1)
输出