如何使用 matplotlib PATH 绘制多边形 [英] how to use matplotlib PATH to draw polygon

查看:104
本文介绍了如何使用 matplotlib PATH 绘制多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 python 的 matplotlib PATH 模块时遇到问题我想画一个这样的闭合多边形:

I have a problem when using python's matplotlib PATH modules I want to draw a close poly like this:

但我不知道要连接的点的确切顺序,结果图像不能满足我的需要.如何在不自己确定顺序而是通过代码确定的情况下正确绘制多边形?

but I don't know exactly the sequence of the points to be connected and it turned out the result images can't meet my needs. How can I draw a polygon correctly without determining the sequence by myself but by the code?

这是我的代码:

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

我得到了这个:

推荐答案

Matplotlib 绘制路径的点,以便为它们提供补丁.如果无法控制顺序,就像问题中的情况一样,这可能会导致不希望的结果.

Matplotlib plots the points of a path in order they are given to patch. This can lead to undesired results, if there is no control over the order, like in the case from the question.

所以解决方案可能是

  • (A) 使用船体.Scipy 提供了 scipy.spatial.ConvexHull 来计算点的周长,自动按照正确的顺序计算.这在很多情况下都能提供良好的结果,参见第一行,但在其他情况下可能会失败,因为船体内部的点被忽略了.
  • (B) 对点进行排序,例如围绕中间的某个点逆时针旋转.在下面的例子中,我取了所有点的平均值.排序可以想象成一个雷达扫描仪,点按它们与 x 轴的角度进行排序.这解决了例如第二排船体的问题,但当然也可能在更复杂的形状中失败.
  • (A) use a hull. Scipy provides scipy.spatial.ConvexHull to calculate the circonference of the points, which is automatically in the correct order. This gives good results in many cases, see first row, but may fail in other cases, because points inside the hull are ignored.
  • (B) sort the points, e.g. counter clockwise around a certain point in the middle. In the example below I take the mean of all points for that. The sorting can be imagined like a radar scanner, points are sorted by their angle to the x axis. This solves e.g. the problem of the hull in the second row, but may of course also fail in more complicated shapes.

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

这篇关于如何使用 matplotlib PATH 绘制多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆