#NEWLINE# def _hierarchical_split( count_dict , horizontal = True , gap = 0.05 ) : #NEWLINE# #INDENT# "\n    Split a square in a hierarchical way given a contingency table.\n\n    Hierarchically split the unit square in alternate directions\n    in proportion to the subdivision contained in the contingency table\n    count_dict.  This is the function that actually perform the tiling\n    for the creation of the mosaic plot.  If the gap array has been specified\n    it will insert a corresponding amount of space (proportional to the\n    unit lenght), while retaining the proportionality of the tiles.\n\n    Parameters\n    ----------\n    count_dict : dict\n        Dictionary containing the contingency table.\n        Each category should contain a non-negative number\n        with a tuple as index.  It expects that all the combination\n        of keys to be representes; if that is not true, will\n        automatically consider the missing values as 0\n    horizontal : bool\n        The starting direction of the split (by default along\n        the horizontal axis)\n    gap : float or array of floats\n        The list of gaps to be applied on each subdivision.\n        If the lenght of the given array is less of the number\n        of subcategories (or if it's a single number) it will extend\n        it with exponentially decreasing gaps\n\n    Returns\n    ----------\n    base_rect : dict\n        A dictionary containing the result of the split.\n        To each key is associated a 4-tuple of coordinates\n        that are required to create the corresponding rectangle:\n\n            0 - x position of the lower left corner\n            1 - y position of the lower left corner\n            2 - width of the rectangle\n            3 - height of the rectangle\n    " #NEWLINE# base_rect = OrderedDict ( [ ( tuple ( ) , ( 0 , 0 , 1 , 1 ) ) ] ) #NEWLINE# categories_levels = _categories_level ( list ( iterkeys ( count_dict ) ) ) #NEWLINE# L = len ( categories_levels ) #NEWLINE# if ( not np . iterable ( gap ) ) : #NEWLINE# #INDENT# gap = [ ( gap / ( 1.5 ** idx ) ) for idx in range ( L ) ] #NEWLINE# #UNINDENT# if ( len ( gap ) < L ) : #NEWLINE# #INDENT# last = gap [ ( - 1 ) ] #NEWLINE# gap = ( list ( * gap ) + [ ( last / ( 1.5 ** idx ) ) for idx in range ( L ) ] ) #NEWLINE# #UNINDENT# gap = gap [ : L ] #NEWLINE# count_ordered = OrderedDict ( [ ( k , count_dict [ k ] ) for k in list ( product ( * categories_levels ) ) ] ) #NEWLINE# for ( cat_idx , cat_enum ) in enumerate ( categories_levels ) : #NEWLINE# #INDENT# base_keys = list ( product ( * categories_levels [ : cat_idx ] ) ) #NEWLINE# for key in base_keys : #NEWLINE# #INDENT# part_count = [ _reduce_dict ( count_ordered , ( key + ( partial , ) ) ) for partial in cat_enum ] #NEWLINE# new_gap = gap [ cat_idx ] #NEWLINE# base_rect = _key_splitting ( base_rect , cat_enum , part_count , count_ordered , horizontal , new_gap ) #NEWLINE# #UNINDENT# horizontal = ( not horizontal ) #NEWLINE# #UNINDENT# return base_rect