U
    SZf6X                     @   s   d dl mZ d dlmZ d dlmZ d dlmZ e	dZ
e	dZd dlmZ dd	d
dddgfddZd3ddZdd Zdd Zdd Zdd Zd4ddZdd Zd5d d!Zd"d# Zd$d% Zd&d' Zd6d,d-Zdddgd.d.dd/dd0dddd/fd1d2ZdS )7    N)
graph_objs)
exceptions)optional_importsZnumpyzscipy.interpolate)measurezTernary contour ploti&  i  abcc                 C   s`   t | ||t dt t |d dddddt t |d dddddt t |d ddddddd	d
S )a]  
    Layout of ternary contour plot, to be passed to ``go.FigureWidget``
    object.

    Parameters
    ==========
    title : str or None
        Title of ternary plot
    width : int
        Figure width.
    height : int
        Figure height.
    pole_labels : str, default ['a', 'b', 'c']
        Names of the three poles of the triangle.
       r   )text{Gz?   Zoutside)titleminZ	linewidthZticks)sumZaaxisZbaxisZcaxisF)r   widthheightZternary
showlegend)dict)r   r   r   pole_labels r   J/tmp/pip-unpacked-wheel-5ksk5baj/plotly/figure_factory/_ternary_contour.py_ternary_layout   s6             r   Mb@?c                 C   sN   | dk}t j|dd}d||  }t |dk r8tdt ||||  } | S )a  
    Replaces zero ternary coordinates with delta and normalize the new
    triplets (a, b, c).

    Parameters
    ----------

    ternary_data : ndarray of shape (N, 3)

    delta : float
        Small float to regularize logarithm.

    Notes
    -----
    Implements a method
    by J. A. Martin-Fernandez,  C. Barcelo-Vidal, V. Pawlowsky-Glahn,
    Dealing with zeros and missing values in compositional data sets
    using nonparametric imputation, Mathematical Geology 35 (2003),
    pp 253-278.
    r   Zaxisr	   zMThe provided value of delta led to negativeternary coords.Set a smaller delta)npany
ValueErrorwhere)Zternary_datadeltaZ	zero_maskZis_any_coord_zeroZunity_complementr   r   r   _replace_zero_coords7   s    r   c                 C   sl   t | } t | d | d  t d }dt d t | d | d  | d d   }t ||f}|S )a  
    Perform Isometric Log-Ratio on barycentric (compositional) data.

    Parameters
    ----------
    barycentric: ndarray of shape (3, N)
        Barycentric coordinates.

    References
    ----------
    "An algebraic method to compute isometric logratio transformation and
    back transformation of compositional data", Jarauta-Bragulat, E.,
    Buenestado, P.; Hervada-Sala, C., in Proc. of the Annual Conf. of the
    Intl Assoc for Math Geology, 2003, pp 31-30.
    r   r	   r         ?   )r   asarraylogsqrtstack)ZbarycentricZx_0Zx_1Z	ilr_tdatar   r   r   _ilr_transformY   s    
 .r&   c              
   C   s   t | } t dddgdddgdddgg}t dd }t d}t dt ||g| |gg| }t dt |jd	d
  }t d|t d| | d	  || d  |f}t |}|S )a  
    Perform inverse Isometric Log-Ratio (ILR) transform to retrieve
    barycentric (compositional) data.

    Parameters
    ----------
    x : array of shape (2, N)
        Coordinates in ILR space.

    References
    ----------
    "An algebraic method to compute isometric logratio transformation and
    back transformation of compositional data", Jarauta-Bragulat, E.,
    Buenestado, P.; Hervada-Sala, C., in Proc. of the Annual Conf. of the
    Intl Assoc for Math Geology, 2003, pp 31-30.
          ?r	   r    g      g        r   g      ?ik, kj -> ijr   r   )r   arrayr$   einsumr#   expr   r%   )xZmatrixstZSkZZlog_barycentricZ
iilr_tdatar   r   r   _ilr_inverser   s    
"
"  "
r0   c                  C   sd   t dt dd gddgddgg} t | dddf | dddf t dg}|t j|fS )zi
    Returns the transformation matrix from barycentric to Cartesian
    coordinates and conversely.
    r'      r   r   r	   N)r   r)   r$   onesZlinalginv)Z	tri_vertsMr   r   r    _transform_barycentric_cartesian   s    &.r5   c                 C   s   t | ttjfstdt| } | jd dkr8tdt| dkrtj| j	ddddd	stj| j	ddd
dd	sd}t|t| dkr| \}}d||  }n| | j	dd \}}}t
t|||fdk rtdt|||fS )zQ
    Check ternary coordinates and return the right barycentric coordinates.
    zOData  should be either an array of shape (n,m),or a list of n m-lists, m=2 or 3r   )r   r1   zCA point should have  2 (a, b) or 3 (a, b, c)barycentric coordinatesr1   r   r	   r   )Zrtold   z=The sum of coordinates should be 1 or 100 for all data pointsr   z+Barycentric coordinates should be positive.)
isinstancelistr   Zndarrayr   r"   shapelenZallcloser   r   r%   )Zb_coordsmsgABCr   r   r   _prepare_barycentric_coord   s0    

r?   ilrc                 C   s  |dkr"t  \}}td|| }n"|dkr<t| } t| }ntd|dd \}}| |  }}	| |  }
}tdtt	t
|}t||	|}t|
||}t||\}}tj|dd j|||fdd	}tj|dd j|||fd
d	}|||fS )a  
    Transform data points with Cartesian or ILR mapping, then Compute
    interpolation on a regular grid.

    Parameters
    ==========

    coordinates : array-like
        Barycentric coordinates of data points.
    values : 1-d array-like
        Data points, field to be represented as contours.
    interp_mode : 'ilr' (default) or 'cartesian'
        Defines how data are interpolated to compute contours.
    	cartesianr(   r@   z&interp_mode should be cartesian or ilrNr      Zcubic)methodZnearest)r5   r   r*   r   r&   r   r   maxintr$   r:   linspaceZmeshgridscipy_interpZgriddataT)coordinatesvaluesinterp_moder4   invMZcoord_pointsZxxyyZx_minZx_maxZy_minZy_maxZn_interpgr_xgr_yZgrid_xZgrid_ygrid_zZgrid_z_otherr   r   r   _compute_grid   s6    

      rQ   c                 C   s2   dt t | t |dt |t | d  S )Nr'   r	   )r   absdotZroll)r,   yr   r   r   _polygon_area   s    rU   c                 C   s  |t j krt j| }ntdt j tdd| }tdd |D }tdd |D }t	||}d|d krdd |D }|d g}t
|dd	 |dd	 D ]V\}}	||d  ||  }
}|	|
 ||
  }t j||d  || |d
d}|| q|S )zQ
    Return a list of ``ncontours`` colors from the ``colormap`` colorscale.
    zRColorscale must be a valid Plotly Colorscale.The available colorscale names are {}r   r	   c                 S   s   g | ]}|d  qS )r   r   .0pairr   r   r   
<listcomp>   s     z_colors.<locals>.<listcomp>c                 S   s   g | ]}|d  qS )r	   r   rV   r   r   r   rY      s     #c                 S   s   g | ]}t t |qS r   )clrsZ	label_rgbZ
hex_to_rgb)rW   colr   r   r   rY      s     NZrgb)Z	colortype)r[   ZPLOTLY_SCALESkeysr   ZPlotlyErrorformatr   rF   r)   ZsearchsortedzipZfind_intermediate_colorappend)	ncontoursZcolormapZcmaprJ   Z	vals_cmapcolsZindscolorsindvalZval1Zval2Zintermr\   r   r   r   _colors   s2    
"
   rf   c                 C   s<   t t | | d  dk o6t t ||d  dk }|S )zy
    Utility function for _contour_trace

    Contours with an area of the order as 1 pixel are considered spurious.
    r   r   )r   allrR   )r,   rT   Z	too_smallr   r   r   _is_invalid_contour
  s    8rh   c                 C   sp  t | }| t |  | t |   }}t | }d| ||< t | }d| ||< g g g g f\}}	}
}g g g g f\}}}}t|D ]\}}t||}t||}|	| |	| |		|gt
|  |	|gt
|  |
	dd |D  |	dd |D  |	|| gt
|  |	|| gt
|  qt
|t
|kr`||	|
|fS ||||fS dS )a{  
    Utility function for _contour_trace.

    In ``im`` only one part of the domain has valid values (corresponding
    to a subdomain where barycentric coordinates are well defined). When
    computing contours, we need to assign values outside of this domain.
    We can choose a value either smaller than all the values inside the
    valid domain, or larger. This value must be chose with caution so that
    no spurious contours are added. For example, if the boundary of the valid
    domain has large values and the outer value is set to a small one, all
    intermediate contours will be added at the boundary.

    Therefore, we compute the two sets of contours (with an outer value
    smaller of larger than all values in the valid domain), and choose
    the value resulting in a smaller total number of contours. There might
    be a faster way to do this, but it works...
    r   c                 S   s"   g | ]}t |jd  |jd qS r	   r   rU   rH   rW   Zcontourr   r   r   rY   9  s     z%_extract_contours.<locals>.<listcomp>c                 S   s"   g | ]}t |jd  |jd qS ri   rj   rk   r   r   r   rY   <  s     N)r   isnanZlogical_notr   rD   copy	enumerater   Zfind_contoursextendr:   )ZimrJ   rc   Zmask_nanZim_minZim_maxZzz_minZzz_maxZall_contours1Zall_values1Z
all_areas1Zall_colors1Zall_contours2Zall_values2Z
all_areas2Zall_colors2ire   Zcontour_level1Zcontour_level2r   r   r   _extract_contours  s8    




rq   c                    sj  dt dddgdddggj }|g|  } t |d }t |d | g||d | gf}t |	g||
gf}t ||kd d }|t|d k r|d8 }n|d7 }|| g   || g| }dg| } fdd|D }t|}t dd|d }g }t|D ]:\}}|	|| || g |	||d  || g q|	|| ||d  g | || |fS )	a  
    Utility function for _contour_trace

    Adds the background color to fill gaps outside of computed contours.

    To compute the background color, the color of the contour with largest
    area (``val_outer``) is used. As background color, we choose the next
    color value in the direction of the extrema of the colormap.

    Then we add information for the outer contour for the different lists
    provided as arguments.

    A discrete colormap with all used colors is also returned (to be used
    by colorscale trace).
       r   r	   r'   r   c                    s   g | ]}| kr|qS r   r   )rW   color
all_colorsr   r   rY   r  s      z&_add_outer_contour.<locals>.<listcomp>)
r   r)   rH   ZdiffconcatenateZnonzeror:   rF   rn   r`   )all_contours
all_values	all_areasrv   rJ   Z	val_outerv_minv_maxrc   	color_min	color_maxZouter_contourZdelta_valuesindexZused_colorsZcolor_numberZscalediscrete_cmrp   rt   r   ru   r   _add_outer_contourF  s.     


r   Electricrgb(150,150,150)llrr	   c
           #      C   sR  t |d |}
t||	|d }|
d |
d  }}|
dd }
|dd }|dkrXd}n
|g| }
t|||
\}}}}t|ddd }t|||||||d  ||	|
||\}}}}}tdg|d f}g }t \}}|  | 	  | j
 }| |	  |j
 }|D ]<}|| j\}}|| }|dkrZt|t|| || t|jf}n4|dkrtt|| | 	  || |	  f}|dkrtdddg}tdddg}tdddg} n
|\}}} t||rq
|d	kr|| n|}!td
||| d	t|!dddd|| ddd| d}"|d	kr<d|"d< ||" q
||fS )a  
    Contour trace in Cartesian coordinates.

    Parameters
    ==========

    x, y : array-like
        Cartesian coordinates
    z : array-like
        Field to be represented as contours.
    ncontours : int or None
        Number of contours to display (determined automatically if None).
    colorscale : None or str (Plotly colormap)
        colorscale of the contours.
    linecolor : rgb color
        Color used for lines. If ``colorscale`` is not None, line colors are
        determined from ``colorscale`` instead.
    interp_mode : 'ilr' (default) or 'cartesian'
        Defines how data are interpolated to compute contours. If 'irl',
        ILR (Isometric Log-Ratio) of compositional data is performed. If
        'cartesian', contours are determined in Cartesian space.
    coloring : None or 'lines'
        How to display contour. Filled contours if None, lines if ``lines``.
    vmin, vmax : float
        Bounds of interval of values used for the colorspace

    Notes
    =====
    r   r   rs   r	   Nzrgb(150, 150, 150)rA   r@   linesscatterternaryZspline)rt   r9   r   ZtoselfTskipz%.3f)typer   r   r   modelinefillZ	fillcolorr   Z	hoverinfonamer   )rf   r   rF   rq   Zargsortr   rw   r5   rD   r   sizerH   rS   r%   r2   r9   r0   r)   rh   r   r`   )#r,   rT   zra   
colorscale	linecolorrK   coloringr{   r|   rc   rJ   r}   r~   rx   ry   rz   rv   orderr   Ztracesr4   rL   ZdxZdyr   Z	y_contourZ	x_contourre   Z
bar_coordsr   r   r   Z_coltracer   r   r   _contour_trace  s    ,
  




$


r   i  FZBlueredc                 C   sb  t dkrtdtd}|dkr*td|dkr6d}|dkrBd}t| } | |  }}t| ||d\}}}t||||
d}t	||||||	||||d	
\}}t
j||d
}|rdnd}| \}}}|d d |d  d |d  d }|j|||d||dt|dkdd||d |r^|s&|}tddgdgdg| | |dddd}|| |S )a  
    Ternary contour plot.

    Parameters
    ----------

    coordinates : list or ndarray
        Barycentric coordinates of shape (2, N) or (3, N) where N is the
        number of data points. The sum of the 3 coordinates is expected
        to be 1 for all data points.
    values : array-like
        Data points of field to be represented as contours.
    pole_labels : str, default ['a', 'b', 'c']
        Names of the three poles of the triangle.
    width : int
        Figure width.
    height : int
        Figure height.
    ncontours : int or None
        Number of contours to display (determined automatically if None).
    showscale : bool, default False
        If True, a colorbar showing the color scale is displayed.
    coloring : None or 'lines'
        How to display contour. Filled contours if None, lines if ``lines``.
    colorscale : None or str (Plotly colormap)
        colorscale of the contours.
    linecolor : None or rgb color
        Color used for lines. ``colorscale`` has to be set to None, otherwise
        line colors are determined from ``colorscale``.
    title : str or None
        Title of ternary plot
    interp_mode : 'ilr' (default) or 'cartesian'
        Defines how data are interpolated to compute contours. If 'irl',
        ILR (Isometric Log-Ratio) of compositional data is performed. If
        'cartesian', contours are determined in Cartesian space.
    showmarkers : bool, default False
        If True, markers corresponding to input compositional points are
        superimposed on contours, using the same colorscale.

    Examples
    ========

    Example 1: ternary contour plot with filled contours

    >>> import plotly.figure_factory as ff
    >>> import numpy as np
    >>> # Define coordinates
    >>> a, b = np.mgrid[0:1:20j, 0:1:20j]
    >>> mask = a + b <= 1
    >>> a = a[mask].ravel()
    >>> b = b[mask].ravel()
    >>> c = 1 - a - b
    >>> # Values to be displayed as contours
    >>> z = a * b * c
    >>> fig = ff.create_ternary_contour(np.stack((a, b, c)), z)
    >>> fig.show()

    It is also possible to give only two barycentric coordinates for each
    point, since the sum of the three coordinates is one:

    >>> fig = ff.create_ternary_contour(np.stack((a, b)), z)


    Example 2: ternary contour plot with line contours

    >>> fig = ff.create_ternary_contour(np.stack((a, b, c)), z, coloring='lines')

    Example 3: customize number of contours

    >>> fig = ff.create_ternary_contour(np.stack((a, b, c)), z, ncontours=8)

    Example 4: superimpose contour plot and original data as markers

    >>> fig = ff.create_ternary_contour(np.stack((a, b, c)), z, coloring='lines',
    ...                                 showmarkers=True)

    Example 5: customize title and pole labels

    >>> fig = ff.create_ternary_contour(np.stack((a, b, c)), z,
    ...                                 title='Ternary plot',
    ...                                 pole_labels=['clay', 'quartz', 'fledspar'])
    NzH    The create_ternary_contour figure factory requires the scipy packageskimagezS    The create_ternary_contour figure factory requires the scikit-image
    packageF   )rK   )r   r   r   r   )ra   r   r   rK   r   r{   r|   )datalayoutr	   r   z: %{a:.3f}<br>z: %{b:.3f}<br>r   z3: %{c:.3f}<br>z: %{marker.color:.3f}<extra></extra>markerszrgb(120, 120, 120)r   )rt   r   )rt   r   r   )r   r   r   r   markeropacityhovertemplater   T)ZcminZcmaxr   	showscale)r   r   r   r   r   r   )rG   ImportErrorr   
get_moduler?   r   rD   rQ   r   r   goZFigureZadd_scatterternaryrE   r   Z	add_trace)rI   rJ   r   r   r   ra   r   r   r   r   r   rK   ZshowmarkersZ
sk_measurer{   r|   rP   rN   rO   r   Zcontour_tracer   Zfigr   r   r   r   r   Zcolorbarr   r   r   create_ternary_contour  s    a
   



r   )r   )r@   )N)Nr   r   r   Nr   r	   )Zplotly.colorsrc   r[   Zplotly.graph_objsr   r   Zplotlyr   r   r   r   rG   r   r   r   r   r&   r0   r5   r?   rQ   rU   rf   rh   rq   r   r   r   r   r   r   r   <module>   sV   

   
)
" 
.

2=       
 	