Beispiel #1
0
def pvalue_plot(x, y, fill_y=None, col=None, color=None, label=None,
                plotargs={}, fillargs={}):
    """Plot of a 1D confidence level distribution, where the y axis is 1-CL.

    Parameters:

    - `x`: x values
    - `y`: y values
    - `fill_y`: for x-values where y is larger than this number, the area
      between the x-axis and the curve will be filled
    - `col`: (optional) integer to select one of the colours from the default
      palette
    - `plotargs`: keyword arguments passed to the `plot` function
    - `fillargs`: keyword arguments passed to the `fill_between` function
    """
    ax = plt.gca()
    _plotargs = {}
    _fillargs = {}
    # default values
    _plotargs['linewidth'] = 0.6
    if label is not None:
        _plotargs['label'] = label
    color = get_color(col=col, color=color)
    _plotargs['color'] = color
    _fillargs['facecolor'] = lighten_color(color, 0.5)
    _fillargs.update(fillargs)
    _plotargs.update(plotargs)
    ax.plot(x, y, **_plotargs)
    if fill_y is not None:
        x_zoom = scipy.ndimage.zoom(x, zoom=10, order=1)
        y_zoom = scipy.ndimage.zoom(y, zoom=10, order=1)
        ax.fill_between(x_zoom, 0, y_zoom,
            where=y_zoom > fill_y,
            **_fillargs)
    ax.set_ylim([0, 1])
Beispiel #2
0
def contour(x, y, z, levels,
              interpolation_factor=1,
              interpolation_order=2,
              col=None, color=None, label=None,
              filled=True,
              contour_args={}, contourf_args={}):
    r"""Plot coloured confidence contours (or bands) given numerical input
    arrays.

    Parameters:

    - `x`, `y`: 2D arrays containg x and y values as returned by numpy.meshgrid
    - `z` value of the function to plot. 2D array in the same shape as `x` and
      `y`. The lowest value of the function should be 0 (i.e. the best fit
      point).
    - levels: list of function values where to draw the contours. They should
      be positive and in ascending order.
    - `interpolation factor` (optional): in between the points on the grid,
      the functioncan be interpolated to get smoother contours.
      This parameter sets the number of subdivisions (default: 1, i.e. no
      interpolation). It should be larger than 1.
    - `col` (optional): number between 0 and 9 to choose the color of the plot
      from a predefined palette
    - `label` (optional): label that will be added to a legend created with
       maplotlib.pyplot.legend()
    - `filled` (optional): if False, contours will be drawn without shading
    - `contour_args`: dictionary of additional options that will be passed
       to matplotlib.pyplot.contour() (that draws the contour lines)
    - `contourf_args`: dictionary of additional options that will be passed
       to matplotlib.pyplot.contourf() (that paints the contour filling).
       Ignored if `filled` is false.
    """
    if interpolation_factor > 1:
        x = scipy.ndimage.zoom(x, zoom=interpolation_factor, order=1)
        y = scipy.ndimage.zoom(y, zoom=interpolation_factor, order=1)
        z = scipy.ndimage.zoom(z, zoom=interpolation_factor, order=interpolation_order)
    _contour_args = {}
    _contourf_args = {}
    color = get_color(col=col, color=color)
    _contour_args['colors'] = color
    if filled:
        _contour_args['linewidths'] = 0.6
    else:
        _contour_args['linewidths'] = 0.8
    N = len(levels)
    _contourf_args['colors'] = [lighten_color(color, 0.5)# RGB
                                       + (max(1-n/N, 0),) # alpha, decreasing for contours
                                       for n in range(N)]
    _contour_args['linestyles'] = 'solid'
    _contour_args.update(contour_args)
    _contourf_args.update(contourf_args)
    # for the filling, need to add zero contour
    levelsf = [np.min(z)] + list(levels)
    ax = plt.gca()
    if filled:
        ax.contourf(x, y, z, levels=levelsf, **_contourf_args)
    CS = ax.contour(x, y, z, levels=levels, **_contour_args)
    if label is not None:
        CS.collections[0].set_label(label)
    return CS
Beispiel #3
0
def error_budget_pie(err_dict, other_cutoff=0.03):
    """Pie chart of an observable's error budget.

    Parameters:

    - `err_dict`: Dictionary as return from `flavio.sm_error_budget`
    - `other_cutoff`: If an individual error contribution divided by the total
      error is smaller than this number, it is lumped under "other". Defaults
      to 0.03.

    Note that for uncorrelated parameters, the total uncertainty is the squared
    sum of the individual uncertainties, so the relative size of the wedges does
    not correspond to the relative contribution to the total uncertainty.

    If the uncertainties of individual parameters are correlated, the total
    uncertainty can be larger or smaller than the squared sum of the individual
    uncertainties, so the representation can be misleading.
    """
    err_tot = sum(err_dict.values())  # linear sum of individual errors
    err_dict_sorted = OrderedDict(sorted(err_dict.items(),
                                         key=lambda t: -t[1]))
    labels = []
    fracs = []
    small_frac = []
    for key, value in err_dict_sorted.items():
        frac = value / err_tot
        if frac > other_cutoff:
            if isinstance(key, str):
                try:
                    labels.append(flavio.Parameter[key].tex)
                except KeyError:
                    # if 'key' is not actually a parameter (e.g. manually set by the user)
                    labels.append(key)
            elif isinstance(key, tuple):
                key_strings = [flavio.Parameter[k].tex for k in key]
                labels.append(', '.join(key_strings))
            fracs.append(frac)
        else:
            small_frac.append(frac)
    if small_frac:
        labels.append('other')
        # the fraction for the "other" errors is obtained by adding them in quadrature
        fracs.append(np.sqrt(np.sum(np.array(small_frac)**2)))
    # initially, the fractions had been calculated assuming that they add to
    # one, but adding the "other" errors in quadrature changed that - correct
    # all the fractions to account for this
    corr = sum(fracs)
    fracs = [f / corr for f in fracs]

    def my_autopct(pct):
        return r'{p:.2g}\%'.format(p=pct * err_tot)

    plt.axis('equal')
    return plt.pie(
        fracs,
        labels=labels,
        autopct=my_autopct,
        wedgeprops={'linewidth': 0.5},
        colors=[lighten_color('C{}'.format(i), 0.5) for i in range(10)])
Beispiel #4
0
def likelihood_plot(x,
                    y,
                    fill_x=None,
                    col=None,
                    color=None,
                    label=None,
                    plotargs={},
                    fillargs={},
                    flipped=False):
    """Plot of a 1D probability density function.

    Parameters:

    - `x`: x values
    - `y`: y values
    - `fill_x`: 2-tuple of x-values in between which the curve will be filled
    - `col`: (optional) integer to select one of the colours from the default
      palette
    - `plotargs`: keyword arguments passed to the `plot` function
    - `fillargs`: keyword arguments passed to the `fill_between` function
    - `flipped`: exchange x and y axes (needed for `density_contour_joint`)
    """
    ax = plt.gca()
    _plotargs = {}
    _fillargs = {}
    # default values
    _plotargs['linewidth'] = 0.6
    if label is not None:
        _plotargs['label'] = label
    color = get_color(col=col, color=color)
    _plotargs['color'] = color
    _fillargs['facecolor'] = lighten_color(color, 0.5)
    _fillargs.update(fillargs)
    _plotargs.update(plotargs)
    if not flipped:
        ax.plot(x, y, **_plotargs)
        if fill_x is not None:
            ax.fill_between(x,
                            0,
                            y,
                            where=np.logical_and(fill_x[0] < x, x < fill_x[1]),
                            **_fillargs)
    else:
        ax.plot(y, x, **_plotargs)
        if fill_x is not None:
            ax.fill_betweenx(x,
                             0,
                             y,
                             where=np.logical_and(fill_x[0] < x,
                                                  x < fill_x[1]),
                             **_fillargs)
Beispiel #5
0
def contour(x,
            y,
            z,
            levels,
            *,
            z_min=None,
            interpolation_factor=1,
            interpolation_order=2,
            col=None,
            color=None,
            label=None,
            filled=True,
            contour_args={},
            contourf_args={},
            **kwargs):
    r"""Plot coloured confidence contours (or bands) given numerical input
    arrays.

    Parameters:

    - `x`, `y`: 2D arrays containg x and y values as returned by numpy.meshgrid
    - `z` value of the function to plot. 2D array in the same shape as `x` and
      `y`.
    - levels: list of function values where to draw the contours. They should
      be positive and in ascending order.
    - `z_min` (optional): lowest value of the function to plot (i.e. value at
      the best fit point). If not provided, the smallest value on the grid is
      used.
    - `interpolation factor` (optional): in between the points on the grid,
      the functioncan be interpolated to get smoother contours.
      This parameter sets the number of subdivisions (default: 1, i.e. no
      interpolation). It should be larger than 1.
    - `col` (optional): number between 0 and 9 to choose the color of the plot
      from a predefined palette
    - `label` (optional): label that will be added to a legend created with
       maplotlib.pyplot.legend()
    - `filled` (optional): if False, contours will be drawn without shading
    - `contour_args`: dictionary of additional options that will be passed
       to matplotlib.pyplot.contour() (that draws the contour lines)
    - `contourf_args`: dictionary of additional options that will be passed
       to matplotlib.pyplot.contourf() (that paints the contour filling).
       Ignored if `filled` is false.
    """
    if z_min is None:
        warnings.warn(
            "The smallest `z` value on the grid will be used as the "
            "minimum of the function to plot. This can lead to "
            "undesired results if the actual minimum is considerably "
            "different from the minimum on the grid. For better "
            "precision, the actual minimum should be provided in the "
            "`z_min` argument.")
        z_min = np.min(z)  # use minmum on the grid
    elif np.min(z) < z_min:
        raise ValueError("The provided minimum `z_min` has to be smaller than "
                         "the smallest `z` value on the grid.")
    z = z - z_min  # subtract z minimum to make value of new z minimum 0
    if interpolation_factor > 1:
        x = scipy.ndimage.zoom(x, zoom=interpolation_factor, order=1)
        y = scipy.ndimage.zoom(y, zoom=interpolation_factor, order=1)
        z = scipy.ndimage.zoom(z,
                               zoom=interpolation_factor,
                               order=interpolation_order)
    _contour_args = {}
    _contourf_args = {}
    color = get_color(col=col, color=color)
    _contour_args['colors'] = color
    if filled:
        _contour_args['linewidths'] = 0.6
    else:
        _contour_args['linewidths'] = 0.8
    N = len(levels)
    _contourf_args['colors'] = [
        lighten_color(color, 0.5)  # RGB
        + (max(1 - n / N, 0), )  # alpha, decreasing for contours
        for n in range(N)
    ]
    _contour_args['linestyles'] = 'solid'
    _contour_args.update(contour_args)
    _contourf_args.update(contourf_args)
    # for the filling, need to add zero contour
    zero_contour = min(np.min(z), np.min(levels) * (1 - 1e-16))
    levelsf = [zero_contour] + list(levels)
    ax = plt.gca()
    if filled:
        ax.contourf(x, y, z, levels=levelsf, **_contourf_args)
    CS = ax.contour(x, y, z, levels=levels, **_contour_args)
    if label is not None:
        CS.collections[0].set_label(label)
    return CS