2017-05-17 51 views
2

我使用Python的matplotlib路徑模塊 時,有一個問題我想提請密切的多是這樣的:如何使用matplotlib PATH繪製多邊形

enter image description here

,但我不知道到底該序列的要連接的點,結果圖像不能滿足我的需要。我怎樣才能正確繪製一個多邊形,而不用自己而是通過代碼來確定序列?

這裏是我的代碼:

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() 

,我得到這個:

enter image description here

+0

聽起來像是你想有一個凸包。查看https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.ConvexHull.html –

回答

3

Matplotlib繪製路徑的點,以便給他們打補丁。 這可能會導致意外的結果,如果在訂單無法控制,就像從問題的情況下。

所以解決方案可以是

  • (A)使用船體。 SciPy的提供scipy.spatial.ConvexHull來計算點的circonference,從而自動處於正確順序。在許多情況下,這會給出好的結果,請參閱第一行,但在其他情況下可能會失敗,因爲船體內部的點會被忽略。
  • (B)排序的點以外,例如在中間的某個點逆時針旋轉。在下面的例子中,我將所有點的意思表示爲。分類可以像雷達掃描儀那樣想象,點根據它們與x軸的角度排序。這解決了例如第二排船體的問題,但當然也可能以更復雜的形狀失效。

enter image description here

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()