@@ -792,6 +792,79 @@ def _plot_param_series_from_csv(
792792 )
793793
794794 def _plot_param_series_from_snapshots (
795+ self ,
796+ csv_path : str ,
797+ unique_name : str ,
798+ param_descriptor : object ,
799+ versus_descriptor : object | None = None ,
800+ ) -> None :
801+ """
802+ Plot a parameter's value across sequential fit results.
803+
804+ Reads data from the CSV file at *csv_path*. The y-axis values
805+ come from the column named *unique_name*, uncertainties from
806+ ``{unique_name}.uncertainty``. When *versus_descriptor* is
807+ provided, the x-axis uses the corresponding ``diffrn.{name}``
808+ column; otherwise the row index is used.
809+
810+ Axis labels are derived from the live descriptor objects
811+ (*param_descriptor* and *versus_descriptor*), which carry
812+ ``.description`` and ``.units`` attributes.
813+
814+ Parameters
815+ ----------
816+ csv_path : str
817+ Path to the ``results.csv`` file.
818+ unique_name : str
819+ Unique name of the parameter to plot (CSV column key).
820+ param_descriptor : object
821+ The live parameter descriptor (for axis label / units).
822+ versus_descriptor : object | None, default=None
823+ A diffrn descriptor whose ``.name`` maps to a
824+ ``diffrn.{name}`` CSV column. ``None`` → use row index.
825+ """
826+ df = pd .read_csv (csv_path )
827+
828+ if unique_name not in df .columns :
829+ log .warning (
830+ f"Parameter '{ unique_name } ' not found in CSV columns. "
831+ f'Available: { list (df .columns )} '
832+ )
833+ return
834+
835+ y = df [unique_name ].astype (float ).tolist ()
836+ uncert_col = f'{ unique_name } .uncertainty'
837+ sy = df [uncert_col ].astype (float ).tolist () if uncert_col in df .columns else [0.0 ] * len (y )
838+
839+ # X-axis: diffrn column or row index
840+ versus_name = versus_descriptor .name if versus_descriptor is not None else None
841+ diffrn_col = f'diffrn.{ versus_name } ' if versus_name else None
842+
843+ if diffrn_col and diffrn_col in df .columns :
844+ x = pd .to_numeric (df [diffrn_col ], errors = 'coerce' ).tolist ()
845+ x_label = getattr (versus_descriptor , 'description' , None ) or versus_name
846+ if hasattr (versus_descriptor , 'units' ) and versus_descriptor .units :
847+ x_label = f'{ x_label } ({ versus_descriptor .units } )'
848+ else :
849+ x = list (range (1 , len (y ) + 1 ))
850+ x_label = 'Experiment No.'
851+
852+ # Y-axis label from descriptor
853+ param_units = getattr (param_descriptor , 'units' , '' )
854+ y_label = f'Parameter value ({ param_units } )' if param_units else 'Parameter value'
855+
856+ title = f"Parameter '{ unique_name } ' across fit results"
857+
858+ self ._backend .plot_scatter (
859+ x = x ,
860+ y = y ,
861+ sy = sy ,
862+ axes_labels = [x_label , y_label ],
863+ title = title ,
864+ height = self .height ,
865+ )
866+
867+ def plot_param_series_from_snapshots (
795868 self ,
796869 unique_name : str ,
797870 versus_name : str | None ,
0 commit comments