class atomica.plotting.PlotData(results, outputs=None, pops=None, output_aggregation=None, pop_aggregation=None, project=None, time_aggregation=None, t_bins=None, accumulate=None)[source]

Bases: object

Process model outputs into plottable quantities

This is what gets passed into a plotting function, which displays a View of the data Conceptually, we are applying visuals to the data. But we are performing an extraction step rather than doing it directly because things like labels, colours, groupings etc. only apply to plots, not to results, and there could be several different views of the same data.

Operators for - and / are defined to faciliate looking at differences and relative differences of derived quantities (quantities computed using PlotData operations) across individual results. To keep the implementation tractable, they don’t generalize further than that, and operators + and * are not implemented because these operations rarely make sense for the data being operated on.

  • results

    Specify which results to plot. Can be

    • a Result,

    • a list of Results,

    • a dict/odict of results (the name of the result is taken from the Result, not the dict)

  • outputs – The name of an output compartment, characteristic, or parameter, or list of names. Inside a list, a dict can be given to specify an aggregation e.g. outputs=['sus',{'total':['sus','vac']}] where the key is the new name. Or, a formula can be given which will be evaluated by looking up labels within the model object. Links will automatically be summed over

  • pops – The name of an output population, or list of names. Like outputs, can specify a dict with a list of pops to aggregate over them

  • output_aggregation

    If an output aggregation is requested, combine the outputs listed using one of

    • ’sum’ - just add values together

    • ’average’ - unweighted average of quantities

    • ’weighted’ - weighted average where the weight is the compartment size, characteristic value, or link source compartment size (summed over duplicate links). ‘weighted’ method cannot be used with non-transition parameters and a KeyError will result in that case

  • pop_aggregation – Same as output_aggregation, except that ‘weighted’ uses population sizes. Note that output aggregation is performed before population aggregation. This also means that population aggregation can be used to combine already aggregated outputs (e.g. can first sum ‘sus’+’vac’ within populations, and then take weighted average across populations)

  • project – Optionally provide a Project object, which will be used to convert names to labels in the outputs for plotting.

  • time_aggregation – Optionally specify time aggregation method. Supported methods are ‘integrate’ and ‘average’ (no weighting). When aggregating times, non-annualized flow rates will be used.

  • t_bins

    Optionally specify time bins, which will enable time aggregation. Supported inputs are

    • A vector of bin edges. Time points are included if the time is >= the lower bin value and < upper bin value.

    • A scalar bin size (e.g. 5) which will be expanded to a vector spanning the data

    • The string ‘all’ will maps to bin edges [-inf, inf] aggregating over all time

  • accumulate – Optionally accumulate outputs over time. Can be ‘sum’ or ‘integrate’ to either sum quantities or integrate by multiplying by the timestep. Accumulation happens after time aggregation. The logic is extremely simple - the quantities in the Series pass through cumsum. If ‘integrate’ is selected, then the quantities are multiplied by dt and the units are multiplied by years


A PlotData instance that can be passed to plot_series() or plot_bars()


Implement custom indexing

The Series objects stored within PlotData are each bound to a single result, population, and output. This operator makes it possible to easily retrieve a particular Series instance. For example,

>>> d = PlotData(results)
... d['default','0-4','sus']

key (tuple) – A tuple of (result,pop,output)


A Series instance



Accumulate values over time


Interpolate all Series onto new time values


Constructs a PlotData instance from program values


Assign colors to quantities


Aggregate values over time


Return vector of time values


Accumulate values over time

Accumulation methods are



Select whether to add or integrate. Supported methods are: - ‘sum’ : runs cumsum on all quantities - should not be used if units are flow rates (so will check for a timescale).

Summation should be used for compartment-based quantities, such as DALYs

  • ’integrate’integrate using trapezoidal rule, assuming initial value of 0

    Note that here there is no concept of ‘dt’ because we might have non-uniform time aggregation bins Therefore, we need to use the time vector actually contained in the Series object (via cumtrapz())

Return type:



Interpolate all Series onto new time values

This will modify all of the contained Series objects in-place. The modified PlotData instance is also returned, so that interpolation and construction can be performed in one line. i.e. both

>>> d = PlotData(result)
... d.interpolate(tvals)


>>> vals = PlotData(result).interpolate(tvals)

will work as intended.


new_tvec – Vector of new time values


The modified PlotData instance

static programs(results, outputs=None, t_bins=None, quantity='spending', accumulate=None, nan_outside=False)[source]

Constructs a PlotData instance from program values

This alternate constructor can be used to plot program-related quantities such as spending or coverage.

  • results – single Result, or list of Results

  • outputs

    specification of which programs to plot spending for. Can be: - the name of a single program - a list of program names - aggregation dict e.g. {‘treatment’:[‘tx-1’,’tx-2’]} or list of such dicts. Output aggregation type is automatically ‘sum’ for

    program spending, and aggregation is NOT permitted for coverages (due to modality interactions)

  • t_bins – aggregate over time, using summation for spending and number coverage, and average for fraction/proportion coverage. Notice that unlike the PlotData() constructor, this function does _not_ allow the time aggregation method to be manually set.

  • quantity – can be ‘spending’, ‘coverage_number’, ‘coverage_eligible’, or ‘coverage_fraction’. The ‘coverage_eligible’ is the sum of compartments reached by a program, such that coverage_fraction = coverage_number/coverage_eligible

  • accumulate – can be ‘sum’ or ‘integrate’

  • nan_outside – If True, then values will be NaN outside the program start/stop year


A new PlotData instance

set_colors(colors=None, results='all', pops='all', outputs='all', overwrite=False)[source]

Assign colors to quantities

This function facilitates assigned colors to the Series objects contained in this PlotData instance.

  • colors – Specify the colours to use. This can be - A list of colours that applies to the list of all matching items - A single colour to use for all matching items - The name of a colormap to use (e.g., ‘Blues’)

  • results – A list of results to set colors for, or a dict of results where the key names the results (e.g. PlotData.results)

  • pops – A list of pops to set colors for, or a dict of pops where the key names the pops (e.g. PlotData.pops

:param outputs:A list of outputs to set colors for, or a dict of outputs where the key names the outputs (e.g. PlotData.outputs) :type overwrite: :param overwrite: False (default) or True. If True, then any existing manually set colours will be overwritten :return: The PlotData instance (also modified in-place)

Essentially, the lists of results, pops, and outputs are used to filter the Series resulting in a list of Series to operate on. Then, the colors argument is applied to that list.

time_aggregate(t_bins, time_aggregation=None, interpolation_method=None)[source]

Aggregate values over time

Note that accumulation is a running total, whereas aggregation refers to binning. The two can be both be applied (aggregation should be performed prior to accumulation).

Normally, aggregation is performed when constructing a PlotData instance and this method does not need to be manually called. However, in rare cases, it may be necessary to explicitly set the interpolation method. Specifically, the interpolation method needs to match the underlying assumption for parameter values. For parameter scenarios, this may require that the ‘previous’ method is used (to match the assumption in the parameter overwrite) rather than relying on the standard assumption that databook quantities can be interpolated directly.

This method modifies the PlotData object in-place. However, the modified object is also returned, so that time aggregation can be chained with other operations, the same as PlotData.interpolate().

  • t_bins – Vector of bin edges OR a scalar bin size, which will be automatically expanded to a vector of bin edges

  • time_aggregation – can be ‘integrate’ or ‘average’. Note that for quantities that have a timescale, flow parameters in number units will be adjusted accordingly (e.g. a parameter in units of ‘people/day’ aggregated over a 1 year period will display as the equivalent number of people that year)

  • interpolation_method – Assumption on how the quantity behaves in between timesteps - in general, ‘linear’ should be suitable for most dynamic quantities, while ‘previous’ should be used for spending and other program-related quantities.


The same modified PlotData instance


Return vector of time values

This method returns a vector of time values for the PlotData object, if all of the series have the same time axis (otherwise it will throw an error). All series must have the same number of timepoints. This will always be the case for a PlotData object unless the instance has been manually modified after construction.


Tuple with (array of time values, array of time labels)