Source code for qiskit_experiments.visualization.plotters.curve_plotter
# This code is part of Qiskit.## (C) Copyright IBM 2022, 2023.## This code is licensed under the Apache License, Version 2.0. You may# obtain a copy of this license in the LICENSE.txt file in the root directory# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.## Any modifications or derivative works of this code must retain this# copyright notice, and modified files need to carry a notice indicating# that they have been altered from the originals."""Plotter for curve fits, specifically from :class:`.CurveAnalysis`."""fromtypingimportListfromuncertaintiesimportUFloatfromqiskit_experiments.curve_analysis.utilsimportanalysis_result_to_reprfromqiskit_experiments.frameworkimportOptionsfrom.base_plotterimportBasePlotter
[docs]classCurvePlotter(BasePlotter):"""A plotter class to plot results from :class:`.CurveAnalysis`. ``CurvePlotter`` plots results from curve fits, which includes - Raw results as a scatter plot. - Processed results with standard deviations/confidence intervals. - Interpolated fit results from the curve analysis. - Confidence interval for the fit results. - A report on the performance of the fit. """
[docs]@classmethoddefexpected_series_data_keys(cls)->List[str]:"""Returns the expected series data keys supported by this plotter. Data Keys: x: X-values for raw results. y: Y-values for raw results. Goes with ``x``. x_formatted: X-values for processed results. y_formatted: Y-values for processed results. Goes with ``x_formatted``. y_formatted_err: Error in ``y_formatted``, to be plotted as error-bars. x_interp: Interpolated X-values for a curve fit. y_interp: Y-values corresponding to the fit for ``y_interp`` X-values. y_interp_err: The standard deviations of the fit for each X-value in ``y_interp``. This data key relates to the option ``plot_sigma``. x_residuals: The X-values for the residual plot. y_residuals: The residual from the fitting. """return["x","y","x_formatted","y_formatted","y_formatted_err","x_interp","y_interp","y_interp_err","x_residuals","y_residuals",]
[docs]@classmethoddefexpected_supplementary_data_keys(cls)->List[str]:"""Returns the expected figures data keys supported by this plotter. This plotter generates a single text box, i.e. fit report, by digesting the provided supplementary data. The style and position of the report is controlled by ``textbox_rel_pos`` and ``textbox_text_size`` style parameters in :class:`PlotStyle`. Data Keys: primary_results: A list of :class:`.AnalysisResultData` objects to be shown in the fit report window. Typically, these are fit parameter values or secondary quantities computed from multiple fit parameters. fit_red_chi: The best reduced-chi squared value of the fit curves. If the fit consists of multiple sub-fits, this will be a dictionary keyed on the analysis name. Otherwise, this is a single float value of a particular analysis. """return["primary_results","fit_red_chi",]
@classmethoddef_default_options(cls)->Options:"""Return curve-plotter specific default plotter options. Options: plot_sigma (List[Tuple[float, float]]): A list of two number tuples showing the configuration to write confidence intervals for the fit curve. The first argument is the relative sigma (n_sigma), and the second argument is the transparency of the interval plot in ``[0, 1]``. Multiple n_sigma intervals can be drawn for the same curve. """options=super()._default_options()options.plot_sigma=[(1.0,0.7),(3.0,0.3)]returnoptions@classmethoddef_default_figure_options(cls)->Options:r"""Return curve-plotter specific default figure options. Figure Options: report_red_chi2_label (str): The label for the reduced-chi squared entry of the fit report. Defaults to the Python string literal ``"reduced-$\\chi^2$"``, corresponding to the formatted string reduced-:math:`\chi^2`. """fig_opts=super()._default_figure_options()fig_opts.report_red_chi2_label="reduced-$\\chi^2$"returnfig_optsdef_plot_figure(self):"""Plots a curve fit figure."""forserinself.series:# Scatter plot with error-barsplotted_formatted_data=Falseifself.data_exists_for(ser,["x_formatted","y_formatted","y_formatted_err"]):x,y,yerr=self.data_for(ser,["x_formatted","y_formatted","y_formatted_err"])self.drawer.scatter(x,y,y_err=yerr,name=ser,zorder=2,legend=True)plotted_formatted_data=True# Scatter plotifself.data_exists_for(ser,["x","y"]):x,y=self.data_for(ser,["x","y"])options={"zorder":1,}# If we plotted formatted data, differentiate scatter points by setting normal X-Y# markers to gray.ifplotted_formatted_data:options["color"]="gray"# If we didn't plot formatted data, the X-Y markers should be used for the legend. We add# it to ``options`` so it's easier to pass to ``scatter``.ifnotplotted_formatted_data:options["legend"]=Trueself.drawer.scatter(x,y,name=ser,**options,)# Line plot for fitifself.data_exists_for(ser,["x_interp","y_interp"]):x,y=self.data_for(ser,["x_interp","y_interp"])self.drawer.line(x,y,name=ser,zorder=3)# Confidence interval plotifself.data_exists_for(ser,["x_interp","y_interp","y_interp_err"]):x,y_interp,y_interp_err=self.data_for(ser,["x_interp","y_interp","y_interp_err"])forn_sigma,alphainself.options.plot_sigma:self.drawer.filled_y_area(x,y_interp+n_sigma*y_interp_err,y_interp-n_sigma*y_interp_err,name=ser,alpha=alpha,zorder=5,)# Plot residualsifself.data_exists_for(ser,["x_residuals","y_residuals"]):# check if we cancel residuals plottingifself.options.get("style",{}).get("style_name")!="canceled_residuals":series_name=ser+"_residuals"x,y=self.data_for(ser,["x_residuals","y_residuals"])self.drawer.scatter(x,y,name=series_name,legend=True)# Fit reportreport=self._write_report()iflen(report)>0:self.drawer.textbox(report)def_write_report(self)->str:"""Write fit report with supplementary_data. Subclass can override this method to customize fit report. By default, this writes important fit parameters and chi-squared value of the fit in the fit report. The ``report_red_chi2_label`` figure option controls the label for the chi-squared entries in the report. Returns: Fit report. """report=""if"primary_results"inself.supplementary_data:lines=[]foroutcomeinself.supplementary_data["primary_results"]:ifisinstance(outcome.value,(float,UFloat)):lines.append(analysis_result_to_repr(outcome))report+="\n".join(lines)if"fit_red_chi"inself.supplementary_data:red_chi=self.supplementary_data["fit_red_chi"]iflen(report)>0:report+="\n"ifisinstance(red_chi,float):report+=f"{self.figure_options.report_red_chi2_label} = {red_chi: .4g}"else:# Composite curve analysis reporting multiple chi-sq values.# This is usually given by a dict keyed on fit group name.# Add gap between primary-results and reduced-chi squared as# we have multiple values to display. This is easier to read.iflen(report)>0:report+="\n"# Created indented text of reduced-chi squared results.report+=f"{self.figure_options.report_red_chi2_label} per fit\n"lines=[]formod_name,mod_chiinred_chi.items():lines.append(f" * {mod_name}: {mod_chi: .4g}")report+="\n".join(lines)returnreport