o
    .wi}8                     @   s  d dl mZmZ d dlmZ d dlmZmZmZ d dl	m
Z
mZmZmZmZ d dlZd dlZd dlmZ d dlmZmZmZ ermd dlZd dlZd dlmZ eejeejjej f f Z!ejjZ"eej#j$e%f Z&ej'j(Z)nee*e*f Z!e*Z"e*Z&d dl+m,Z, e,d	e
d
e
defddZ)erd dl-Z-ddgZ.ererdgndgZ.d2ddZ/e)e.						d3deeee e0e%ef ee0e%ef  f dee" dee1 dee2 dee2 dee% dee% de!fddZ3de4dee4e4f fddZ5dee2e2e2e2f de%fd d!Z6d"ee"ej f d#e4deej e"f fd$d%Z7e)e.e		&		d4d'edee" d(e1d)ee8ee4e%f   d*ee& de!fd+d,Z9e)e.						d3d-eeeeef eee ee ee f f d.ee dee" d/eee%e%f  dee% dee% d)ee8ee4e%f   de!fd0d1Z:dS )5    )	GeneratorSequence)product)ceilfloorsqrt)AnyListOptionalUnionno_type_checkN)Tensor)_LATEX_AVAILABLE_MATPLOTLIB_AVAILABLE_SCIENCEPLOT_AVAILABLE)contextmanagerargskwargsreturnc                  o   s    dV  dS )z0No-ops decorator if matplotlib is not installed.N )r   r   r   r   X/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/utilities/plot.pystyle_change*   s   
r   sciencezno-latexdefaultc                   C   s   t stddS )z+Raise error if matplotlib is not installed.z`Plot function expects `matplotlib` to be installed. Please install with `pip install matplotlib`N)r   ModuleNotFoundErrorr   r   r   r   _error_on_missing_matplotlib8   s
   r   valaxhigher_is_betterlower_boundupper_boundlegend_namenamec              	      s$  t   |du rt nd|f\}}| d ttrV dkr1|j	 
 gddd ntD ]\}}	|rB| d| n| }
|j||		 
 ddd|
d	 q5nttrt D ]?\}\}}	|	 dkr|j|		 
 ddd
|d	 | d |d |tt|	 qa|j||		 
 dd|d qanttr*t td trׇ fddd D  D ]\}}	|j|		 
 ddd
|d	 qn>tdjdk}|rjndtD ]$\}}	|r|r| d| n| nd}
|j|		 
 ddd
|
d	 q| d |d |t  ntd| \}}|rF|rF|j||dddddd | }|dur[|dur[d||  }n
d|d |d   }|j|durp|| n|d | |dur~|| n|d | d |d ||dur|nd | }d|d |d   }g }|dur| | |dur| | |j!||d |d ddd |dur|dur|s|"|d | |d  |j#|d |dddd |dur|r|"|d | |d  |j#|d |dddd ||fS )a  Plot a single metric value or multiple, including bounds of value if existing.

    Args:
        val: A single tensor with one or multiple values (multiclass/label/output format) or a list of such tensors.
            If a list is provided the values are interpreted as a time series of evolving values.
        ax: Axis from a figure.
        higher_is_better: Indicates if a label indicating where the optimal value it should be added to the figure
        lower_bound: lower value that the metric can take
        upper_bound: upper value that the metric can take
        legend_name: for class based metrics specify the legend prefix e.g. Class or Label to use when multiple values
            are provided
        name: Name of the metric to use for the y-axis label

    Returns:
        A tuple consisting of the figure and respective ax objects of the generated figure

    Raises:
        ModuleNotFoundError:
            If `matplotlib` is not installed

    NF   o
   )marker
markersize None)r&   r'   	linestylelabel-TStep)r&   r'   r+   r   c                    s,   i | ]  t  fd dtD qS )c                    s   g | ]}|   qS r   r   ).0i)kr   r   r   
<listcomp>v   s    z7plot_single_or_multi_val.<locals>.<dictcomp>.<listcomp>)torchstackrange)r.   n_stepsr   )r0   r   
<dictcomp>v   s   , z,plot_single_or_multi_val.<locals>.<dictcomp> z&Got unknown format for argument `val`.zupper center)g      ?gffffff?   )locbbox_to_anchorncolfancyboxshadowg?)bottomtopdashedr0   )
linestylescolorszOptimal 
 valuecenter)shorizontalalignmentverticalalignment)$r   pltsubplots	get_xaxisset_visible
isinstancer   numelplotdetachcpu	enumeratedictitems
set_xlabel
set_xticksr2   arangelenr   r3   ndimT	unsqueeze
ValueErrorget_legend_handles_labelslegendget_ylimset_ylimgrid
set_ylabelget_xlimappendhlinesset_xlimtext)r   r   r   r   r    r!   r"   figr/   vr+   r0   multi_serieshandleslabelsylimfactorxlimy_linesr   r5   r   plot_single_or_multi_val@   s   
 


$






rp   nc                 C   sX   t | }t||krt|t|fS t|t| | kr$t|t|fS t|t|fS )z/Split `n` figures into `rows` x `cols` figures.)r   intr   r   )rq   nsqr   r   r   _get_col_row_split   s   rt   patch_colorc                 C   sN   | \}}}}dd |||fD \}}}d| d|  d|  }|dkr%dS dS )	zGet the text color for a given value and colormap.

    Following Wikipedia's recommendations: https://en.wikipedia.org/wiki/Relative_luminance.

    Args:
        patch_color: RGBA color tuple

    c                 s   s0    | ]}|d kr|d n|d d d V  qdS )g?ܵ?gףp=
)@g)\(?gzG?g333333@Nr   )r.   cr   r   r   	<genexpr>   s   . z"_get_text_color.<locals>.<genexpr>gz6?g,C?g]m{?g?z.1whiter   )ru   rgbayr   r   r   _get_text_color   s   
r~   axsnbc                 C   s:   t | tr| S | j} | |d D ]}|  q| d| S )zSReduce `axs` to `nb` Axes.

    All further Axes are removed from the figure.

    N)rL   _AX_TYPEflatremove)r   r   r   r   r   r   trim_axs   s   

r   Tconfmatadd_textrk   cmapc                 C   sz  t   | jdkr| jd d}}t|\}}nd| jd ddf\}}}}|dur?| jdkr?t||kr?tdt| d| | jdkrU|pJt|}	tt	t
t|}nd}	|p_t| }|du rltj||dd	n| |f\}
}t||}t|D ]}|dks|dkr|| n|}|	dur|jd
|	|  dd |j| jdkr| |   n|   |d}|| |d kr|jddd || dkr|jddd |tt| |tt| |j|ddd |j|ddd |r8tt|t|D ]8\}}| jdkr| |||f n| ||f }||| }t|}|j ||t
t!| dddd|d qq}|
|fS )a  Plot an confusion matrix.

    Inspired by: https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/metrics/_plot/confusion_matrix.py.
    Works for both binary, multiclass and multilabel confusion matrices.

    Args:
        confmat: the confusion matrix. Either should be an [N,N] matrix in the binary and multiclass cases or an
            [N, 2, 2] matrix for multilabel classification
        ax: Axis from a figure. If not provided, a new figure and axis will be created
        add_text: if text should be added to each cell with the given value
        labels: labels to add the x- and y-axis
        cmap: matplotlib colormap to use for the confusion matrix
            https://matplotlib.org/stable/users/explain/colors/colormaps.html

    Returns:
        A tuple consisting of the figure and respective ax objects (or array of ax objects) of the generated figure

    Raises:
        ModuleNotFoundError:
            If `matplotlib` is not installed

    r9   r      r#   NzYExpected number of elements in arg `labels` to match number of labels in confmat but got  and T)nrowsncolsconstrained_layoutzLabel    )fontsize)r   zPredicted classz
True class-   r%   )rotationr      rD   )havar   color)"r   rX   shapert   rW   r[   nprV   listmapstrr4   tolistrH   rI   
get_figurer   	set_titleimshowrP   rO   rT   ra   rU   
set_yticksset_xticklabelsset_yticklabelsr   r   normitemr~   rf   round)r   r   r   rk   r   r   	n_classesrowscols	fig_labelrg   r   r/   imiijjr   ru   rv   r   r   r   plot_confusion_matrix   sR   

(
0&(r   curvescorelabel_namesc                 C   s:  t | dk rtdt |  | dd \}}t  |du r"t nd|f\}	}t|tret|tre|jdkre|jdkre|durHd| dnd}
|j	|
  |
  dd|
d |
durd|  nt|trot|tst|trt|tr|jdkr|jdkrt |}|durt ||krtd	t | d
| tt||D ]G\}\}}|dur| d| n|du rt|nt|| }
|
|durd||  dnd7 }
|j	|
  |
  dd|
d |  qntdt| d
t| d|dur||d  ||d  |d || |	|fS )a  Inspired by: https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/metrics/_plot/roc_curve.py.

    Plots a curve object

    Args:
        curve: a tuple of (x, y, t) where x and y are the coordinates of the curve and t are the thresholds used
            to compute the curve
        score: optional area under the curve added as label to the plot
        ax: Axis from a figure
        label_names: Tuple containing the names of the x and y axis
        legend_name: Name of the curve to be used in the legend
        name: Custom name to describe the metric
        labels: Optional labels for the different curves that will be added to the plot

    Returns:
        A tuple consisting of the figure and respective ax objects (or array of ax objects) of the generated figure

    Raises:
        ModuleNotFoundError:
            If `matplotlib` is not installed
        ValueError:
            If `curve` does not have 3 elements, being in the wrong format
    r   z*Expected 2 or 3 elements in curve but got Nr#   zAUC=z0.3fr,   )r*   	linewidthr+   z\Expected number of elements in arg `labels` to match number of labels in roc curves but got r   _z AUC=r8   zQUnknown format for argument `x` and `y`. Expected either list or tensors but got .r   T)rW   r[   r   rH   rI   rL   r   rX   r   rN   rO   rP   r]   r   rQ   zipr   typerT   ra   r`   r   )r   r   r   r   r!   r"   rk   xr}   rg   r+   r   r/   x_y_r   r   r   
plot_curve(  sR   !($2$$



r   )r   N)NNNNNN)NTNN);collections.abcr   r   	itertoolsr   mathr   r   r   typingr   r	   r
   r   r   numpyr   r2   r   torchmetrics.utilities.importsr   r   r   
matplotlibmatplotlib.axesmatplotlib.pyplotpyplotrH   tupleFigureaxesAxesndarray_PLOT_OUT_TYPEr   rC   Colormapr   
_CMAP_TYPEstylecontextr   object
contextlibr   scienceplots_styler   rR   boolfloatrp   rr   rt   r~   r   r   r   r   r   r   r   r   <module>   s   

&n
*K*