parameters: (group_counts, margin=2)
return_statement: return boxes
docstring: @arg [int] group_counts: counts of the number of images in each
      distinct level within the metadata's caetgories
    @kwarg int margin: space between boxes in the 2D layout
    @returns [Box] an array of Box() objects; one per level in `group_counts`
function: def get_categorical_boxes(group_counts, margin=2):
    '''
    @arg [int] group_counts: counts of the number of images in each
      distinct level within the metadata's caetgories
    @kwarg int margin: space between boxes in the 2D layout
    @returns [Box] an array of Box() objects; one per level in `group_counts`
    '''
    group_counts = sorted(group_counts, reverse=True)
    boxes = []
    for i in group_counts:
      w = h = math.ceil(i**(1/2))
      boxes.append(Box(i, w, h, None, None))
    # find the position along x axis where we want to create a break
    wrap = math.floor(sum([i.cells for i in boxes])**(1/2)) - (2 * margin)
    # find the valid positions on the y axis
    y = margin
    y_spots = []
    for i in boxes:
      if (y + i.h + margin) <= wrap:
        y_spots.append(y)
        y += i.h + margin
      else:
        y_spots.append(y)
        break
    # get a list of lists where sublists contain elements at the same y position
    y_spot_index = 0
    for i in boxes:
      # find the y position
      y = y_spots[y_spot_index]
      # find members with this y position
      row_members = [j.x + j.w for j in boxes if j.y == y]
      # assign the y position
      i.y = y
      y_spot_index = (y_spot_index + 1) % len(y_spots)
      # assign the x position
      i.x = max(row_members) + margin if row_members else margin
    return boxes
function_tokens: def get_categorical_boxes ( group_counts , margin = 2 ) : group_counts = sorted ( group_counts , reverse = True ) boxes = [ ] for i in group_counts : w = h = math . ceil ( i ** ( 1 / 2 ) ) boxes . append ( Box ( i , w , h , None , None ) ) # find the position along x axis where we want to create a break wrap = math . floor ( sum ( [ i . cells for i in boxes ] ) ** ( 1 / 2 ) ) - ( 2 * margin ) # find the valid positions on the y axis y = margin y_spots = [ ] for i in boxes : if ( y + i . h + margin ) <= wrap : y_spots . append ( y ) y += i . h + margin else : y_spots . append ( y ) break # get a list of lists where sublists contain elements at the same y position y_spot_index = 0 for i in boxes : # find the y position y = y_spots [ y_spot_index ] # find members with this y position row_members = [ j . x + j . w for j in boxes if j . y == y ] # assign the y position i . y = y y_spot_index = ( y_spot_index + 1 ) % len ( y_spots ) # assign the x position i . x = max ( row_members ) + margin if row_members else margin return boxes