Ë
    ëÓ^jóH  ã                  óh  — U d Z ddl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rddlmZ  ej                  d«      ZdZ	 ddlZd	Zd
ed<   edœ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#d„Z	 d$	 	 	 	 	 d%d„Zd&d„Z	 	 d"	 	 	 	 	 	 	 d#d„Zy# e$ r dZY Œfw xY w)'u\  Post-training metrics plotting utilities.

Reads the ``metrics.csv`` written by PTL's ``CSVLogger`` (always present after a ``build_trainer``-based run) and builds
seaborn figures grouped by metric type (Loss, AP@0.50, AP@0.50:0.95, AR).

Loss panel shows aggregate and component loss scalars. AP/AR panels show all ``train/``, ``val/``, and ``test/``
columns for each group â€” both the base and EMA series when EMA is enabled, so both are visible in the legend.

Usage::

    from rfdetr.visualize.training import plot_metrics
    fig = plot_metrics("output/rfdetr_base/metrics.csv")
    plt.show(fig)
é    )ÚannotationsN)ÚPath)ÚTYPE_CHECKINGÚAnyÚOptional)ÚFigurez_\d+$é   TÚboolÚ_IS_SEABORN_AVAILABLEF)Ú	n_columnsc               óš   — | j                  «       \  }}|sy| j                  ||ddt        |t        dt	        |«      «      «      dd¬«       y)z<Place a compact multi-column legend below a matplotlib axes.Nzupper center)g      à?g
×£p=
Ç¿é   é	   T)ÚlocÚbbox_to_anchorÚncolÚfontsizeÚframeon)Úget_legend_handles_labelsÚlegendÚminÚmaxÚlen)Úaxr   ÚhandlesÚlabelss       úd/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/visualize/training.pyÚ_place_legend_below_axesr   *   sR   € à×2Ñ2Ó4�O€GˆVÙØØ‡I�IØØØØ#Ü�œC ¤3 v£;Ó/Ó0ØØð õ ó    c                óH   — | j                  d«      \  }}}|r|dv r||fS d| fS )zBSplit a CSVLogger metric column into split prefix and metric name.ú/>   ÚvalÚtestÚtrainÚ )Ú	partition)ÚcolumnÚsplitÚ	separatorÚmetric_names       r   Ú_split_metric_columnr+   :   s9   € à$*×$4Ñ$4°SÓ$9Ñ!€Eˆ9�kÙ�UÐ6Ñ6Ø�kÐ!Ð!Øˆvˆ:Ðr   c                ó   — | dk(  ry| dk(  ryy)z2Return the plotting line style for a metric split.r$   ú:r#   z-.ú-© )r(   s    r   Ú_line_style_for_splitr0   B   s   € à�ÒØØ�‚ØØr   c                ó`  — 	 ddl m} |j                  d   j	                  «       j                  dg «      }i }|D ]­  }t        |«      \  }	}
|
|vr!|r|t        |«      t        |«      z     nd||
<   ||
   }t        |	«      }t        rEddl
}|d|g   j                  |g¬«      }|j                  rŒu	 |j                  |d|| d	||d
|¬«	       Œ‘| j                  |d   ||   d
|||¬«       Œ¯ y# t        $ r}t        d«      |‚d}~ww xY w# t        $ r |j                  |d|| d||d
|¬«	       Y Œów xY w)u  Plot columns with color by metric name and line style by split.

    When seaborn is installed, draws mean Â± 1 std-dev bands computed from within-epoch step-level rows in ``raw_df``.
    Falls back to epoch-averaged lines from ``epoch_df`` when seaborn is absent.
    r   NúYmatplotlib is required for training metric plots. Install it with: pip install matplotlibzaxes.prop_cycleÚcolorÚC0Úepoch)Úsubset)Úsdr   g333333û?)	ÚdataÚxÚyr   Úerrorbarr3   Ú	linestyleÚ	linewidthÚlabelr7   )	r8   r9   r:   r   Úcir3   r<   r=   r>   )r=   r<   r3   r>   )Úmatplotlib.pyplotÚpyplotÚImportErrorÚrcParamsÚby_keyÚgetr+   r   r0   r   ÚseabornÚdropnaÚemptyÚlineplotÚ	TypeErrorÚplot)r   Úraw_dfÚepoch_dfÚmetric_columnsÚpltÚexcÚcolor_cycleÚmetric_colorsr'   r(   r*   r3   r<   ÚsnsÚcol_datas                  r   Ú_plot_columns_on_axesrU   K   s‚  € ðÝ'ð —,‘,Ð0Ñ1×8Ñ8Ó:×>Ñ>¸wÈÓK€KØ$&€Mà ò -ˆÜ1°&Ó9Ñˆˆ{Ø˜mÑ+Ù_j¨´S¸Ó5GÌ#ÈkÓJZÑ5ZÒ)[ÐptˆM˜+Ñ&Ø˜kÑ*ˆÜ)¨%Ó0ˆ	å Û!à˜w¨Ð/Ñ0×7Ñ7À¸xÐ7ÓHˆHØ—>“>ðØ—L‘LØ%Ø!Ø ØØ!*Ø#Ø"+Ø"%Ø$ð !õ 
ð2 �G‰GØ˜Ñ!Ø˜Ñ ØØ#ØØð õ ñM-øô ò ÜØgó
àð	ûðûô@ !ò à—L‘LØ%Ø!Ø ØØØ#Ø"+Ø"%Ø$ð !ö 
ðús)   ‚C* Â/DÃ*	DÃ3C?Ã?DÄ#D-Ä,D-c                óª  ‡ — dˆ fd„}dd„}‰ j                   D �cg c]8  } |t        |«      «      sŒ‰ |   j                  «       j                  «       sŒ7|‘Œ: }} |dd«      D �cg c]  }d|vsŒd|vsŒ|‘Œ }} |dd«      } |ddd	«      D �cg c]  }d|vsd|v sŒ|‘Œ }} |d
d«      D �cg c]	  }d|vsŒ|‘Œ }	} |dd«      D �cg c]  }d|vsŒd|vsŒ|‘Œ }
} |dd«      } |dd«      } |dd«      } |ddd«      }|||||	|
||||dœ
}|j	                  «       D ��ci c]  \  }}|sŒ	||“Œ c}}S c c}w c c}w c c}w c c}w c c}w c c}}w )a  Build plot groups from numeric PTL CSVLogger metrics.

    Args:
        df: DataFrame-like object with metric columns.

    Returns:
        Non-empty metric groups keyed by subplot title.

    Raises:
        AttributeError: If ``df`` does not provide DataFrame-like columns.
    c                 óÜ   •‡— d}‰j                   D �‡cg c]M  Š‰j                  |«      sŒt        ˆfd„| D «       «      sŒ*‰‰   j                  «       j                  «       sŒL‰‘ŒO c}S c c}w )zLReturn split-prefixed columns whose name contains any of the given patterns.)útrain/úval/útest/c              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­w©Nr/   )Ú.0ÚpÚcs     €r   ú	<genexpr>z<_build_metric_groups.<locals>._split_cols.<locals>.<genexpr>œ   s   øè ø€ ÒC]ÈqÀAÈÄFÑC]ùs   ƒ)ÚcolumnsÚ
startswithÚanyÚnotna)ÚpatternsÚprefixesr_   Údfs     `€r   Ú_split_colsz)_build_metric_groups.<locals>._split_cols˜   s]   ù€ à.ˆà—z‘z÷
Ø Q§\¡\°(Õ%;ÄÓC]ÐT\ÔC]Õ@]ÐbdÐefÑbg×bmÑbmÓbo×bsÑbsÕbuŠAò
ð 	
ùò 
s   ”A)«A)Á !A)Á"A)c                ó®   — | dv ry| j                  dd¬«      d   j                  «       }t        j                  |«      ryd|v xs |j	                  d«      S )	z0Return whether a metric column is a loss scalar.>   Ústepr5   Fr!   r   )ÚmaxsplitéÿÿÿÿÚlossÚkp_)ÚrsplitÚlowerÚ_AUXILIARY_LOSS_SUFFIX_REÚsearchrb   )ÚnameÚleafs     r   Ú_is_loss_colz*_build_metric_groups.<locals>._is_loss_colŸ   sW   € àÐ$Ñ$ØØ�{‰{˜3¨ˆ{Ó+¨BÑ/×5Ñ5Ó7ˆÜ$×+Ñ+¨DÔ1ØØ˜ˆ~Ò7 §¡°Ó!7Ð7r   ÚmAP_50Ú
ema_mAP_50Ú	mAP_50_95ÚmAP_75Ú
ema_mAP_75Úema_mAP_50_95z/AP/ÚmARÚema_mARÚ	keypoint_Úkeypoint_map_50Úema_keypoint_map_50Ú	map_50_95Úmap_75Úkeypoint_map_75Úema_keypoint_map_75Úkeypoint_map_50_95Úema_keypoint_map_50_95Úkeypoint_mARÚema_keypoint_mARÚF1Ú	precisionÚrecall)
ÚLossúDetection AP@0.50úDetection AP@0.50:0.95úDetection AP@0.75zDetection ARúKeypoint AP@0.50úKeypoint AP@0.50:0.95úKeypoint AP@0.75zKeypoint ARzF1 / Precision / Recall)re   ÚstrÚreturnú	list[str])rs   r“   r”   r
   )ra   r“   rd   rc   Úitems)rg   rh   ru   rs   Ú	loss_colsr_   Údetection_map_50Údetection_map_75Údetection_map_50_95Údetection_marr   rƒ   r…   Úkeypoint_marÚf1_precision_recallÚmetric_groupsra   s   `                r   Ú_build_metric_groupsrŸ   ‹   s´  ø€ õ
ó8ð #%§*¡*Öc˜$±¼SÀ»YÕ0GÈBÈtÉHÏNÉNÓL\×L`ÑL`ÕLb’Ðc€IÐcÙ#.¨x¸Ó#FÖu˜aÈ+Ð]^ÒJ^ÐckÐstÒctšÐuÐÐuÙ" 8¨\Ó:Ðá˜{¨O¸VÓDöØÈÐXYÑHYÐ]hÐlmÒ]mŠðÐð ñ !,¨E°9Ó =ÖV˜1ÀÐTUÒAU’QÐV€MÐVáÐ0Ð2GÓHöØÈKÐ_`ÒL`ÐemÐuvÒevŠð€Oð ñ "Ð"3Ð5JÓK€OÙ$Ð%9Ð;SÓTÐÙ˜~Ð/AÓB€LÙ% d¨K¸ÓBÐð Ø-Ø"5Ø-Ø%Ø+Ø!3Ø+Ø#Ø#6ñ+€Mð 0=×/BÑ/BÓ/D×P™m˜d GÊˆD�'‰MÓPÐPùò7 dùÚuùòùò Wùòùó( QsX   šD6±!D6ÁD6Á$	D;Á.D;Á3D;ÂE ÂE Â-	EÂ7EÃ	E
ÃE
ÃE
Ä"
EÄ-Ec                óh  — 	 ddl }t        | «      }|j                  «       st	        d|› �«      ‚|j                  |«      }d|j                  vrt        d«      ‚t        |«      }|j                  d«      j                  d¬«      j                  «       }||fS # t        $ r}t        d«      |‚d}~ww xY w)	aR  Read a PTL CSVLogger metrics file and return both step-level and epoch-averaged DataFrames.

    Returns:
        A ``(raw_df, epoch_df)`` pair where ``raw_df`` contains every logged row
        (one per training step or validation epoch) and ``epoch_df`` is the per-epoch
        mean used for column detection and log-scale checks.
    r   NzQpandas is required for training metric plots. Install it with: pip install pandaszmetrics.csv not found: r5   z/metrics.csv does not contain an 'epoch' column.T)Únumeric_only)ÚpandasrB   r   ÚexistsÚFileNotFoundErrorÚread_csvra   Ú
ValueErrorÚ%_drop_trailing_validation_only_epochsÚgroupbyÚmeanÚreset_index)Úmetrics_csvÚpdrP   Úcsv_pathrg   rL   rM   s          r   Ú_read_metrics_csvr®   Æ   s·   € ðxÛô �KÓ €HØ�?‰?ÔÜÐ"9¸(¸Ð DÓEÐEà	�‰�XÓ	€BØ�b—j‘jÑ ÜÐJÓKÐKÜ2°2Ó6€FØ�~‰~˜gÓ&×+Ñ+¸Ð+Ó>×JÑJÓL€HØ�8ÐÐøô ò xÜÐmÓnÐtwÐwûðxús   ‚B Â	B1Â B,Â,B1c                óÀ  — | j                   D �cg c]  }t        |«      j                  d«      sŒ|‘Œ! }}| j                   D �cg c]  }t        |«      j                  d«      sŒ|‘Œ! }}|r|s| S | |   j                  «       j	                  d¬«      s| S | }t        |«      dkD  r°|d   j                  d   }|d   |k(  }|j                  |   }|j                  |    j                  r|S ||   j                  «       j	                  d¬«      }||   j                  «       j	                  d¬«      }	|s|	s|S |j                  |    }t        |«      dkD  rŒ°|S c c}w c c}w )a�  Remove post-fit validation rows that Lightning logs as a synthetic final epoch.

    The Roboflow finetune demos run ``trainer.validate(...)`` after ``trainer.fit(...)`` to write a final metrics JSON.
    PTL appends that validation pass to the same ``CSVLogger`` file using ``epoch == max_epochs``. That row is useful as
    a standalone final validation result, but it is not part of the training curve and can create a misleading last-
    epoch jump in plots. Only trailing epochs with validation/test metrics and no training metrics are removed, and only
    when the CSV also contains real training rows. Pure validation CSV files are preserved.
    rX   )rY   rZ   N©Úaxisr   r5   rl   )	ra   r“   rb   rd   rc   r   Úilocr   rH   )
rg   r'   Útrain_columnsÚeval_columnsÚcleanedÚ
last_epochÚ
epoch_maskÚ
epoch_rowsÚhas_train_metricsÚhas_eval_metricss
             r   r§   r§   ß   s\  € ð +-¯*©*ÖY ¼¸F»×8NÑ8NÈxÕ8X’VÐY€MÐYØ)+¯©Öa˜v´s¸6³{×7MÑ7MÐN_Õ7`’FÐa€LÐaÙ¡Øˆ	ØˆmÑ×"Ñ"Ó$×(Ñ(¨dÐ(Ô3Øˆ	à€GÜ
ˆg‹,˜Ò
Ø˜WÑ%×*Ñ*¨2Ñ.ˆ
Ø˜WÑ%¨Ñ3ˆ
Ø—[‘[ Ñ,ˆ
Ø�;‰;˜
�{Ñ#×)Ò)ØˆNØ& }Ñ5×;Ñ;Ó=×AÑAÀtÐAÓLÐØ% lÑ3×9Ñ9Ó;×?Ñ?ÀTÐ?ÓJÐÙÑ$4ØˆNØ—+‘+˜z˜kÑ*ˆô ˆg‹,˜Ó
ð €Nùò' ZùÚas   �E¯EÁEÁ#Ec               óú  — 	 ddl }|j                  d«       ddlm} |st        d«      ‚t        |«      }	|	dk(  rdnd}
|	|
z   dz
  |
z  }|j                  ||
dd	|z  fd
¬«      \  }}|j                  «       }t        |j                  «       «      D ]È  \  }\  }}||   }t        || ||«       |j                  |dd¬«       |j                  dd¬«       |j                  |d¬«       |j                  dd¬«       |dk(  rJ|rH||   }|dk  j!                  d¬«      rt#        j$                  dt&        d¬«       n|j)                  d«       |dk(  sŒ¾t+        |«       ŒÊ t-        |	t        |«      «      D ]  }||   j/                  d
«       Œ |j1                  |d¬«       |j3                  «        d|v r|j5                  |	dk(  rdnd¬«       |�|j7                  |dd¬ «       |S # t        $ r}t	        d«      |‚d}~ww xY w)!z#Build a figure for grouped metrics.r   NÚAggr2   zDmetrics.csv does not contain any supported non-empty metric columns.r   é   é   é   F)ÚfigsizeÚsqueezeé   Úbold©r   Ú
fontweightÚEpoché   ©r   Tç333333Ó?©ÚalpharŒ   r°   zvloss_log_scale=True was requested, but at least one loss value is non-positive; using linear scale for the Loss panel.)Ú
stacklevelÚlogé   ç¸…ëQ¸Î?g¸…ëQ¸¾?©Úbottomé–   Útight©ÚdpiÚbbox_inches)Ú
matplotlibÚuser@   rA   rB   r¦   r   ÚsubplotsÚflattenÚ	enumerater–   rU   Ú	set_titleÚ
set_xlabelÚ
set_ylabelÚgridrc   ÚwarningsÚwarnÚUserWarningÚ
set_yscaler   ÚrangeÚset_visibleÚsuptitleÚtight_layoutÚsubplots_adjustÚsavefig)rL   rM   rž   ÚtitleÚoutput_pathÚloss_log_scaler×   rO   rP   Ún_groupsÚn_colsÚn_rowsÚfigÚaxesÚ	axes_flatÚidxÚsubplot_titleÚmetric_listr   Ú
group_datas                       r   Ú_plot_metric_groupsr÷   þ   s  € ðÛà�‰�uÔÝ'ñ ÜÐ_Ó`Ð`ä�=Ó!€HØ˜a’-‰Q Q€FØ˜Ñ !Ñ#¨Ñ.€Fà—‘˜V V°b¸!¸f¹*Ð5EÈu�ÓU�I€CˆØ—‘“€Iä-6°}×7JÑ7JÓ7LÓ-Mò )Ñ)ˆÑ)ˆm˜[Ø�s‰^ˆÜ˜b &¨(°KÔ@Ø
�‰�]¨R¸FˆÔCØ
�‰�g¨ˆÔ+Ø
�‰�m¨bˆÔ1Ø
�‰�˜CˆÔ Ø˜FÒ"¡~Ø! +Ñ.ˆJØ˜a‘×$Ñ$¨$Ð$Ô/Ü—‘ð=äØ ö	ð —‘˜eÔ$Ø˜FÓ"Ü$ RÕ(ð')ô* �Xœs 9›~Ó.ò *ˆØ�#‰×"Ñ" 5Õ)ð*ð ‡L�L� €LÔ$Ø×ÑÔØ�ÑØ×Ñ¨8°qª=¡4¸dÐÔCØÐØ�‰�K S°gˆÔ>Ø€Jøô[ ò ÜØgó
àð	ûðús   ‚G  Ç 	G:Ç)G5Ç5G:c                ól   — t        | «      \  }}t        |«      }t        ||d|v rd|d   ini d||¬«      S )uE  Plot aggregate and component training losses from a PTL ``metrics.csv`` file.

    Reads the CSV written by PyTorch Lightning's ``CSVLogger``, groups loss columns
    (aggregate loss, per-component scalars, and keypoint NLL terms) into a single panel,
    and renders an optional seaborn error-band overlay when seaborn is installed.

    Args:
        metrics_csv: Path to the ``metrics.csv`` written by PTL's ``CSVLogger``.
        output_path: Optional filesystem path to save the rendered figure (PNG, PDF, â€¦).
            When ``None`` the figure is returned but not written to disk.
        loss_log_scale: When ``True``, the loss y-axis uses a logarithmic scale.
            Useful when loss components span several orders of magnitude.

    Returns:
        A ``matplotlib.figure.Figure`` containing the loss panel.

    Raises:
        FileNotFoundError: When ``metrics_csv`` does not exist.
        ImportError: When ``pandas`` or ``matplotlib`` is not installed.
        ValueError: When ``metrics_csv`` contains no loss columns.

    Examples:
        .. code-block:: python

            from rfdetr.visualize.training import plot_loss_metrics
            fig = plot_loss_metrics("output/rfdetr_small/metrics.csv")
            fig = plot_loss_metrics("output/rfdetr_small/metrics.csv", output_path="loss.png", loss_log_scale=True)
    rŒ   zRF-DETR Loss Metrics©rê   rë   rì   ©r®   rŸ   r÷   )r«   rë   rì   rL   rM   Úgroupss         r   Úplot_loss_metricsrü   =  sO   € ôB )¨Ó5Ñ€FˆHÜ! (Ó+€FÜØØØ$*¨fÑ$4ˆ�˜‘Ñ ¸"Ø$ØØ%ôð r   c                óØ   — t        | «      \  }}t        |«      }|j                  «       D ���cg c]  \  }}|dv r	|D ]  }|‘Œ Œ }}}}|st        d«      ‚t	        ||||¬«      S c c}}}w )uø  Plot train/val/test detection and keypoint mAP metrics from a PTL ``metrics.csv`` file.

    Reads the CSV written by PyTorch Lightning's ``CSVLogger``, selects all AP-family
    columns (AP@0.50, AP@0.75, AP@0.50:0.95 for both detection and keypoints), and renders
    them in a single combined panel.  EMA series are included when present so both live and
    EMA metric trajectories are visible in the legend.

    Args:
        metrics_csv: Path to the ``metrics.csv`` written by PTL's ``CSVLogger``.
        output_path: Optional filesystem path to save the rendered figure (PNG, PDF, â€¦).
            When ``None`` the figure is returned but not written to disk.

    Returns:
        A ``matplotlib.figure.Figure`` containing the combined mAP panel.

    Raises:
        FileNotFoundError: When ``metrics_csv`` does not exist.
        ImportError: When ``pandas`` or ``matplotlib`` is not installed.
        ValueError: When ``metrics_csv`` contains no supported mAP metric columns.

    Examples:
        .. code-block:: python

            from rfdetr.visualize.training import plot_map_metrics
            fig = plot_map_metrics("output/rfdetr_small/metrics.csv")
            fig = plot_map_metrics("output/rfdetr_small/metrics.csv", output_path="map.png")
    >   r�   r’   r�   r�   r‘   rŽ   zHmetrics.csv does not contain any supported non-empty mAP metric columns.)rë   )r®   rŸ   r–   r¦   Ú_plot_map_columns)	r«   rë   rL   rM   rž   Ú
group_namera   r'   Úmap_columnss	            r   Úplot_map_metricsr  j  s™   € ô> )¨Ó5Ñ€FˆHÜ(¨Ó2€Mð $1×#6Ñ#6Ó#8÷ð áˆJ˜Øð
ñ
ð òð ò 	ðØð€Kò ñ ÜÐcÓdÐdÜ˜V X¨{ÈÔTÐTùô!s   ®A%c               óÞ  — 	 ddl }|j                  d«       ddlm} |j                  d¬«      \  }}t        || ||«       |j                  ddd	¬
«       |j                  dd¬«       |j                  dd¬«       |j                  dd¬«       t        |«       |j                  «        |j                  d¬«       |�|j                  |dd¬«       |S # t        $ r}t	        d«      |‚d}~ww xY w)z;Plot mAP metrics on a single axes with line style by split.r   Nr¼   zTmatplotlib is required for mAP metric plots. Install it with: pip install matplotlib)r¾   é   )rÀ   zRF-DETR mAP MetricsrÂ   rÃ   rÄ   rÆ   rÇ   rÈ   ÚmAPTrÉ   rÊ   rÏ   rÐ   rÒ   rÓ   rÔ   )r×   rØ   r@   rA   rB   rÙ   rU   rÜ   rÝ   rÞ   rß   r   rç   rè   ré   )	rL   rM   rN   rë   r×   rO   rP   rð   r   s	            r   rþ   rþ   ž  sç   € ðÛà�‰�uÔÝ'ð �l‰l 7ˆlÓ+�G€CˆÜ˜"˜f h°Ô?à‡L�LÐ&°À€LÔGØ‡M�M�' B€MÔ'Ø‡M�M�% "€MÔ%Ø‡G�GˆD˜€GÔÜ˜RÔ Ø×ÑÔØ×Ñ˜tÐÔ$ØÐØ�‰�K S°gˆÔ>Ø€Jøô# ò ÜØbó
àð	ûðús   ‚C Ã	C,ÃC'Ã'C,c                óV   — t        | «      \  }}t        |«      }t        |||d||¬«      S )uï  Read a PTL ``CSVLogger`` metrics file and build a training plot.

    The figure contains one subplot per metric group (loss, detection metrics,
    keypoint metrics, and F1/precision/recall), arranged in a 2-column grid.
    Only groups with at least one non-NaN column are shown.

    When seaborn is installed, each series is drawn as mean Â± 1 std-dev band
    computed from the within-epoch step-level rows logged by PTL's
    ``CSVLogger``.  Metrics recorded only once per epoch (e.g. ``val/mAP_50``)
    show a plain line because their per-epoch std is zero.  When seaborn is
    absent the plot falls back to epoch-averaged lines.

    Args:
        metrics_csv: Path to the ``metrics.csv`` file produced by
            ``CSVLogger``.
        output_path: Optional destination for the PNG file. If omitted, the
            figure is returned without saving.
        loss_log_scale: If ``True``, use a logarithmic y-axis for the Loss
            panel when all loss values are positive.

    Returns:
        The matplotlib figure. The figure is left open so notebook cells can
        display it inline.

    Raises:
        ImportError: If ``matplotlib`` or ``pandas`` are not installed.
        FileNotFoundError: If ``metrics_csv`` does not exist.
    zRF-DETR Training Metricsrù   rú   )r«   rë   rì   rL   rM   rž   s         r   Úplot_metricsr  ¹  s=   € ôB )¨Ó5Ñ€FˆHÜ(¨Ó2€MÜØØØØ(ØØ%ôð r   )r   r   r   Úintr”   ÚNone)r'   r“   r”   ztuple[str, str])r(   r“   r”   r“   )
r   r   rL   r   rM   r   rN   r•   r”   r  )rg   r   r”   údict[str, list[str]])r«   r“   r”   ztuple[Any, Any])rg   r   r”   r   )rL   r   rM   r   rž   r	  rê   r“   rë   úOptional[str]rì   r
   r”   r   )NF)r«   r“   rë   r
  rì   r
   r”   r   r\   )r«   r“   rë   r
  r”   r   )
rL   r   rM   r   rN   r•   rë   r
  r”   r   ) Ú__doc__Ú
__future__r   Úrerà   Úpathlibr   Útypingr   r   r   Úmatplotlib.figurer   Úcompilerq   Ú_LEGEND_COLUMNSrF   r   Ú__annotations__rB   r   r+   r0   rU   rŸ   r®   r§   r÷   rü   r  rþ   r  r/   r   r   ú<module>r     sj  ðòõ #ã 	Û Ý ß /Ñ /áÝ(à&˜BŸJ™J xÓ0Ð Ø€ð"Ûà"&Ð˜4Ó&ð
 ;Jõ ó óó=ó@8Qóvó2ð><Øð<àð<ð (ð<ð
 ð<ð ð<ð ð<ð ó<ðB "&Ø ð*Øð*àð*ð ð*ð ó	*ð^ "&ð1UØð1Uàð1Uð ó1Uóhð: "&Ø ð*Øð*àð*ð ð*ð ô	*øðg ò "Ø!Òð"ús   ¿B' Â'B1Â0B1