def __init__(self, show_missing=True, get_category=None, **kwargs): """ ``kwargs['attributes']`` must contain exactly one attribute. If only one of the two configurations has a value for a run, only add a coordinate if *show_missing* is True. *get_category* can be a function that takes **two** runs (dictionaries of properties) and returns a category name. This name is used to group the points in the plot. Runs for which this function returns None are shown in a default category and are not contained in the legend. For example, to group by domain use:: def domain_as_category(run1, run2): # run2['domain'] has the same value, because we always # compare two runs of the same problem return run1['domain'] *get_category* and *category_styles* (see :py:class:`PlotReport <downward.reports.plot.PlotReport>`) are best used together, e.g. to distinguish between different levels of difficulty:: def improvement(run1, run2): time1 = run1.get('search_time', 1800) time2 = run2.get('search_time', 1800) if time1 > 10 * time2: return 'strong' if time1 >= time2: return 'small' return 'worse' styles = { 'strong': ('x','r'), 'small': ('*','b'), 'worse': ('o','y'), } PlotReport(attributes=['search_time'], get_category=improvement, category_styles=styles) """ kwargs.setdefault('legend_location', (1.3, 0.5)) # If the size has not been set explicitly, make it a square. params = kwargs.get('params', {}) params.setdefault('figure.figsize', [8, 8]) kwargs['params'] = params PlotReport.__init__(self, **kwargs) assert self.attribute, 'ScatterPlotReport needs exactly one attribute' # By default all values are in the same category. self.get_category = get_category or (lambda run1, run2: None) self.show_missing = show_missing self.xlim_left = self.xlim_left or EPSILON self.ylim_bottom = self.ylim_bottom or EPSILON if self.output_format == 'tex': self.writer = ScatterPgfPlots else: self.writer = ScatterMatplotlib
def __init__(self, show_missing=True, get_category=None, **kwargs): """ ``kwargs['attributes']`` must contain exactly one attribute. If only one of the two configurations has a value for a run, only add a coordinate if *show_missing* is True. *get_category* can be a function that takes **two** runs (dictionaries of properties) and returns a category name. This name is used to group the points in the plot. Runs for which this function returns None are shown in a default category and are not contained in the legend. For example, to group by domain use:: def domain_as_category(run1, run2): # run2['domain'] has the same value, because we always # compare two runs of the same problem return run1['domain'] *get_category* and *category_styles* (see :py:class:`PlotReport <downward.reports.plot.PlotReport>`) are best used together, e.g. to distinguish between different levels of difficulty:: def improvement(run1, run2): time1 = run1.get('search_time', 1800) time2 = run2.get('search_time', 1800) if time1 > 10 * time2: return 'strong' if time1 >= time2: return 'small' return 'worse' styles = { 'strong': ('x','r'), 'small': ('*','b'), 'worse': ('o','y'), } PlotReport(attributes=['search_time'], get_category=improvement, category_styles=styles) """ kwargs.setdefault('legend_location', (1.3, 0.5)) # If the size has not been set explicitly, make it a square. params = kwargs.get('params', {}) params.setdefault('figure.figsize', [8, 8]) kwargs['params'] = params PlotReport.__init__(self, **kwargs) assert self.attribute, 'ScatterPlotReport needs exactly one attribute' # By default all values are in the same category. self.get_category = get_category or (lambda run1, run2: None) self.show_missing = show_missing self.xlim_left = self.xlim_left or EPSILON self.ylim_bottom = self.ylim_bottom or EPSILON if self.output_format == 'tex': self.writer = ScatterPgfPlots else: self.writer = ScatterMatplotlib
def __init__(self, x_algo, y_algo, x_attribute, y_attribute, show_missing=True, get_category=None, **kwargs): """ See :class:`.PlotReport` for inherited arguments. The keyword argument *attributes* must contain exactly one attribute. Use the *filter_algorithm* keyword argument to select exactly two algorithms. If only one of the two algorithms has a value for a run, only add a coordinate if *show_missing* is True. *get_category* can be a function that takes **two** runs (dictionaries of properties) and returns a category name. This name is used to group the points in the plot. If there is more than one group, a legend is automatically added. Runs for which this function returns None are shown in a default category and are not contained in the legend. For example, to group by domain: >>> def domain_as_category(run1, run2): ... # run2['domain'] has the same value, because we always ... # compare two runs of the same problem. ... return run1['domain'] Example grouping by difficulty: >>> def improvement(run1, run2): ... time1 = run1.get('search_time', 1800) ... time2 = run2.get('search_time', 1800) ... if time1 > time2: ... return 'better' ... if time1 == time2: ... return 'equal' ... return 'worse' >>> from downward.experiment import FastDownwardExperiment >>> exp = FastDownwardExperiment() >>> exp.add_report(ScatterPlotReport( ... attributes=['search_time'], ... get_category=improvement)) Example comparing the number of expanded states for two algorithms: >>> exp.add_report(ScatterPlotReport( ... attributes=["expansions_until_last_jump"], ... filter_algorithm=["algorithm-1", "algorithm-2"], ... get_category=domain_as_category, ... format="png", # Use "tex" for pgfplots output. ... ), ... name="scatterplot-expansions") """ # If the size has not been set explicitly, make it a square. matplotlib_options = kwargs.get('matplotlib_options', {}) matplotlib_options.setdefault('figure.figsize', [8, 8]) kwargs['matplotlib_options'] = matplotlib_options PlotReport.__init__(self, **kwargs) if not self.attribute: logging.critical('ScatterPlotReport needs exactly one attribute') # By default all values are in the same category. self.get_category = get_category or (lambda run1, run2: None) self.show_missing = show_missing self.xlim_left = self.xlim_left or MIN_AXIS self.ylim_bottom = self.ylim_bottom or MIN_AXIS if self.output_format == 'tex': self.writer = ScatterPgfPlots else: self.writer = ScatterMatplotlib self.x_algo = x_algo self.y_algo = y_algo self.x_attribute = x_attribute self.y_attribute = y_attribute