使用python的matplotlib PATH模块时遇到问题 我想像这样绘制一个密集的聚合物:
但我不确切知道要连接的点的顺序,结果结果图像无法满足我的需要。如何在不自行确定序列的情况下正确绘制多边形,而不是通过代码?
这是我的代码:
import matplotlib
import matplotlib.pyplot as plt
import pandas
from matplotlib.path import Path
import matplotlib.patches as patches
#read data
info = pandas.read_csv('/Users/james/Desktop/nba.csv')
info.columns = ['number', 'team_id', 'player_id', 'x_loc', 'y_loc',
'radius', 'moment', 'game_clock', 'shot_clock', 'player_name',
'player_jersey']
#first_team_info
x_1 = info.x_loc[1:6]
y_1 = info.y_loc[1:6]
matrix= [x_1,y_1]
z_1 = list(zip(*matrix))
z_1.append(z_1[4])
n_1 = info.player_jersey[1:6]
verts = z_1
codes = [Path.MOVETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.CLOSEPOLY,
]
path = Path(verts, codes)
fig = plt.figure()
ax = fig.add_subplot(111)
patch = patches.PathPatch(path, facecolor='orange', lw=2)
ax.add_patch(patch)
ax.set_xlim(0, 100)
ax.set_ylim(0, 55)
plt.show()
我得到了这个:
答案 0 :(得分:4)
Matplotlib绘制路径的点,以便它们被赋予补丁。 如果无法控制订单,这可能会导致意外结果,例如问题的情况。
所以解决方案可能是
scipy.spatial.ConvexHull
来计算点的圆周,这将自动按正确的顺序排列。在许多情况下,这会产生良好的结果,请参见第一行,但在其他情况下可能会失败,因为船体内的点会被忽略。import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import ConvexHull
p = [(1,1), (2,1.6), (0.8,2.7), (1.7,3.2)]
p2 = [(0.7,1.3),(2,0.9),(1.4,1.5),(1.9,3.1),(0.6,2.5),(1.4,2.3)]
def convexhull(p):
p = np.array(p)
hull = ConvexHull(p)
return p[hull.vertices,:]
def ccw_sort(p):
p = np.array(p)
mean = np.mean(p,axis=0)
d = p-mean
s = np.arctan2(d[:,0], d[:,1])
return p[np.argsort(s),:]
fig, axes = plt.subplots(ncols=3, nrows=2, sharex=True, sharey=True)
axes[0,0].set_title("original")
poly = plt.Polygon(p, ec="k")
axes[0,0].add_patch(poly)
poly2 = plt.Polygon(p2, ec="k")
axes[1,0].add_patch(poly2)
axes[0,1].set_title("convex hull")
poly = plt.Polygon(convexhull(p), ec="k")
axes[0,1].add_patch(poly)
poly2 = plt.Polygon(convexhull(p2), ec="k")
axes[1,1].add_patch(poly2)
axes[0,2].set_title("ccw sort")
poly = plt.Polygon(ccw_sort(p), ec="k")
axes[0,2].add_patch(poly)
poly2 = plt.Polygon(ccw_sort(p2), ec="k")
axes[1,2].add_patch(poly2)
for ax in axes[0,:]:
x,y = zip(*p)
ax.scatter(x,y, color="k", alpha=0.6, zorder=3)
for ax in axes[1,:]:
x,y = zip(*p2)
ax.scatter(x,y, color="k", alpha=0.6, zorder=3)
axes[0,0].margins(0.1)
axes[0,0].relim()
axes[0,0].autoscale_view()
plt.show()