Exemplo n.º 1
0
def test_set_dict_defaults_inplace():
    d1 = {}
    set_dict_defaults_inplace(d1, {}, {})
    assert d1 == {}

    d2 = {}
    set_dict_defaults_inplace(d2, {1: 2}, {1: 4, 2: 8})
    assert d2 == {1: 4, 2: 8}

    d3 = {}
    set_dict_defaults_inplace(d3, {1: 2})
    assert d3 == {1: 2}

    d4 = {1: 1, 2: 4}
    set_dict_defaults_inplace(
        d4, {2: 8, 3: 27}, {3: 81, 4: 256})
    assert d4 == {1: 1, 2: 4, 3: 81, 4: 256}
Exemplo n.º 2
0
def plot_C_vs_t_in_bin(
    rd,
    tout,
    Cout,
    bi=0,
    ax=None,
    labels=None,
    xscale="log",
    yscale="log",
    substances=None,
    ttlfmt=None,
    legend_kwargs=None,
    ls=None,
    c=None,
    xlabel=None,
    ylabel=None,
):
    """
    Plots bin local concentration as function of time for selected
    substances.

    Parameters
    ----------
    rd: ReactionDiffusion
    tout: 1D array of floats
    Cout: concentration trajectories from solver
    bi: bin index
    ax: Axes instance
    labels: sequence of strings
    xscale: matplotlib scale choice (e.g. 'log', 'symlog')
    yscale: matplotlib scale choice (e.g. 'log', 'symlog')
    substances: sequence of indies or names of substances
    ttlfmt: string formatted with bin boundaries (set to empty to suppress)
    legend_kwargs: dict
        kwargs passed to matplotlib legend function,
        (default: {'loc': None, 'prop': {'size': 12}}), set
        to False to suppress legend.
    ls: sequence of strings
        linestyles
    c: sequence of strings
        colors

    Returns
    =======
    Axes instance

    """
    if ttlfmt is None:
        if rd.N == 1:
            ttlfmt = "C(t)"
        else:
            ttlfmt = r"C(t) in bin: {0:.2g} m $\langle$" + r" x $\langle$ {1:.2g} m"
    legend_kwargs = legend_kwargs or {}
    set_dict_defaults_inplace(legend_kwargs, dict(loc="upper left", prop={"size": 12}))
    ls = ls or DEFAULT["ls"]
    c = c or DEFAULT["c"]
    ax, substances, labels = _init_ax_substances_labels(rd, ax, substances, labels, xscale, yscale)
    for i, lbl in zip(substances, labels):
        ax.plot(tout, Cout[:, bi, i], label=lbl, ls=ls[i % len(ls)], c=c[i % len(c)])
    try:
        ax.set_xlabel(xlabel or "t / " + str(tout.dimensionality.latex), {"fontsize": 16})
        ax.set_ylabel(ylabel or "C / " + str(Cout.dimensionality.latex), {"fontsize": 16})
    except AttributeError:
        pass
    if ttlfmt:
        ax.set_title(ttlfmt.format(rd.x[bi], rd.x[bi + 1]))
    if legend_kwargs is not False:
        ax.legend(**legend_kwargs)
    return ax
Exemplo n.º 3
0
def plot_solver_linear_error(
    integration,
    Cref=0,
    ax=None,
    x=None,
    ti=slice(None),
    bi=0,
    si=0,
    plot_kwargs=None,
    fill_between_kwargs=None,
    scale_err=1.0,
    fill=True,
    **kwargs
):
    """
    Parameters
    ----------
    integration: chemreac.integrate.Integration
        result from integration.
    Cref: array or float
        analytic solution to compare with
    ax: Axes instance or dict
        if ax is a dict it is used as key word arguments passed to
        matplotlib.pyplot.axes (default: None)
    x: array
        (optional) x-values, when None it is deduced to be
        either t or x (when ti or bi are slices repecitvely)
        (default: None)
    ti: slice
        time indices
    bi: slice
        bin indices
    si: integer
        specie index
    plot_kwargs: dict
        keyword arguments passed to matplotlib.pyplot.plot (default: None)
    fill_between_kwargs: dict
        keyword arguments passed to matplotlib.pyplot.fill_between
        (default: None)
    scale_err: float
        value with which errors are scaled. (default: 1.0)
    fill: bool
        whether or not to fill error span
    \*\*kwargs
        common keyword arguments of plot_kwargs and fill_between_kwargs,
        e.g. 'color', (default: None).

    See Also
    --------
    plot_solver_linear_excess_error
    """
    ax = _init_axes(ax)
    Cerr = integration.Cout - to_unitless(Cref, get_derived_unit(integration.rd.unit_registry, "concentration"))
    if x is None:
        if isinstance(ti, slice):
            x = integration.tout[ti]
        elif isinstance(bi, slice):
            x = integration.rd.xcenters[bi]
        else:
            raise NotImplementedError("Failed to deduce x-axis.")

    plot_kwargs = plot_kwargs or {}
    set_dict_defaults_inplace(plot_kwargs, kwargs)
    plt.plot(np.asarray(x), np.asarray(scale_err * Cerr[ti, bi, si]), **plot_kwargs)

    if fill:
        le_l, le_u = solver_linear_error_from_integration(integration, ti=ti, bi=bi, si=si)
        Cerr_u = le_u - Cref[ti, bi, si]
        Cerr_l = le_l - Cref[ti, bi, si]
        fill_between_kwargs = fill_between_kwargs or {}
        set_dict_defaults_inplace(fill_between_kwargs, {"alpha": 0.2}, kwargs)
        plt.fill_between(
            np.asarray(x), np.asarray(scale_err * Cerr_l), np.asarray(scale_err * Cerr_u), **fill_between_kwargs
        )
    return ax
Exemplo n.º 4
0
def _plot_analysis(
    cb,
    labels,
    rd,
    tout,
    yout,
    indices,
    axes=None,
    titles=None,
    lintreshy=1e-10,
    logx=True,
    legend_kwargs=None,
    ls=None,
    c=None,
):
    """
    Parameters
    ----------
    cb: callback
        callback with signature (rd, tout, yout, indices) returning
        3-dimensional array with shape (tout.size, len(axes), len(labels))
    labels: sequence of strings
        labels of individual plots
    rd: ReactionDiffusion instance
    tout: 1-dimensional array of floats
    yout: solver output
    indices: 4th argument for callback
    axes: sequence of matplotlib Axes instances
        (default: len(indices) number of subplot axes)
    titles: titles per axis
    lintreshy: float
        symlog option 'linthreshy' (default: 1e-10)
    logx: set x scale to 'log'
    legend_kwargs: dict
        dict of kwargs to pass to matplotlib legend function
        (default: {'loc': None, 'prop': {'size': 12}}), set
        to False to suppress legend.
    ls: sequence of strings
        linestyles
    c: sequence of strings
        colors
    """
    legend_kwargs = legend_kwargs or {}
    set_dict_defaults_inplace(legend_kwargs, dict(loc=None, prop={"size": 12}))
    if axes is None:
        axes = [plt.subplot(len(indices), 1, i + 1) for i in range(len(indices))]
    else:
        assert len(axes) == len(indices)
    ls = ls or DEFAULT["ls"]
    c = c or DEFAULT["c"]
    row_out = cb(rd, tout, yout, indices)
    for i, ax in enumerate(axes):
        ax.set_yscale("symlog", linthreshy=lintreshy)
        if logx:
            ax.set_xscale("log")
        istl = 0  # style counter
        for j, lbl in enumerate(labels):
            if np.all(np.abs(row_out[:, i, j]) < lintreshy):
                continue
            ax.plot(tout, row_out[:, i, j], label=lbl, c=c[istl % len(c)], ls=ls[istl % len(ls)])
            istl += 1
        if legend_kwargs is not False:
            ax.legend(**legend_kwargs)
        if titles:
            ax.set_title(titles[i])
        ax.set_xlabel("t / s")
    return axes