a
    d2                     @   s|  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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rd 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j#j$Z%n2ee&e&f Z!e&Z"d dl'm(Z( e(eee	dd	d
Z%erd dl)Z)ddgZ*er$er$dgndgZ*ddddZ+e%e*d!eeee ee,ef eee,ef  f ee" ee- ee. ee. ee, ee, e!dddZ/e0ee0e0f dddZ1ee"ej f e0eej e"f dddZ2e%e*ed"eee" e-ee
ee0e,f   e!dddZ3e%e*d#eeeeef ee
e e
e e
e f f ee ee" eee,e,f  ee, ee, e!ddd Z4dS )$    )product)ceilfloorsqrt)	AnyDict	GeneratorListOptionalSequenceTuple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   d/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/utilities/plot.pystyle_change'   s    r   Zsciencezno-latexdefault)r   c                   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_matplotlib5   s    r   )valaxhigher_is_betterlower_boundupper_boundlegend_namenamer   c              	      s4  t   |du rt nd|f\}}| d ttr dkrb|j	 
 gddd nHtD ]>\}}	|r| d| n| }
|j||		 
 ddd|
d	 qjnttrLt D ]\}\}}	|	 dkr*|j|		 
 ddd
|d	 | d |d |tt|	 q|j||		 
 dd|d qƐn ttrdt td tr fddd D  D ]&\}}	|j|		 
 ddd
|d	 qntdjdk}|r܈jndtD ]J\}}	|r|r| d| n| nd}
|j|		 
 ddd
|
d	 q| d |d |t  ntd| \}}|r|r|j||dddddd | }|dur|durd||  }nd|d |d   }|j|dur|| n
|d | |dur|| n
|d | d |d ||dur8|nd | }d|d |d   }g }|durr| | |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-TZ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>s       z7plot_single_or_multi_val.<locals>.<dictcomp>.<listcomp>)torchstackrange)r.   Zn_stepsr   )r0   r   
<dictcomp>s   r2   z,plot_single_or_multi_val.<locals>.<dictcomp> z&Got unknown format for argument `val`.zupper center)g      ?gffffff?   )locZbbox_to_anchorZncolZfancyboxZshadowg?)ZbottomtopZdashedr0   )Z
linestylescolorszOptimal 
 valuecenter)sZhorizontalalignmentZverticalalignment)$r   pltsubplotsZ	get_xaxisZset_visible
isinstancer   Znumelplotdetachcpu	enumeratedictitems
set_xlabel
set_xticksr3   arangelenr   r4   ndimTZ	unsqueeze
ValueErrorZget_legend_handles_labelslegendZget_ylimZset_ylimgrid
set_ylabelZget_xlimappendZhlinesZset_xlimtext)r   r   r   r    r!   r"   r#   figr/   vr,   r0   Zmulti_seriesZhandleslabelsZylimZfactorZxlimZy_linesr   r6   r   plot_single_or_multi_val=   s    
$
""
$ 






rW   )nr   c                 C   sX   t | }|| | kr$t|t|fS t|t| | krHt|t|fS t|t|fS )z/Split `n` figures into `rows` x `cols` figures.)r   intr   r   )rX   Znsqr   r   r   _get_col_row_split   s    rZ   )axsnbr   c                 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)rA   _AX_TYPEZflatremove)r[   r\   r   r   r   r   trim_axs   s    

r_   T)confmatr   add_textrV   r   c              
   C   s>  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r|pt|}tt	t
t|}nd}|pt| }|du rtj||dn
| |f\}	}
t|
|}
t|D ]:}|dkr|dkr|
| n|
}|dur@|jd	||  d
d || jdkr`| |   n
|    |jdd
d |jdd
d |tt| |tt| |j|ddd |j|ddd |rtt|t|D ]N\}}| jdkr| |||f n
| ||f }|j||t
| 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

    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 )ZnrowsZncolszLabel    )fontsizezPredicted classz
True class-   r&   )Zrotationre      r=   )Zhavare   )r   rL   shaperZ   rK   rN   nprJ   listmapstrr5   tolistr?   r@   Z
get_figurer_   	set_titleZimshowrD   rC   rH   rQ   rI   Z
set_yticksZset_xticklabelsZset_yticklabelsr   rS   item)r`   r   ra   rV   r\   Z	n_classesrowscolsZ	fig_labelrT   r[   r/   iiZjjr   r   r   r   plot_confusion_matrix   sH    

&
 
.&$rt   )curvescorer   label_namesr"   r#   r   c                 C   s  t | dk rtd| dd \}}t  |du r:t nd|f\}}t|trt|tr|jdkr|jdkr|durd| dnd}	|j	|
  |
  dd|	d |dur||d	  ||d  |	dur|  nt|trt|ts*t|trt|tr|jdkr|jdkrtt||D ]|\}
\}}|dur\| d
|
 nt|
}	|	|durd||
  dnd7 }	|j	|
  |
  |	d |  q8ntdt| dt| d|d || ||fS )aw  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

    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
    rb   z6Expected 2 or 3 elements in curve but got {len(curve)}Nr$   zAUC=z0.3fr-   )r+   Z	linewidthr,   r   _z AUC=r8   )r,   zQUnknown format for argument `x` and `y`. Expected either list or tensors but got rc   .T)rK   rN   r   r?   r@   rA   r   rL   rp   rB   rC   rD   rH   rQ   rO   rk   rE   ziprm   typerP   ro   )ru   rv   r   rw   r"   r#   xyrT   r,   r/   Zx_Zy_r   r   r   
plot_curve  sB    ($
 & 

r~   )NNNNNN)NTN)NNNNN)5	itertoolsr   mathr   r   r   typingr   r   r   r	   r
   r   r   r   r   numpyrj   r3   r   Ztorchmetrics.utilities.importsr   r   r   Z
matplotlibZmatplotlib.axesZmatplotlib.pyplotZpyplotr?   ZFigureZaxesZAxesZndarrayZ_PLOT_OUT_TYPEr]   stylecontextr   object
contextlibr   Zscienceplots_styler   rm   boolfloatrW   rY   rZ   r_   rt   r~   r   r   r   r   <module>   s   ,
      &n
&   D     *