Python 如何(整齐地)在凸面外壳外部获得注释?

Python 如何(整齐地)在凸面外壳外部获得注释?,python,python-3.x,annotations,convex-hull,Python,Python 3.x,Annotations,Convex Hull,我已经开发了一些代码来自动生成等边n维多边形: # Create equilateral n-dimensional polygon def polygon(side, radius=1, rotation=0, translation=None): import math vertex = 2 * math.pi / side points = [ (math.sin(vertex * i + rotation) * radius,

我已经开发了一些代码来自动生成等边n维多边形:

# Create equilateral n-dimensional polygon

def polygon(side, radius=1, rotation=0, translation=None):
    import math
    vertex = 2 * math.pi / side

    points = [
        (math.sin(vertex * i + rotation) * radius,
         math.cos(vertex * i + rotation) * radius)
         for i in range(side)]

    if translation:
       points = [[sum(pair) for pair in zip(point, translation)]
                  for point in points]
return np.array(points)
现在,我想把标签整齐地放在这个n维多边形的角上。在下面的示例中,我创建了一个半径为10的六边形,以(3,3)为中心

导入matplotlib.pyplot作为plt
pol=多边形(7,10,0,3,3])
外壳=凸形外壳(pol)
标签=['A','B','C','D','E','F','G','H','I','J','K','L','M',',
“N”、“O”、“P”、“Q”、“R”、“S”、“T”、“U”、“V”、“W”、“X”、“Y”、“Z”]
图=plt.图(figsize=(4,4),dpi=100)
对于hull.simplices中的单工:
plt.图(pol[simplex,0],pol[simplex,1],'k-')
plt.图(pol[:,0],pol[:,1],'gs',ms=10)
如果标签不是“无”:
对于i,枚举中的标签(标签):

如果我首先,让我们看看n维正多边形的特例

为此,您可以将注释放在稍微大一点的多边形的顶点上(我使用了原始半径的1.2倍)

下面是完整的代码和结果

import matplotlib.pyplot as plt
from scipy.spatial import ConvexHull

r = 10  # radius
center = [3, 3]
pol = polygon(7, r, 0, center)
pol2 = polygon(7, 1.2*r, 0, center)  # for annotations
hull = ConvexHull(pol)
labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', "L", 'M', 
          'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

fig = plt.figure(figsize=(4, 4), dpi=100)
for simplex in hull.simplices:
    plt.plot(pol[simplex,0], pol[simplex,1], 'k-')
plt.plot(pol[:,0], pol[:,1], 'gs', ms=10)
if labels is not None:
    for i, label in enumerate(labels):
        if i <= len(pol)-1:
            plt.annotate(label, xy=(pol2[i,0], pol2[i,1]), xytext=(0, 0), 
                         textcoords='offset points', ha="center", va="center")
plt.xlim(center[0] - 1.5*r, center[0] + 1.5*r)
plt.ylim(center[1] - 1.5*r, center[1] + 1.5*r)
plt.axis('off')
plt.show()
  • 从M到S画一条线,取线上的新点M_ext,使S与M和M_ext等距,但M_ext在另一边。我们知道,在这种情况下,M_ext绝对是

    M_ext = pol[S] + (pol[S] - M)
    
    可以对其进行规范化,以便注释与单纯形的距离相同(例如,使用numpy.linalg.norm)。在我的代码中,我还乘以一个常数因子,这样文本就不会与顶点重叠

    M_ext = pol[S] + (pol[S] - M) / np.linalg.norm(pol[S]-M)
    
  • 同样完整的代码和结果如下:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.spatial import ConvexHull
    
    r = 10  # radius
    center = [3, 3]
    pol = polygon(7, r, 0, center)
    pol2 = polygon(7, 1.2*r, 0, center)  # for annotations
    hull = ConvexHull(pol)
    labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', "L", 'M', 
              'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    
    fig = plt.figure(figsize=(4, 4), dpi=100)
    for simplex in hull.simplices:
        plt.plot(pol[simplex,0], pol[simplex,1], 'k-')
    plt.plot(pol[:,0], pol[:,1], 'gs', ms=10)
    if labels is not None:
        for i, label in enumerate(labels):
            if i <= len(pol)-1:
                S = i
                (N_1, N_2) = hull.neighbors[S]
                M = (pol[N_1] + pol[N_2]) / 2
                M_ext = pol[S] + (pol[S] - M) / np.linalg.norm(pol[S] - M) * 0.2*r
                plt.annotate(label, xy=M_ext, xytext=(0, 0), 
    textcoords='offset points', ha="center", va="center")
    plt.xlim(center[0] - 1.5*r, center[0] + 1.5*r)
    plt.ylim(center[1] - 1.5*r, center[1] + 1.5*r)
    plt.axis('off')
    plt.show()
    
    导入matplotlib.pyplot作为plt
    将numpy作为np导入
    从scipy.spatial导入convxhull
    r=10#半径
    中间=[3,3]
    pol=多边形(7,r,0,中心)
    pol2=多边形(7,1.2*r,0,中心)#用于注释
    外壳=凸形外壳(pol)
    标签=['A','B','C','D','E','F','G','H','I','J','K','L','M',',
    “N”、“O”、“P”、“Q”、“R”、“S”、“T”、“U”、“V”、“W”、“X”、“Y”、“Z”]
    图=plt.图(figsize=(4,4),dpi=100)
    对于hull.simplices中的单工:
    plt.图(pol[simplex,0],pol[simplex,1],'k-')
    plt.图(pol[:,0],pol[:,1],'gs',ms=10)
    如果标签不是“无”:
    对于i,枚举中的标签(标签):
    
    如果我首先,让我们看看n维正多边形的特例

    为此,您可以将注释放在稍微大一点的多边形的顶点上(我使用了原始半径的1.2倍)

    下面是完整的代码和结果

    import matplotlib.pyplot as plt
    from scipy.spatial import ConvexHull
    
    r = 10  # radius
    center = [3, 3]
    pol = polygon(7, r, 0, center)
    pol2 = polygon(7, 1.2*r, 0, center)  # for annotations
    hull = ConvexHull(pol)
    labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', "L", 'M', 
              'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    
    fig = plt.figure(figsize=(4, 4), dpi=100)
    for simplex in hull.simplices:
        plt.plot(pol[simplex,0], pol[simplex,1], 'k-')
    plt.plot(pol[:,0], pol[:,1], 'gs', ms=10)
    if labels is not None:
        for i, label in enumerate(labels):
            if i <= len(pol)-1:
                plt.annotate(label, xy=(pol2[i,0], pol2[i,1]), xytext=(0, 0), 
                             textcoords='offset points', ha="center", va="center")
    plt.xlim(center[0] - 1.5*r, center[0] + 1.5*r)
    plt.ylim(center[1] - 1.5*r, center[1] + 1.5*r)
    plt.axis('off')
    plt.show()
    
  • 从M到S画一条线,取线上的新点M_ext,使S与M和M_ext等距,但M_ext在另一边。我们知道,在这种情况下,M_ext绝对是

    M_ext = pol[S] + (pol[S] - M)
    
    可以对其进行规范化,以便注释与单纯形的距离相同(例如,使用numpy.linalg.norm)。在我的代码中,我还乘以一个常数因子,这样文本就不会与顶点重叠

    M_ext = pol[S] + (pol[S] - M) / np.linalg.norm(pol[S]-M)
    
  • 同样完整的代码和结果如下:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.spatial import ConvexHull
    
    r = 10  # radius
    center = [3, 3]
    pol = polygon(7, r, 0, center)
    pol2 = polygon(7, 1.2*r, 0, center)  # for annotations
    hull = ConvexHull(pol)
    labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', "L", 'M', 
              'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    
    fig = plt.figure(figsize=(4, 4), dpi=100)
    for simplex in hull.simplices:
        plt.plot(pol[simplex,0], pol[simplex,1], 'k-')
    plt.plot(pol[:,0], pol[:,1], 'gs', ms=10)
    if labels is not None:
        for i, label in enumerate(labels):
            if i <= len(pol)-1:
                S = i
                (N_1, N_2) = hull.neighbors[S]
                M = (pol[N_1] + pol[N_2]) / 2
                M_ext = pol[S] + (pol[S] - M) / np.linalg.norm(pol[S] - M) * 0.2*r
                plt.annotate(label, xy=M_ext, xytext=(0, 0), 
    textcoords='offset points', ha="center", va="center")
    plt.xlim(center[0] - 1.5*r, center[0] + 1.5*r)
    plt.ylim(center[1] - 1.5*r, center[1] + 1.5*r)
    plt.axis('off')
    plt.show()
    
    导入matplotlib.pyplot作为plt
    将numpy作为np导入
    从scipy.spatial导入convxhull
    r=10#半径
    中间=[3,3]
    pol=多边形(7,r,0,中心)
    pol2=多边形(7,1.2*r,0,中心)#用于注释
    外壳=凸形外壳(pol)
    标签=['A','B','C','D','E','F','G','H','I','J','K','L','M',',
    “N”、“O”、“P”、“Q”、“R”、“S”、“T”、“U”、“V”、“W”、“X”、“Y”、“Z”]
    图=plt.图(figsize=(4,4),dpi=100)
    对于hull.simplices中的单工:
    plt.图(pol[simplex,0],pol[simplex,1],'k-')
    plt.图(pol[:,0],pol[:,1],'gs',ms=10)
    如果标签不是“无”:
    对于i,枚举中的标签(标签):
    
    如果我非常感谢您的快速响应、代码和理论推理!您的代码几乎可以正常工作,仅当n>8时,第二个多边形上的标签超出图形限制。根据你的解决方案,我会自己尝试调整。等等,我执行了一些错误的操作。我的错。现在效果很好!很高兴这有帮助!非常感谢您的快速响应、代码和理论推理!您的代码几乎可以正常工作,仅当n>8时,第二个多边形上的标签超出图形限制。根据你的解决方案,我会自己尝试调整。等等,我执行了一些错误的操作。我的错。现在效果很好!很高兴这有帮助!