在matplotlib中绘制六边形的每个顶点和交点处的标注

lc8prwob  于 2023-08-06  发布在  其他
关注(0)|答案(3)|浏览(143)

我试图产生下面的图片“一个六边形或6角星星多边形,其中数字被放置在每个六个顶点和六个交叉点”。


的数据
下面是我的代码。我一直在找六边形的顶点来画出数字。

import matplotlib.pyplot as plt
import math

def plot_hexagram_with_numbers(side_length):
    # Calculate the coordinates for the vertices of the hexagram
    vertices = []
    mu_hexagon = 360 / 6
    for i in range(6):
        angle_rad = math.radians(i * mu_hexagon)
        x = side_length * math.cos(angle_rad)
        y = side_length * math.sin(angle_rad)
        vertices.append((x, y))

    # Create a list of triangles' vertices for the hexagram
    triangles = []
    for i in range(6):
        triangle = [vertices[i], vertices[(i + 2) % 6], vertices[(i + 4) % 6]]
        triangles.append(triangle)

    # Plot the hexagram's triangles
    for triangle in triangles:
        x_coords, y_coords = zip(*triangle)
        plt.plot(x_coords, y_coords, 'b-')

    # Add numbers at each vertex and intersection of the hexagram
    label_distance = side_length / 20  # Adjust this value as needed
    for i in range(6):
        x, y = vertices[i]
        # cant figure out how to find the edges/intersections :( 

    # Set axis equal and show the plot
    plt.axis('equal')
    plt.show()

字符串
这是上面代码生成的图像:


6rvt4ljy

6rvt4ljy1#

你的三角形不是闭合的,因此你在triangles中有两个以上的三角形(一个六边形是)。您应该构建完整的三角形,这样您甚至可以将代码泛化为任何大小的尖星(只要它是3的倍数)。
我使用shapely来计算交集:

import matplotlib.pyplot as plt
import math
from shapely import Polygon, get_coordinates

def plot_hexagram_with_numbers(side_length, nb_points=6):
    if nb_points % 3:
        raise ValueError("nb_points must be a multiple of 3")
    # Calculate the coordinates for the vertices of the hexagram
    vertices = []
    mu_hexagon = 360 / nb_points
    for i in range(nb_points):
        angle_rad = math.radians(i * mu_hexagon)
        x = side_length * math.cos(angle_rad)
        y = side_length * math.sin(angle_rad)
        vertices.append((x, y))

    # Create a list of triangles' vertices and plot triangles
    triangles = []
    nb_triangles = nb_points//3
    for i in range(nb_triangles):
        triangle = [vertices[i], vertices[i + nb_triangles], vertices[i + 2*nb_triangles], vertices[i]]
        plt.plot(*zip(*triangle), 'b-')
        triangles.append(Polygon(triangle))

    # computing intersections
    intersections = [] 
    for i in range(nb_triangles):
        for j in range(i+1, nb_triangles):
            intersections.extend(get_coordinates(triangles[i].intersection(triangles[j]))[:-1])

    # Add numbers at each vertex and intersection of the hexagram
    for i, (x,y) in enumerate(vertices + intersections, start=1):
        plt.annotate(i, (x,y))

    # Set axis equal and show the plot
    plt.axis('equal')
    plt.show()

字符串
输出(默认,nb_points=6):


的数据
输出(nb_points=9):


a2mppw5e

a2mppw5e2#

你可以考虑使用sympy。使用sympy,您可以创建两个重叠的三角形作为Polygon对象。sympy Polygon对象有一个intersection方法,如果交点存在,该方法将返回交点。参见documentation here

import matplotlib.pyplot as plt
import sympy as sp

vertices1 = [(0,0), (1,0), (0.5, 3**0.5/2)]
vertices2 = [(0,0.6), (1,0.6), (0.5, 0.6-3**0.5/2)]

sp_triangle1 = sp.Polygon(*vertices1)
sp_triangle2 = sp.Polygon(*vertices2)

intersections = sp_triangle1.intersection(sp_triangle2)
intersections = [(float(p.x), float(p.y)) for p in intersections]

all_points = intersections + vertices1 + vertices2
print(all_points)

triangle1 = plt.Polygon(vertices1, fill=False)
triangle2 = plt.Polygon(vertices2, fill=False)

fig, ax = plt.subplots()
ax.add_patch(triangle1)
ax.add_patch(triangle2)
for n, point in enumerate(all_points, 1):
    ax.annotate(n, point)
ax.set_xlim(-0.25, 1.25)
ax.set_ylim(-0.4, 1)
ax.set_aspect(1)
fig.show()

字符串


的数据

ghhaqwfi

ghhaqwfi3#

注意,我使用了问题中的示例图中使用的标签的奇数序列,以防精确序列是作业的要求之一。


的数据
在下面的代码中,标签的点和锚点使用简单的三角函数放置在不同半径的圆上。
在绘图之前有一些准备工作,因为我想尽可能地对齐所有标签,并且我想尊重顶点和交点的奇数编号。

import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['figure.constrained_layout.use'] = True
plt.rcParams['figure.dpi'] = 150

R = 100
angles = np.linspace(0, 7, 8)*np.pi/3+np.pi/2
x = np.cos(angles)*R ; y = np.sin(angles)*R

l, c, r = 'left center right'.split()
b, c, t = 'bottom center top'.split()
positions = [
    {'ha':c, 'va':b}, {'ha':r, 'va':t}, {'ha':r, 'va':b}, # left vertices
    {'ha':c, 'va':t}, {'ha':l, 'va':b}, {'ha':l, 'va':t}, # right vertices
    {'ha':l, 'va':t}, {'ha':l, 'va':c}, {'ha':l, 'va':b}, # left intersections
    {'ha':r, 'va':b}, {'ha':r, 'va':c}, {'ha':r, 'va':t}, # right intersections
    ]
labels = '6 5 4 10 8 3 7 9 2 12 1 11'.split()

ax = plt.subplot()
ax.set_aspect(1)

plt.plot(x[0::2], y[0::2], color='k', lw=3, solid_capstyle='round')
plt.plot(x[1::2], y[1::2], color='k', lw=3, solid_capstyle='round')

n = 0
# place labels of vertices a little bit outside
R1 = R*1.07
x = np.cos(angles)*R1 ; y = np.sin(angles)*R1
for X, Y in zip(x[:6], y[:6]):
    ax.text(X, Y, labels[n], **positions[n], fontsize='large')
    n += 1

# place the labels for the intersections at the distance of 
# each triangle side from centre, i.e., d = 0.5 R
R2 = R*0.50
x = np.cos(angles+np.pi/6)*R2 ; y = np.sin(angles+np.pi/6)*R2
for X, Y in zip(x[:6], y[:6]):
    ax.text(X, Y, labels[n], **positions[n], fontsize='large')
    n += 1

# no distractions    
ax.set_frame_on(0)
ax.set_xticks([])
ax.set_yticks([])

plt.show()

字符串

相关问题