2014-10-27 2 views
5

Что я ищу - это метод или класс, который позволяет мне отображать список шестиугольников в сетке. В идеале я мог бы использовать некоторую форму set-method для изменения цвета/штриховки/границы отдельных шестиугольников.Отображение данных в гексагональной сетке с использованием Python

Шестиугольники хранятся с использованием осевой системы координат, описанной в guide by @amitp. Но я могу легко выводить их центры как xy-координаты.

Я чувствую, что может быть решение, спрятанное где-то в hexbin или RegularPolyCollection. Но первый - метод гистограммы, и последнее кажется чрезмерно сложным благодаря масштабированию DPI.

Так кто-нибудь знает библиотеку, которая предоставляет шестиугольную сетку? Это не должно быть в matplotlib. Я также очень рад использовать искусство ASCII или переключиться на R.

+1

Почему бы вам не использовать просто холст Tkinter? –

ответ

7

Здесь идет реализация, которая позволяет вам установить гексагональную ячейку нужного цвета, а также позволить создавать пользовательские цвета границ.

Это все сделано вручную, всего 1 час, используя ваш ссылочный сайт. Возможно, вам придется адаптировать его к вашим потребностям, но, похоже, работает.

from tkinter import * 

class HexaCanvas(Canvas): 
    """ A canvas that provides a create-hexagone method """ 
    def __init__(self, master, *args, **kwargs): 
     Canvas.__init__(self, master, *args, **kwargs) 

     self.hexaSize = 20 

    def setHexaSize(self, number): 
     self.hexaSize = number 


    def create_hexagone(self, x, y, color = "black", fill="blue", color1=None, color2=None, color3=None, color4=None, color5=None, color6=None): 
     """ 
     Compute coordinates of 6 points relative to a center position. 
     Point are numbered following this schema : 

     Points in euclidiean grid: 
        6 

       5  1 
        . 
       4  2 

        3 

     Each color is applied to the side that link the vertex with same number to its following. 
     Ex : color 1 is applied on side (vertex1, vertex2) 

     Take care that tkinter ordinate axes is inverted to the standard euclidian ones. 
     Point on the screen will be horizontally mirrored. 
     Displayed points: 

        3 
       color3/  \color2  
       4  2 
      color4|  |color1 
       5  1 
       color6\  /color6 
        6 

     """ 
     size = self.hexaSize 
     Δx = (size**2 - (size/2)**2)**0.5 

     point1 = (x+Δx, y+size/2) 
     point2 = (x+Δx, y-size/2) 
     point3 = (x , y-size ) 
     point4 = (x-Δx, y-size/2) 
     point5 = (x-Δx, y+size/2) 
     point6 = (x , y+size ) 

     #this setting allow to specify a different color for each side. 
     if color1 == None: 
      color1 = color 
     if color2 == None: 
      color2 = color 
     if color3 == None: 
      color3 = color 
     if color4 == None: 
      color4 = color 
     if color5 == None: 
      color5 = color 
     if color6 == None: 
      color6 = color 

     self.create_line(point1, point2, fill=color1, width=2) 
     self.create_line(point2, point3, fill=color2, width=2) 
     self.create_line(point3, point4, fill=color3, width=2) 
     self.create_line(point4, point5, fill=color4, width=2) 
     self.create_line(point5, point6, fill=color5, width=2) 
     self.create_line(point6, point1, fill=color6, width=2) 

     if fill != None: 
      self.create_polygon(point1, point2, point3, point4, point5, point6, fill=fill) 

class HexagonalGrid(HexaCanvas): 
    """ A grid whose each cell is hexagonal """ 
    def __init__(self, master, scale, grid_width, grid_height, *args, **kwargs): 

     Δx  = (scale**2 - (scale/2.0)**2)**0.5 
     width = 2 * Δx * grid_width + Δx 
     height = 1.5 * scale * grid_height + 0.5 * scale 

     HexaCanvas.__init__(self, master, background='white', width=width, height=height, *args, **kwargs) 
     self.setHexaSize(scale) 

    def setCell(self, xCell, yCell, *args, **kwargs): 
     """ Create a content in the cell of coordinates x and y. Could specify options throught keywords : color, fill, color1, color2, color3, color4; color5, color6""" 

     #compute pixel coordinate of the center of the cell: 
     size = self.hexaSize 
     Δx = (size**2 - (size/2)**2)**0.5 

     pix_x = Δx + 2*Δx*xCell 
     if yCell%2 ==1 : 
      pix_x += Δx 

     pix_y = size + yCell*1.5*size 

     self.create_hexagone(pix_x, pix_y, *args, **kwargs) 



if __name__ == "__main__": 
    tk = Tk() 

    grid = HexagonalGrid(tk, scale = 50, grid_width=4, grid_height=4) 
    grid.grid(row=0, column=0, padx=5, pady=5) 

    def correct_quit(tk): 
     tk.destroy() 
     tk.quit() 

    quit = Button(tk, text = "Quit", command = lambda :correct_quit(tk)) 
    quit.grid(row=1, column=0) 

    grid.setCell(0,0, fill='blue') 
    grid.setCell(1,0, fill='red') 
    grid.setCell(0,1, fill='green') 
    grid.setCell(1,1, fill='yellow') 
    grid.setCell(2,0, fill='cyan') 
    grid.setCell(0,2, fill='teal') 
    grid.setCell(2,1, fill='silver') 
    grid.setCell(1,2, fill='white') 
    grid.setCell(2,2, fill='gray') 

    tk.mainloop() 

Я попытался правильно прокомментировать свой код. Если вам что-то кажется неясным, пожалуйста, не стесняйтесь спрашивать объяснения.

Удачи Артур Вайс.

NB: скрипт, выполняющийся на python 3. Рисунок немного зазубрен. Улучшение на холсте Tk может добавить анти-псевдоним, как предлагается в https://mail.python.org/pipermail/tkinter-discuss/2009-April/001904.html

+0

В Win7, 3.4.2, tk 8.6, tk.quit завершает работу tcl, но не закрывает окна tk. tk.destroy делает. –

+0

В моей Linux он работает правильно. Я знаю, что для того, чтобы выйти из него должным образом, вы должны называть методы 'tk.destroy' и' tk.quit'. Но, спасибо, чтобы указать на эту ошибку. Я отредактирую код. –

Смежные вопросы