2017-10-02 5 views
0

Si, par exemple, j'ai les coordonnées suivantes avec les couleurs correspondantes qui représentent une grille de forme hexagonale d'hexagones:Comment tracer les coordonnées (x, y, z) sous la forme d'une grille hexagonale?

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"]] 

Comment peut-on placette en Python de sorte que les points de la parcelle conserver cette forme hexagonale? De plus, comment peut-on représenter la liste des «couleurs» sur l'hexagone.

Un peu comme ceci:

simple grille Hexagonal

Mais le regard n'a pas d'importance, juste une simple visualisation de type nuage de points suffirait, juste pour que l'on peut voir où en par rapport aux autres hexagones les couleurs mentent.

+0

Utilisez-vous l'ASCII ou souhaitez-vous utiliser le module graphique tortue? – EgMusic

+0

Que représentent les coordonnées? Je ne peux pas faire le lien entre l'image et le 'coord'. Vous voudrez probablement dire la convention utilisée ici, p. si je prends une liste '[[a, b, c], [d, e, f]]', qu'est-ce que a, b, c, d, e, f? – ImportanceOfBeingErnest

+0

@ChaseBarnes Je souhaite utiliser la solution la plus simple. ASCII suffirait. – ishido

Répondre

1

Il vous suffit de transformer les coordonnées (y, z) de vos hexagones en coordonnées cartésiennes y sur les axes matplotlib.

Je pense que la bonne façon de faire qui utilise cette formule:

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

Vous pouvez ensuite ajouter les hexagones à l'aide d'un patch matplotlib RegularPolygon, ou tracer les centres utilisant scatter.

Voici un script pour une parcelle de vos listes:

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() 

enter image description here

+0

Merci beaucoup pour cela. Est-il également possible de mettre en plus une étiquette dans chaque hexagone? Dire si j'avais une liste de 'labels = [['yes'], ['no'], ['yes'], ['no'], ['yes'], ['non'], ['non ']] '. J'ai vu que 'RegularPolygon' avait une option d'étiquettes – ishido

+1

' label' pour 'RegularPolygon' je pense est de mettre une étiquette dans une légende. Au lieu de cela, vous pouvez utiliser 'ax.text (x, y, label)'. Voir mes modifications – tom

2

est ici une fonction qui convertit un (u, v, w) uplet de coordonnées hex en coordonnées rectangulaires. Je vais l'illustrer en utilisant le module standard turtle (je n'ai pas le module matplotlib). J'ai changé les couleurs de la liste afin que nous puissions facilement vérifier que chaque point est tracé dans la bonne position.

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() 

sortie

dots on a hexagonal grid

+0

@Chase Barnes Merci d'avoir corrigé cette faute de frappe. Mais l'info sur l'installation de matplotlib est tout à fait hors de propos pour ma réponse. –

+0

Je comprends, mais juste au cas où les gens veulent savoir comment installer les modules, il est là. – EgMusic

+0

D'après ma lecture du problème, vous avez un cercle vert où vous devriez avoir un cercle cyan à [0, -1, 1], c'est-à-dire la position du bas. – cdlane

1

Voici ma tentative de terminer la solution de tortue de PM2Ring (+1), et fixe ce que je vois comme une erreur de calcul de coordonnées dans sa réponse:

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() 

enter image description here