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

查看:1599
本文介绍了如何使用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天全站免登陆