如何绘制六边形网格形状的 (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()
如果例如我有以下坐标对应的颜色 代表六边形的六边形网格:
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()