Отображение данных в шестиугольной сетке с использованием Python

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

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

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

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


person John    schedule 27.10.2014    source источник
comment
Почему бы вам не использовать просто холст Tkinter?   -  person Arthur Vaïsse    schedule 27.10.2014


Ответы (2)


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

Это все сделано вручную, всего за 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

person Arthur Vaïsse    schedule 27.10.2014
comment
В Win7, 3.4.2, tk 8.6 tk.quit закрывает tcl, но не закрывает окна tk. tk.destroy делает. - person Terry Jan Reedy; 27.10.2014
comment
На моем линуксе работает нормально. Я знаю, что для того, чтобы выйти из него правильно, вам нужно вызвать методы tk.destroy и tk.quit. Но спасибо указать эту ошибку здесь. Я отредактирую код. - person Arthur Vaïsse; 28.10.2014

Вы можете использовать мой модуль Python hexalattice именно для этой цели - создания и построения шестиугольных сеток:

from hexalattice.hexalattice import *
hex_centers, _ = create_hex_grid(nx=5,
                                 ny=5,
                                 do_plot=True)
                                 
plt.show()    # import matplotlib.pyplot as plt

Создание этого графика: введите здесь описание изображения

Дополнительные примеры см. в этом ответе: этот ответ

person alexkaz    schedule 11.10.2020