a
    ~bwx                     @   s  d dl mZ d dlZd dlZd dlZd dlmZ ddlm	Z	m
Z
 ddlmZmZ h dZh d	Zh d
ZddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgdgdgdgdgdgdgdgdgdgdgdgdgdZh dZddddddZedZdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd:d1d2Z d;d3d4Z!d<d6d7Z"d8d9 Z#dS )=    )divisionN)colors   )isfinite	max_range   )color_intervalsprocess_cmap>   Z	parcoordsZsankeypietableZparcats>   geoternaryscenepolarmapbox>   r   r   r   xaxisyaxisr   r   r   r   r   )barboxcandlestickZcarpetcontourcontourcarpetZheatmapZ	heatmapgl	histogramZhistogram2dhistogram2dcontourohlc
pointcloudscatterscattercarpet	scatterglviolinZconeZmesh3d	scatter3dZ
streamtubeZsurfaceZ
choropleth
scattergeobarpolarscatterpolarscatterpolarglscatterternaryscattermapbox>   r   r   r&   r    r!   r%   r   r   r
   r#   r   Z	waterfallr"   r   r   Zsplomr$   r   Zarear   r   r   r   r   ZopacityheightsymbolZmaxzoomZminzoom)ZalphaZcell_heightZmarkerZmax_zoomZmin_zoomz\D*(\d+)c                 C   s&   t | }|rt|d}nd}|S )aj  
    Extract the subplot number from a subplot value string.

    'x3' -> 3
    'polar2' -> 2
    'scene' -> 1
    'y' -> 1

    Note: the absence of a subplot number (e.g. 'y') is treated by plotly as
    a subplot number of 1

    Parameters
    ----------
    subplot_val: str
        Subplot string value (e.g. 'scene4')

    Returns
    -------
    int
       )_subplot_rematchintgroup)subplot_valr+   subplot_number r0   =lib/python3.9/site-packages/holoviews/plotting/plotly/util.py_get_subplot_number~   s
    
r2   c                 C   s$   | dkrd}n| dkrd}n| }|S )a]  
    Get the subplot value prefix for a subplot type. For most subplot types
    this is equal to the subplot type string itself. For example, a
    `scatter3d.scene` value of `scene2` is used to associate the scatter3d
    trace with the `layout.scene2` subplot.

    However, the `xaxis`/`yaxis` subplot types are exceptions to this pattern.
    For example, a `scatter.xaxis` value of `x2` is used to associate the
    scatter trace with the `layout.xaxis2` subplot.

    Parameters
    ----------
    subplot_type: str
        Subplot string value (e.g. 'scene4')

    Returns
    -------
    str
    r   xr   yr0   )subplot_typesubplot_val_prefixr0   r0   r1   _get_subplot_val_prefix   s    r7   c                 C   s   | t v rd}n| }|S )a  
    Get the name of the trace property used to associate a trace with a
    particular subplot type.  For most subplot types this is equal to the
    subplot type string. For example, the `scatter3d.scene` property is used
    to associate a `scatter3d` trace with a particular `scene` subplot.

    However, for some subplot types the trace property is not named after the
    subplot type.  For example, the `scatterpolar.subplot` property is used
    to associate a `scatterpolar` trace with a particular `polar` subplot.


    Parameters
    ----------
    subplot_type: str
        Subplot string value (e.g. 'scene4')

    Returns
    -------
    str
    Zsubplot)_subplot_prop_named_subplot)r5   subplot_prop_namer0   r0   r1   _get_subplot_prop_name   s    r:   c                 C   s   |  di }| ddD ]t}|dd}t|g }|D ]R}t|}t|}|||}t|}	|	dkrv|t|	 }
n|}
|
|vr8i ||
< q8qdS )a  
    Make sure a layout subplot property is initialized for every subplot that
    is referenced by a trace in the figure.

    For example, if a figure contains a `scatterpolar` trace with the `subplot`
    property set to `polar3`, this function will make sure the figure's layout
    has a `polar3` property, and will initialize it to an empty dict if it
    does not

    Note: This function mutates the input figure dict

    Parameters
    ----------
    fig: dict
        A plotly figure dict
    layoutdataNtyper   r)   )
setdefaultget_trace_to_subplotr:   r7   r2   str)figr;   trace
trace_typesubplot_typesr5   r9   r6   r.   r/   Zlayout_prop_namer0   r0   r1   _normalize_subplot_ids   s    rF   c                 C   s  dd t D }d|d< d|d< | dg D ]\}|dd}t|g }|D ]:}t|}t|}|||}t|}	t|| |	||< qJq*| d	i }
d
D ]r}|
|g D ]`}|dd}|dkrt|}t|d ||d< |dd}|dkrt|}t|d ||d< qq|S )aj  
    Given an input figure, return a dict containing the max subplot number
    for each subplot type in the figure

    Parameters
    ----------
    fig: dict
        A plotly figure dict

    Returns
    -------
    dict
        A dict from subplot type strings to integers indicating the largest
        subplot number in the figure of that subplot type
    c                 S   s   i | ]
}|d qS )r   r0   ).0r5   r0   r0   r1   
<dictcomp>  s   z(_get_max_subplot_ids.<locals>.<dictcomp>r   r   r   r<   r=   r   r;   annotationsshapesimagesxrefr3   paperyrefr4   )_subplot_typesr?   r@   r:   r7   r2   max)rB   Zmax_subplot_idsrC   rD   rE   r5   r9   r6   r.   r/   r;   layout_propobjrM   xref_numberrO   yref_numberr0   r0   r1   _get_max_subplot_ids   s8    rV   c                  C   s
  |  ddD ]|}| dd}t |g }|D ]Z}t|}t|}| ||}t|}	|	| |d }
|
dkr~|t|
 ||< q,|||< q,q| di }i }|D ]\}|| }|dk rqt| D ]8}|	|rt|}	|	| }|t| }|
|||< qq|| | dd}| d	d}t| D ]}|	dr|| }| d
d}t|| }|dkrvdt| |d
< nd|d
< nP|	d	r*|| }| d
d}t|| }|dkrdt| |d
< nd|d
< q*t| D ]}|dd dkr|| }| dd}|r|d dkr,t|| }n |d dkrt|| }nq|dkr^t|nd}|d | |d< qdD ]}| |g D ]v}|r| dd}|dkrt|}dt||  |d< |r| dd}|dkrt|}dt||  |d< qqzdS )aO  
    Apply offsets to the subplot id numbers in a figure.

    Note: This function mutates the input figure dict

    Note: This function assumes that the normalize_subplot_ids function has
    already been run on the figure, so that all layout subplot properties in
    use are explicitly present in the figure's layout.

    Parameters
    ----------
    fig: dict
        A plotly figure dict
    offsets: dict
        A dict from subplot types to the offset to be applied for each subplot
        type.  This dict matches the form of the dict returned by
        get_max_subplot_ids
    r<   Nr=   r   r   r)   r;   r   r   anchorr4   r3      axismatches rI   rM   rN   rO   )r?   r@   r:   r7   r2   rA   r>   listkeys
startswithpopupdate) rB   ZoffsetsrC   rD   rE   r5   r9   r6   r.   r/   Zoffset_subplot_numberr;   Znew_subplotsoffsetrR   Znew_subplot_numberZnew_layout_propZx_offsetZy_offsetr   rW   Zanchor_numberr   rY   Zmatches_valZmatches_numbersuffixrS   rM   rT   rO   rU   r0   r0   r1   _offset_subplot_ids2  s    







rc   c                    s  |  dg }|  di }fdd fdd fdd}|D ] }|d	d
}	|	tv rF|| qF|D ]$}
tD ]}|
|rt|||
  qtql|D ]b}
|
dr||
 }|dddg} ||d< q|
dr||
 }|dddg}||d< q|dg }|dd}|rr|di }|dd}d}t|||   |d< ||ddddddd|d	 ||d< |dg D ]Z}|dddkr|dd  |d< |d ddkr~|d!d  |d!< q~|d"g D ]}|dddkr,|d#d$  |d#< |d%d&  |d%< |d ddkr|d'd$  |d'< |d(d&  |d(< q|d)g D ]}|dddkr|dd  |d< |d*d |d*< |d ddkr~|d!d  |d!< |d+d |d+< q~dS ),a  
    Scale a figure and translate it to sub-region of the original
    figure canvas.

    Note: If the input figure has a title, this title is converted into an
    annotation and scaled along with the rest of the figure.

    Note: This function mutates the input fig dict

    Note: This function assumes that the normalize_subplot_ids function has
    already been run on the figure, so that all layout subplot properties in
    use are explicitly present in the figure's layout.

    Parameters
    ----------
    fig: dict
        A plotly figure dict
    scale_x: float
        Factor by which to scale the figure in the x-direction. This will
        typically be a value < 1.  E.g. a value of 0.5 will cause the
        resulting figure to be half as wide as the original.
    scale_y: float
        Factor by which to scale the figure in the y-direction. This will
        typically be a value < 1
    translate_x: float
        Factor by which to translate the scaled figure in the x-direction in
        normalized coordinates.
    translate_y: float
        Factor by which to translate the scaled figure in the x-direction in
        normalized coordinates.
    r<   r;   c                    s,   t | d    dt | d    dgS Nr   r)   min)r3   )scale_xtranslate_xr0   r1   scale_translate_x  s    z+_scale_translate.<locals>.scale_translate_xc                    s,   t | d    dt | d    dgS rd   re   )r4   )scale_ytranslate_yr0   r1   scale_translate_y  s    z+_scale_translate.<locals>.scale_translate_yc                    sH   |  di }|dddg}|dddg} ||d< ||d< d S )Ndomainr3   r   r)   r4   )r>   r?   )rS   rm   r3   r4   )ri   rl   r0   r1   perform_scale_translate  s
    z1_scale_translate.<locals>.perform_scale_translater=   r   r   rm   r   r)   r   rJ   titleN	titlefontsize      FrN   g      ?g)\(?centerZbottom)	textZ	showarrowrM   rO   r3   r4   ZxanchorZyanchorZfontrM   r3   rO   r4   rK   Zx0g      ?Zx1g      ?Zy0Zy1rL   ZsizexZsizey)r>   r?   _domain_trace_typesrP   r^   r_   roundappend)rB   rg   rj   rh   rk   r<   r;   rn   rC   rD   propr5   r   Zx_domainr   Zy_domainrJ   ro   rp   Ztitle_fontsizeZmin_fontsizerS   r0   )ri   rl   rg   rj   rh   rk   r1   _scale_translate  s|     	





rz   c                 C   sF   |  dg }|t|dg  |  di }t||di  dS )ae  
    Merge a sub-figure into a parent figure

    Note: This function mutates the input fig dict, but it does not mutate
    the subfig dict

    Parameters
    ----------
    fig: dict
        The plotly figure dict into which the sub figure will be merged
    subfig: dict
        The plotly figure dict that will be copied and then merged into `fig`
    r<   r;   N)r>   extendcopydeepcopyr?   merge_layout)rB   Zsubfigr<   r;   r0   r0   r1   merge_figure   s    r   c                 C   s   |  D ]\}}t|tr2|| v r2t| | | qt|trj| |drjt| | d trj| | | q|dkr|dkr| ddrq|durt|| |< qdS )a:  
    Merge layout objects recursively

    Note: This function mutates the input obj dict, but it does not mutate
    the subobj dict

    Parameters
    ----------
    obj: dict
        dict into which the sub-figure dict will be merged
    subobj: dict
        dict that sill be copied and merged into `obj`
    Nr   Zstylezwhite-bg)	items
isinstancedictr~   r\   r?   r{   r|   r}   )rS   Zsubobjry   valr0   r0   r1   r~   8  s    

r~   c           
         s   t t| }t| d | }||  |||  } fdd| D }g }tt| D ]<}|| t|d|  }td|||  }	|||	f qR|S )a  
    Compute normalized domain tuples for a list of widths and a subplot
    spacing value

    Parameters
    ----------
    widths: list of float
        List of the desired withs of each subplot. The length of this list
        is also the specification of the number of desired subplots
    spacing: float
        Spacing between subplots in normalized coordinates

    Returns
    -------
    list of tuple of float
    r)   c                    s   g | ]}|  qS r0   r0   )rG   wZtotal_widthr0   r1   
<listcomp>r      z,_compute_subplot_domains.<locals>.<listcomp>N)floatsumlenrangerf   rx   )
ZwidthsZspacingZ
widths_sumZtotal_spacingZrelative_spacingZrelative_widthsZdomainscZdomain_startZdomain_stopr0   r   r1   _compute_subplot_domains[  s    r   2   Fc           &   
      s\  dd | D }dd | d D }t |}	t |}
d}t|	D ]<}t|
D ].}| | | }|s^qH||di ddM }qHq<|rd	nd
}t|	D ]x}t|
D ]j}| | | }|sq|di d|}|rt||| ||< |di d|}|rt||| ||< qq|r>||
d |  }|t|   fdd|D }nd |rx||	d |  }|t| fdd|D }ndt||}t||}g i d}tt| |D ]\}\}}tt||D ]\}\}}|rt	|}t
| t|}|r||d< |dkr|di dd	 |rJ||d< |dkrJ|di dd	 t|| |rd|
 }d|	 }|
dkr|d|
 nd}|	dkrd|	 nd}|| } || }!t|| |!|| |d  || |d   nx|d d| }"|d d|  }#|d |d  |#||   }|d |d  |"||   }t||||d |d  t|| qĐq|rlddi|d< |r||d d< n0|rd|d d< nt|||	d   |d d< |r||d d< n0|rd|d d< nt|||
d   |d d< |r&|d  D ]\}$}%|$drd|%d< q|rX|d  D ]\}$}%|$dr8d|%d< q8|S )a  
    Construct a figure from a 2D grid of sub-figures

    Parameters
    ----------
    figures_grid: list of list of (dict or None)
        2D list of plotly figure dicts that will be combined in a grid to
        produce the resulting figure.  None values maybe used to leave empty
        grid cells
    row_spacing: float (default 50)
        Vertical spacing between rows in the gird in pixels
    column_spacing: float (default 50)
        Horizontal spacing between columns in the grid in pixels
        coordinates
    share_xaxis: bool (default False)
        Share x-axis between sub-figures in the same column. Also link all x-axes in the
        figure. This will only work if each sub-figure has a single x-axis
    share_yaxis: bool (default False)
        Share y-axis between sub-figures in the same row. Also link all y-axes in the
        figure. This will only work if each subfigure has a single y-axis
    width: int (default None)
        Final figure width. If not specified, width is the sum of the max width of
        the figures in each column
    height: int (default None)
        Final figure width. If not specified, height is the sum of the max height of
        the figures in each row

    Returns
    -------
    dict
        A plotly figure dict
    c                 S   s   g | ]}d qS r0   rG   _r0   r0   r1   r     r   zfigure_grid.<locals>.<listcomp>c                 S   s   g | ]}d qS r   r0   r   r0   r0   r1   r     r   r   TZconfig
responsiveFNi  r;   widthr'   r)   c                    s   g | ]}|  qS r0   r0   )rG   Zwi)column_width_scaler0   r1   r     r   g      ?c                    s   g | ]}|  qS r0   r0   )rG   hi)row_height_scaler0   r1   r     r   )r<   r;   r   r   g?g       @Zautosizer3   rZ   r4   )r   r   r?   rQ   r   r   	enumeratezipr|   r}   rF   rV   r_   rc   rz   r   r   r^   )&Zfigures_gridZrow_spacingZcolumn_spacingZshare_xaxisZshare_yaxisr   r'   Zrow_heightsZcolumn_widthsZnrowsZncolsr   rr   Zfig_elementdefaultr   hZavailable_column_widthZavailable_row_heightZcolumn_domainsZrow_domainsZoutput_figureZfig_rowZ
row_domainrB   Zcolumn_domainZsubplot_offsetsrg   rj   ZpxpyZsxZsyZ
fig_heightZ	fig_widthry   r   r0   )r   r   r1   figure_grid~  s    )






*

r   c           
   
   C   s~  t |tr|nd}t |trRt|d }t | trRt| |krRtd|t| f zt| |}W n@ ty } z(tj	| }|du r||W  Y d}~S d}~0 0 t |trNg }t
dd|d }t|d D ]x}	|	dk r||d ||	 f q|	|kr||d |d f q|||	 ||	d  f |||	 ||	 f q|S t |trtt||||fd\}\}}t|S )aH  Converts a cmap spec to a plotly colorscale

    Args:
        cmap: A recognized colormap by name or list of colors
        levels: A list or integer declaring the color-levels
        cmin: The lower bound of the color range
        cmax: The upper bound of the color range

    Returns:
        A valid plotly colorscale
    Nr)   zwThe number of colors in the colormap must match the intervals defined in the color_levels, expected %d colors found %d.r   r   )Zclip)r   r,   r\   r   
ValueErrorr	   	Exceptionr   ZPLOTLY_SCALESr?   npZlinspacer   rx   r   Zmake_colorscale)
ZcmapZlevelsZcminZcmaxZncolorsZpaletteeZ
colorscaleZscaleir0   r0   r1   get_colorscale%  s<    




r   _dimc                 C   s   i }|  di  D ]R\}}|dd dkr| |d}||g  |dd}||f}|| | q| D ]r\}}	t|	dk rqp|	d \}
}|	dd D ]B\}}|
|d	< d
|v rd
|v rdd t|d
 |d
 gD |d
< qqpdS )a  
    Configure matching axes for a figure

    Note: This function mutates the input figure

    Parameters
    ----------
    fig: dict
        The figure dictionary to process.
    matching_prop: str
        The name of the axis property that should be used to determine that two axes
        should be matched together.  If the property is missing or None, axes will not
        be matched
    r;   r)   rX   rY   Nr[   r   r   rZ   r   c                 S   s   g | ]}t |r|nd qS )N)r   )rG   vr0   r0   r1   r   {  s   z5configure_matching_axes_from_dims.<locals>.<listcomp>)r?   r   r>   replacerx   r   r   )rB   Zmatching_propZaxis_mapkr   Zmatching_valZaxis_refZ	axis_pairr   Z
axis_pairsZmatches_referenceZlinked_axisrY   r0   r0   r1   !configure_matching_axes_from_dimsS  s$    r   c                 C   sz   t | }|D ]h}| | }|dr.| | qt|trBt| qt|t tfr|rt|d tr|D ]}t| qfqdS )z
    Remove all HoloViews internal properties (those with leading underscores) from the
    input figure.

    Note: This function mutates the input figure

    Parameters
    ----------
    fig: dict
        The figure dictionary to process.
    r   r   N)r\   r^   r_   r   r    clean_internal_figure_propertiestuple)rB   Z	fig_propsry   r   elr0   r0   r1   r     s    


 r   )r   r   FFNN)NNN)r   )$Z
__future__r   r|   reZnumpyr   Zplotlyr   Z	core.utilr   r   utilr   r	   rv   rP   r8   r@   Zlegend_trace_typesZSTYLE_ALIASEScompiler*   r2   r7   r:   rF   rV   rc   rz   r   r~   r   r   r   r   r   r0   r0   r0   r1   <module>   s   ,
(6r|#$      
 (
.
-