
    M/Ph;i              
           d Z ddlmZmZ ddlmZ ddlZddlmZm	Z	m
Z
mZ ddlmZ ddlmZ dgZd	 ZddZd Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zddd
dd dddd
df
dZdS ) zCreate a mosaic plot from a contingency table.

It allows to visualize multivariate categorical data in a rigorous
and informative way.

see the docstring of the mosaic function for more informations.
    )lrangelzip)productN)arraycumsumiterabler_)	DataFrame)utilsmosaicc                    t          |           sl| dk    rt          ddg          } nT| dk    rt          ddg          } n<| dk     r"t          d                    |                     t          | d| z
  g          } t	          j        | t                    } t	          j        | dk               r"t          d                    |                     t	          j        | d          r"t          d                    |                     t          |           dk     rt          ddg          S t          dt          |           f         }||d	         dz  z  }|S )
z
    return a list of proportions of the available space given the division
    if only a number is given, it will assume a split in two pieces
    r                 ?   z.proportions should be positive,given value: {})dtypezBat least one proportion should be greater than zerogiven value: {}   )r   r   
ValueErrorformatnpasarrayfloatanyallcloselenr	   r   )
proportionlefts     _/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/graphics/mosaicplot.py_normalize_splitr      sr   
 J 	???Sz**JJ1__Sz**JJ!^^ 006z0B0BD D D 
C*,<=>>JJe444J	vj1n @ ,,2F:,>,>@ @ 	@	{:q!! 
$fZ00
 
 	

 :c3Z   a
###$DDHsNDK    T皙?c                 F    t                     t                    t          |          t          |          f\   dk     sdk     r#t          d                                        t          |          }|dd         }|dd         |z
  }	||t	          j        t          |          dz
            z  z  }|d         |	d         z   |d         z
  }
||
z  }|	|
z  }	r n|rnz  z   }|	rnz  }	 fdt          ||	          D             }|S )ai  
    Split the given rectangle in n segments whose proportion is specified
    along the given axis if a gap is inserted, they will be separated by a
    certain amount of space, retaining the relative proportion between them
    a gap of 1 correspond to a plot that is half void and the remaining half
    space is proportionally divided among the pieces.
    r   z/dimension of the square less thanzero w={} h={}Nr   r   c                 2    g | ]\  }}r||fn||fS  r$   ).0sah
horizontalwxys      r   
<listcomp>z_split_rect.<locals>.<listcomp>Y   sF     6 6 6Aq  *;1a||1a| 6 6 6r    )r   r   r   r   r   aranger   zip)r+   r,   widthheightr   r)   gapproportionsstarting	amplitude	extensionresultsr(   r*   s   ``   `      @@r   _split_rectr8   7   sw    q588U5\\5==@JAq!Q	A1q55 ++16!Q<<9 9 	9":..K 3B3HABB(*I biK 0 01 45555H y},x{:I 	HI  &Q(:6Laa1*MMH*3QQ!4I6 6 6 6 6 6 6 6)446 6 6GNr    c                     t                    t          fd|                                 D                       }|S )zz
    Make partial sum on a counter dict.
    Given a match for the beginning of the category, it will sum each value.
    c              3   >   K   | ]\  }}|d          k    |V  d S Nr$   )r%   kvLpartial_keys      r   	<genexpr>z_reduce_dict.<locals>.<genexpr>d   s9      IIdaAbqbE[4H4H4H4H4H4HIIr    )r   sumitems)
count_dictr?   countr>   s    ` @r   _reduce_dictrE   ^   sI    
 	KAIIIIIj..00IIIIIELr    c           
          i }t          |          }|                                 D ]V\  }\  }	}
}}||d|         k    r5t          |	|
|||||          }t          ||          D ]\  }}||||fz   <   M|	|
||f||<   W|S )a  
    Given a dictionary where each entry  is a rectangle, a list of key and
    value (count of elements in each category) it split each rect accordingly,
    as long as the key start with the tuple key_subset.  The other keys are
    returned without modification.
    N)r   rB   r8   r/   )	rect_dictkeysvalues
key_subsetr)   r2   resultr>   namer+   r,   r*   r(   	divisionskeyrects                   r   _key_splittingrP   h   s     FJA'oo// ( (lq!Qbqb!!#Aq!Q
CHHI y11 - -	T(,tsf}%%- q!Q<F4LLMr    c                     t          j        |           r/t          | t                    st	          d | D                       }nt          |           f}|S )zconvert an object in a tuple of strings (even if it is not iterable,
    like a single integer number, but keep the string healthy)
    c              3   4   K   | ]}t          |          V  d S r;   )str)r%   os     r   r@   z_tuplify.<locals>.<genexpr>   s(      ((qCFF((((((r    )r   r   
isinstancerS   tuple)objress     r   _tuplifyrY   |   sW     
{3 
3 4 4 ((C(((((3xxkJr    c                     g }t          |  D ]=}t          |          }|                    t          d |D                                  >|S )zuse the Ordered dict to implement a simple ordered set
    return each level of each category
    [[key_1_level_1,key_2_level_1],[key_1_level_2,key_2_level_2]]
    c                     i | ]}|d S r;   r$   )r%   js     r   
<dictcomp>z%_categories_level.<locals>.<dictcomp>   s    444QD444r    )r/   rY   appendlist)rH   rX   i	tuplefieds       r   _categories_levelrb      sX    
 C4\ 7 7QKK	

444)444556666Jr    c           
          t          t                      dfg          }t          t                                                               }t          |          }t          j                  sfdt          |          D             t                    |k     r-d         t           fdt          |          D             z   d|          fdt          t          |           D             t          |          D ]V\  }}t          t          |d|                    }|D ]-fd|D             }	|         }
t          |||	||
          }.| }W|S )am  
    Split a square in a hierarchical way given a contingency table.

    Hierarchically split the unit square in alternate directions
    in proportion to the subdivision contained in the contingency table
    count_dict.  This is the function that actually perform the tiling
    for the creation of the mosaic plot.  If the gap array has been specified
    it will insert a corresponding amount of space (proportional to the
    unit length), while retaining the proportionality of the tiles.

    Parameters
    ----------
    count_dict : dict
        Dictionary containing the contingency table.
        Each category should contain a non-negative number
        with a tuple as index.  It expects that all the combination
        of keys to be represents; if that is not true, will
        automatically consider the missing values as 0
    horizontal : bool
        The starting direction of the split (by default along
        the horizontal axis)
    gap : float or array of floats
        The list of gaps to be applied on each subdivision.
        If the length of the given array is less of the number
        of subcategories (or if it's a single number) it will extend
        it with exponentially decreasing gaps

    Returns
    -------
    base_rect : dict
        A dictionary containing the result of the split.
        To each key is associated a 4-tuple of coordinates
        that are required to create the corresponding rectangle:

            0 - x position of the lower left corner
            1 - y position of the lower left corner
            2 - width of the rectangle
            3 - height of the rectangle
    )r   r   r   r   c                      g | ]
}d |z  z  S g      ?r$   )r%   idxr2   s     r   r-   z'_hierarchical_split.<locals>.<listcomp>   s"    444CsSCZ444r    r   c                      g | ]
}d |z  z  S re   r$   )r%   rf   lasts     r   r-   z'_hierarchical_split.<locals>.<listcomp>   s"    BBB#D3#:-BBBr    Nc                 "    i | ]}||         S r$   r$   )r%   r<   rC   s     r   r]   z'_hierarchical_split.<locals>.<dictcomp>   s5     D D D 
1 D D Dr    c                 8    g | ]}t          |fz             S r$   )rE   )r%   partialcount_orderedrN   s     r   r-   z'_hierarchical_split.<locals>.<listcomp>   s:     5 5 5 ' '}cWJ6FGG 5 5 5r    )dictrV   rb   r_   rH   r   r   r   ranger   	enumeraterP   )rC   r)   r2   	base_rectcategories_levelsr>   cat_idxcat_enum	base_keys
part_countnew_gaprl   rN   rh   s   ` `        @@@r   _hierarchical_splitrw      s   R uww-.//I)$z/@/@*A*ABBA ;s 54444588444
3xx!||2wCjBBBBqBBBB
bqb'CD D D D!%g/@&A!B!BD D DM&'899 $ $"3HWH"=>??	 		< 		<C5 5 5 5 5+35 5 5J 'lG&y(J'17< <II#^

r    c                     ddl m}  |t          |                               ddd                                        d          S )z0Transform a color from the hsv space to the rgb.r   )
hsv_to_rgbr      )matplotlib.colorsry   r   reshape)hsvry   s     r   _single_hsv_to_rgbr~      sJ    ,,,,,,:eCjj((Aq1122::1===r    c                    t          t          |                                                     }t          |          }t          |d                   }t	          j        dd|dz             dd         }|dk    rt          |d                   nd}t	          j        dd|dz             dd	         }|dk    rt          |d                   nd}t	          j        dd|dz             dd	         }|d
k    rt          |d
                   nd}g dd|dz            }t          t          |          |d                   }t          t          |          |dk    r|d         ndg          }t          t          |          |dk    r|d         ndg          }t          t          |          |d
k    r|d
         ndg          }i }t          ||||          D ]\  }	}
}}|	\  }}|
\  }}|\  }}|\  }}|f|r|fnt                      z   }||r|fnt                      z   }||r|fnt                      z   }t          |||g          }t          |          |dd}|||<   |S )a\  "Create the default properties of the mosaic given the data
    first it will varies the color hue (first category) then the color
    saturation (second category) and then the color value
    (third category).  If a fourth category is found, it will put
    decoration on the rectangle.  Does not manage more than four
    level of categories
    r   r   r   r   Nr   g      ?r   rz   ) /-|+r   )colorhatchlw)rb   r_   rH   r   r   linspacer   r   rV   r   r~   )datarq   Nlevelsr>   hue
saturationvaluer   
propertiesr(   r&   r=   thvhnsvsnvvvntvtnlevelr}   props                           r   _create_default_propertiesr      s    *$tyy{{*;*;<<#$$Ga !!A
+c3A
&
&ss
+C%,q[[a !!!aAS#q1u--crc2J%,q[[a !!!aAKS!a%(("-E%,q[[a !!!aA$$$Va!eV,E
tCyy+A.
/
/Cd:&&-4q[[&q))rdD DJe-4q[[&q))rdD DEe-4q[[&q))rdD DE Jc:ue<< 
! 
!
1aBBBB"1"%''2"1"%''2"1"%''2RRL!!+C002QGG 
5r    c                 (    t           d          r"t           d          rt           |           d}	 t                                                     }n# t          $ r| t          j                    i }t          j         j                  D ]&}t          d |D                       } |         ||<   '| t                                                     }Y nw xY wd |D              t          t                                                               }t          | } fd|D             }| |t          t          |                    n|}i }                                 D ]%\  }	t          fd|D                       }
|	||
<   &|  S )aj  normalize the data to a dict with tuples of strings as keys
    right now it works with:

        0 - dictionary (or equivalent mappable)
        1 - pandas.Series with simple or hierarchical indexes
        2 - numpy.ndarrays
        3 - everything that can be converted to a numpy array
        4 - pandas.DataFrame (via the _normalize_dataframe function)
    pivotgroupbyNc              3      K   | ]}|V  d S r;   r$   )r%   r`   s     r   r@   z"_normalize_data.<locals>.<genexpr>-  s"      ((q((((((r    c                 4    i | ]\  }}t          |          |S r$   )rY   )r%   r<   r=   s      r   r]   z#_normalize_data.<locals>.<dictcomp>2  s$    ---tq!HQKK---r    c                 >    i | ]}|                     |d           S )r   get)r%   r<   r   s     r   r]   z#_normalize_data.<locals>.<dictcomp>6  s'    6661dhhq!nn666r    c              3   (   K   | ]}|         V  d S r;   r$   )r%   r`   rN   s     r   r@   z"_normalize_data.<locals>.<genexpr>>  s'      ..1A......r    )hasattr_normalize_dataframer_   rB   AttributeErrorr   r   ndindexshaperV   rb   rH   r   r   r   )r   indexrB   temprf   rL   rq   indexescontingencyr   new_keyrN   s   `          @r   _normalize_datar     s    tW '$	":": #D%00#TZZ\\"" 	# 	# 	# z$:dj)) 	# 	#C((C(((((DcDJJTZZ\\""	# .-u---D)$tyy{{*;*;<<()G6666g666KD /4mF3())***EKjjll % %
U.........$GDKs   !A BCCc                     | |                                          }|                    |dd          }||                                         }|                    d          }|                    d          }|S )zTake a pandas DataFrame and count the element present in the
    given columns, return a hierarchical index on those columns
    F)sortobservedr   )axisr   )dropnar   rD   meanfillna)	dataframer   r   groupedcountedaverageds         r   r   r   D  so     U""$$Dll5uul==Gen""$$G|||##Hs##HOr    c                     t           d           t          t                                                               }t	          |          }dt          d                                  D                       z  }g }t          |          D ]o}i }||         D ]M}d||<                                    D ]!\  }}	|||         k    r||xx         |	z  cc<   "||xx         |z  cc<   N|	                    |           pi }
                                 D ]R\  }}	d}t          |          D ]\  }}|||         |         z  }||z  t          j        ||z  d|z
  z            f|
|<   S fd|
                                D             }i }|                                D ]M\  }}|dk     rdn|d|z   z  }|dk    rdn|d|z   z  }d|z
  |z
  d	z  }|d
k    rdn	|dk     rdnd}|||g|d||<   N|S )zevaluate colors from the indipendence properties of the matrix
    It will encounter problem if one category has all zeros
    Nr   c              3      K   | ]}|V  d S r;   r$   )r%   r=   s     r   r@   z(_statistical_coloring.<locals>.<genexpr>Z  s"      //Aa//////r    r   c                 :    i | ]\  }\  }}||         |z
  |z  S r$   r$   )r%   r<   mr&   r   s       r   r]   z)_statistical_coloring.<locals>.<dictcomp>s  s0    EEEyq&1aa$q'A+"EEEr    r   r   r          @r   r+   r   rT   r   )r   r   )r   rb   r_   rH   r   rA   rI   rn   rB   r^   ro   r   sqrt)r   rq   r   totallevels_count	level_idxr   r   rN   r   expectedbaser`   r<   sigmaspropsdevredbluegreenr   s   `                    r   _statistical_coloringr   S  sq    4&&D)$tyy{{*;*;<<#$$G#////////E L7^^ ( (	
&y1 	' 	'E #Ju"jjll / /
UC	N**u%%%.%%%u&J'''' Hjjll K K
UcNN 	' 	'DAqLOA&&DDubgedlcDj.I&J&JJ FEEEHNN4D4DEEEFELLNN C CS1WWcc3!c'?AggssC28$4sT!S(Qww388CC #UD1EBBc

Lr    c                 4    |dk    r| S | |dz  z   |z  |z  |z  S )Nr   r   r$   )r+   r*   r(   Ws       r   _get_positionr   ~  s-    AvvCK1q 1$$r    c                 R   t          t          |                                                     t                    dk    rd}t	          |          i }t          |                                           }| }|                                }|                                }	|j        |j	        |	j        |j	        g}
|j
        |j        |	j
        |j        g}|r*|
dd         |
dd         z   }
|dd         |dd         z   }t          |
|          D ]\  }} |g             |g            t                    D ]d\  }t                      }|D ]}|rdk    rg dng dndk    rg dng dt          fd	t!                    D                       |fz   fd
|D             }t          |                                          }t%          d |D                       t%          fd|D                       }t%          fd|D                       }|z   dz  }|dz  r|n|||<    |
         t          |                                                      |         t          |                                          |                    f|S )zfind the position of the label for each value of each category

    right now it supports only up to the four categories

    ax: the axis on which the label should be applied
    rotation: the rotation list for each side
       zrmaximum of 4 level supported for axes labeling... and 4is already a lot of levels, are you sure you need them all?r   Nrz   )r   r   r   )r   r   r   )r   r   r   c              3   @   K   | ]}|         |                  V  d S r;   r$   )r%   r`   
categoriesindex_selects     r   r@   z!_create_labels.<locals>.<genexpr>  sD       7 7 ! 'qM,q/: 7 7 7 7 7 7r    c                 >    i | ]\  }}|d dz            k    ||S )Nr   r$   )r%   r<   r=   basekeyr   s      r   r]   z"_create_labels.<locals>.<dictcomp>  s@     ; ; ;tq!$.9q=.(999 999r    c              3   *   K   | ]\  }}}}||z  V  d S r;   r$   )r%   r+   r,   r*   r(   s        r   r@   z!_create_labels.<locals>.<genexpr>  s.      33lq!QAE333333r    c              3   F   K   | ]\  }}}}t          |||          V  d S r;   r   r%   r+   r,   r*   r(   r   s        r   r@   z!_create_labels.<locals>.<genexpr>  9      KKlq!QaAq11KKKKKKr    c              3   F   K   | ]\  }}}}t          |||          V  d S r;   r   r   s        r   r@   z!_create_labels.<locals>.<genexpr>  r   r    r   )rotation)rb   r_   rH   r   r   rB   twinxtwiny
set_xticks
set_yticksset_xticklabelsset_yticklabelsr/   ro   rm   rV   rn   rI   rA   )rectsr)   axr   msglabelsrB   verticalax2ax3	ticks_pos	ticks_labposlabr   level_ticksr   subsetvalsx_laby_labsider   r   r   r   r   s                         @@@@@r   _create_labelsr     s=    #4

#5#566J
:MooFE~H ((**C
((**Cs~s~NI#R%7$c&9;I  2abbMIbqbM1	abbMIbqbM1		9--  SBB &j11 ,; ,;	5ff $	> $	>E
  	0>>#/<<LL#/<<LL>>#/<<LL#/<<L  7 7 7 7 7%*9%5%57 7 7 7 7G(G; ; ; ; ;u ; ; ;F ((D33d33333AKKKKdKKKKKEKKKKdKKKKKE (A-D*.(!=K 		)T+"4"4"6"677888	)T+"2"2"4"455&.y&9	; 	; 	; 	; 	;Mr    g{Gzt?c                     d S r;   r$   )rN   s    r   <lambda>r     s    $ r    r   Fr   c           	         t          | t                    r|t          d          ddlm} t          j        |          \  }}t          | |          } t          | ||          }|d }|rt          |           }nt          |           }t          |t                    r|fd}|                                D ]y\  }}|\  }}}} ||          }|r|n||         } ||          } |||f||fd|i|}|                    |           |                    ||d	z  z   ||d	z  z   |d
d
d           z|	r0t          j        |
          r|
}n|
gdz  }t#          ||||          }nT|                    g            |                    g            |                    g            |                    g            |                    |           ||fS )a  Create a mosaic plot from a contingency table.

    It allows to visualize multivariate categorical data in a rigorous
    and informative way.

    Parameters
    ----------
    data : {dict, Series, ndarray, DataFrame}
        The contingency table that contains the data.
        Each category should contain a non-negative number
        with a tuple as index.  It expects that all the combination
        of keys to be represents; if that is not true, will
        automatically consider the missing values as 0.  The order
        of the keys will be the same as the one of insertion.
        If a dict of a Series (or any other dict like object)
        is used, it will take the keys as labels.  If a
        np.ndarray is provided, it will generate a simple
        numerical labels.
    index : list, optional
        Gives the preferred order for the category ordering. If not specified
        will default to the given order.  It does not support named indexes
        for hierarchical Series.  If a DataFrame is provided, it expects
        a list with the name of the columns.
    ax : Axes, optional
        The graph where display the mosaic. If not given, will
        create a new figure
    horizontal : bool, optional
        The starting direction of the split (by default along
        the horizontal axis)
    gap : {float, sequence[float]}
        The list of gaps to be applied on each subdivision.
        If the length of the given array is less of the number
        of subcategories (or if it's a single number) it will extend
        it with exponentially decreasing gaps
    properties : dict[str, callable], optional
        A function that for each tile in the mosaic take the key
        of the tile and returns the dictionary of properties
        of the generated Rectangle, like color, hatch or similar.
        A default properties set will be provided fot the keys whose
        color has not been defined, and will use color variation to help
        visually separates the various categories. It should return None
        to indicate that it should use the default property for the tile.
        A dictionary of the properties for each key can be passed,
        and it will be internally converted to the correct function
    labelizer : dict[str, callable], optional
        A function that generate the text to display at the center of
        each tile base on the key of that tile
    title : str, optional
        The title of the axis
    statistic : bool, optional
        If true will use a crude statistical model to give colors to the plot.
        If the tile has a constraint that is more than 2 standard deviation
        from the expected value under independence hypothesis, it will
        go from green to red (for positive deviations, blue otherwise) and
        will acquire an hatching when crosses the 3 sigma.
    axes_label : bool, optional
        Show the name of each value of each category
        on the axis (default) or hide them.
    label_rotation : {float, list[float]}
        The rotation of the axis label (if present). If a list is given
        each axis can have a different rotation

    Returns
    -------
    fig : Figure
        The figure containing the plot.
    rects : dict
        A dictionary that has the same keys of the original
        dataset, that holds a reference to the coordinates of the
        tile and the Rectangle that represent it.

    References
    ----------
    A Brief History of the Mosaic Display
        Michael Friendly, York University, Psychology Department
        Journal of Computational and Graphical Statistics, 2001

    Mosaic Displays for Loglinear Models.
        Michael Friendly, York University, Psychology Department
        Proceedings of the Statistical Graphics Section, 1992, 61-68.

    Mosaic displays for multi-way contingency tables.
        Michael Friendly, York University, Psychology Department
        Journal of the american statistical association
        March 1994, Vol. 89, No. 425, Theory and Methods

    Examples
    --------
    >>> import numpy as np
    >>> import pandas as pd
    >>> import matplotlib.pyplot as plt
    >>> from statsmodels.graphics.mosaicplot import mosaic

    The most simple use case is to take a dictionary and plot the result

    >>> data = {'a': 10, 'b': 15, 'c': 16}
    >>> mosaic(data, title='basic dictionary')
    >>> plt.show()

    A more useful example is given by a dictionary with multiple indices.
    In this case we use a wider gap to a better visual separation of the
    resulting plot

    >>> data = {('a', 'b'): 1, ('a', 'c'): 2, ('d', 'b'): 3, ('d', 'c'): 4}
    >>> mosaic(data, gap=0.05, title='complete dictionary')
    >>> plt.show()

    The same data can be given as a simple or hierarchical indexed Series

    >>> rand = np.random.random
    >>> from itertools import product
    >>> tuples = list(product(['bar', 'baz', 'foo', 'qux'], ['one', 'two']))
    >>> index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
    >>> data = pd.Series(rand(8), index=index)
    >>> mosaic(data, title='hierarchical index series')
    >>> plt.show()

    The third accepted data structure is the np array, for which a
    very simple index will be created.

    >>> rand = np.random.random
    >>> data = 1+rand((2,2))
    >>> mosaic(data, title='random non-labeled array')
    >>> plt.show()

    If you need to modify the labeling and the coloring you can give
    a function tocreate the labels and one with the graphical properties
    starting from the key tuple

    >>> data = {'a': 10, 'b': 15, 'c': 16}
    >>> props = lambda key: {'color': 'r' if 'a' in key else 'gray'}
    >>> labelizer = lambda k: {('a',): 'first', ('b',): 'second',
    ...                        ('c',): 'third'}[k]
    >>> mosaic(data, title='colored dictionary', properties=props,
    ...        labelizer=labelizer)
    >>> plt.show()

    Using a DataFrame as source, specifying the name of the columns of interest

    >>> gender = ['male', 'male', 'male', 'female', 'female', 'female']
    >>> pet = ['cat', 'dog', 'dog', 'cat', 'dog', 'cat']
    >>> data = pd.DataFrame({'gender': gender, 'pet': pet})
    >>> mosaic(data, ['pet', 'gender'], title='DataFrame as Source')
    >>> plt.show()

    .. plot :: plots/graphics_mosaicplot_mosaic.py
    Nz<You must pass an index if data is a DataFrame. See examples.r   )	Rectangle)r)   r2   c                 ,    d                     |           S )N
)join)r<   s    r   r   zmosaic.<locals>.<lambda>}  s    diill r    c                 0                         | d           S r;   r   )rN   
color_dicts    r   r   zmosaic.<locals>.<lambda>  s    T!:!: r    labelr   centersmaller)havasizer   )rU   r
   r   matplotlib.patchesr   r   create_mpl_axr   rw   r   r   rm   rB   	add_patchtextr   r   r   r   r   r   r   	set_title)r   r   r   r)   r2   r   	labelizertitle	statistic
axes_labellabel_rotationr   figr   default_propsr<   r=   r+   r,   r*   r(   confr   r  Rectr   r   r   s                              @r   r   r     sN   n $	"" +u} * + + 	+ -,,,,, !"%%GC4''DEEEE **	 9-d332488*d## ;
::::
 	. 	.1
1az!}}2-"2y||y!QA;;T;U;;
T
AE	1q1u9dx9 	 	. 	. 	. 	.  
;~&& 	,%HH&'!+Hz2x@@
b
2
b
2LL:r    )Tr!   ) __doc__statsmodels.compat.pythonr   r   	itertoolsr   numpyr   r   r   r   r	   pandasr
   statsmodels.graphicsr   __all__r   r8   rE   rP   rY   rb   rw   r~   r   r   r   r   r   r   r   r$   r    r   <module>r     s    3 2 2 2 2 2 2 2           - - - - - - - - - - - -       & & & & & &*  @$ $ $ $N    (  	 	 	I I I IX> > >, , ,^- - -`  ( ( (V% % %P P Pf 5&&$uF F F F F Fr    