如何绘制六边形网格形状的 (x,y,z) 坐标?

How to plot (x,y,z) coordinates in the shape of a hexagonal grid?

如果例如我有以下坐标对应的颜色 代表六边形的六边形网格:

coord = [[0,0,0],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0],[1,0,-1]]
colors = [["Green"],["Blue"],["Green"],["Green"],["Red"],["Green"],["Green"]]

如何在 Python 中绘制此图,使图上的点保持六边形?另外如何在六边形上表示 'colors' 列表。

有点像这样:

简单的六角网格

但外观并不重要,只需一个简单的散点图类型可视化就足够了,这样人们就可以看到颜色相对于其他六边形的位置。

您只需将六边形的 (y, z) 坐标转换为 matplotlib 轴上的 y 笛卡尔坐标。

我认为正确的方法是使用这个公式:

y_cartesian = (2 / 3) * sin(60) * (y_hex - z_hex)

然后您可以使用 matplotlib 添加六边形 RegularPolygon patch, or plot the centres using scatter

这是一个脚本,可以根据您的列表绘制图表:

import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon
import numpy as np

coord = [[0,0,0],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0],[1,0,-1]]
colors = [["Green"],["Blue"],["Green"],["Green"],["Red"],["Green"],["Green"]]
labels = [['yes'],['no'],['yes'],['no'],['yes'],['no'],['no']]

# Horizontal cartesian coords
hcoord = [c[0] for c in coord]

# Vertical cartersian coords
vcoord = [2. * np.sin(np.radians(60)) * (c[1] - c[2]) /3. for c in coord]

fig, ax = plt.subplots(1)
ax.set_aspect('equal')

# Add some coloured hexagons
for x, y, c, l in zip(hcoord, vcoord, colors, labels):
    color = c[0].lower()  # matplotlib understands lower case words for colours
    hex = RegularPolygon((x, y), numVertices=6, radius=2. / 3., 
                         orientation=np.radians(30), 
                         facecolor=color, alpha=0.2, edgecolor='k')
    ax.add_patch(hex)
    # Also add a text label
    ax.text(x, y+0.2, l[0], ha='center', va='center', size=20)

# Also add scatter points in hexagon centres
ax.scatter(hcoord, vcoord, c=[c[0].lower() for c in colors], alpha=0.5)

plt.show()

这是一个将十六进制坐标的 (u, v, w) 元组转换为直角坐标的函数。我将使用标准 turtle 模块(我没有 matplotlib 模块)来说明它。我更改了列表中的颜色,以便我们可以轻松检查每个点是否绘制在正确的位置。

import turtle
from math import sqrt

root3 = sqrt(3)

# the scale used for drawing
side = 50

# Convert hex coordinates to rectangular
def hex_to_rect(coord):
    u, v, w = coord
    x = u - v/2 - w/2
    y = (v - w) * root3 / 2
    return x * side, y * side

# Initialize the turtle
t = turtle.Turtle()
t.speed(0)
t.hideturtle()
t.up()

coords = [[0,0,0], [0,1,-1], [-1,1,0], [-1,0,1], [0,-1,1], [1,-1,0], [1,0,-1]]
colors = ['black', 'red', 'orange', 'green', 'cyan', 'blue', 'magenta']

#Plot the points
for hexcoord, color in zip(coords, colors):
    xy = hex_to_rect(hexcoord)
    t.goto(xy)
    t.dot(15, color)

# Wait for the user to close the window
turtle.done()

输出

下面是我尝试完成 PM2Ring 基于 turtle 的解决方案 (+1) 以及修复我在他的回答中看到的坐标计算错误的尝试:

from math import sqrt
from turtle import Turtle, Screen

ROOT3_OVER_2 = sqrt(3) / 2

FONT_SIZE = 18
FONT = ('Arial', FONT_SIZE, 'normal')

SIDE = 50  # the scale used for drawing

# Convert hex coordinates to rectangular
def hex_to_rect(coord):
    v, u, w = coord
    x = -u / 2 + v - w / 2
    y = (u - w) * ROOT3_OVER_2
    return x * SIDE, y * SIDE

def hexagon(turtle, radius, color, label):
    clone = turtle.clone()  # so we don't affect turtle's state
    xpos, ypos = clone.position()
    clone.setposition(xpos - radius / 2, ypos - ROOT3_OVER_2 * radius)
    clone.setheading(-30)
    clone.color('black', color)
    clone.pendown()
    clone.begin_fill()
    clone.circle(radius, steps=6)
    clone.end_fill()
    clone.penup()
    clone.setposition(xpos, ypos - FONT_SIZE / 2)
    clone.write(label, align="center", font=FONT)

# Initialize the turtle
tortoise = Turtle(visible=False)
tortoise.speed('fastest')
tortoise.penup()

coords = [[0, 0, 0], [0, 1, -1], [-1, 1, 0], [-1, 0, 1], [0, -1, 1], [1, -1, 0], [1, 0, -1]]
colors = ["Green", "Blue", "Green", "Green", "Red", "Green", "Green"]
labels = ['yes', 'no', 'yes', 'no', 'yes', 'no', 'no']

# Plot the points
for hexcoord, color, label in zip(coords, colors, labels):
    tortoise.goto(hex_to_rect(hexcoord))
    hexagon(tortoise, SIDE, color, label)

# Wait for the user to close the window
screen = Screen()
screen.exitonclick()