"""Simplified plotting."""
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import smplr
import sympy
import uncertainties
import uncertainties.unumpy as unp
from matplotlib import pylab
from matplotlib.pyplot import *
# local imports
from smpl import doc, interpolate, io, stat, util, wrap
from smpl import fit as ffit
[docs]
def set_plot_style():
# fig_size = (8, 6)
# fig_legendsize = 14
# fig_labelsize = 12 # ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’.
params = {
"legend.fontsize": "x-large",
"figure.figsize": (8, 6),
"axes.labelsize": "x-large",
"axes.titlesize": "x-large",
"xtick.labelsize": "x-large",
"ytick.labelsize": "x-large",
}
pylab.rcParams.update(params)
matplotlib.rcParams.update(params)
# matplotlib.rcParams.update({'font.size': fig_labelsize})
# colors = dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS)
unv = unp.nominal_values
usd = unp.std_devs
default = {
# 'params' :[None ,"Initial fit parameters",
"title": [None, "Plot title"],
"xlabel": [
"",
"X axis label",
],
"ylabel": [
"",
"Y axis label",
],
"label": [
None,
"Legend name of plotted ``data``",
],
"fmt": [
".",
"Format for plotting fit function (could be a line style, marker or a combination of both or 'step')",
],
"where": [
"mid",
"Where to place the ticks. Possible values are 'pre', 'post', 'mid', 'edge'. Might be incompatible with uncertainties.",
],
"units": [
None,
"Units of the fit parameters as strings. Displayed in the Legend",
],
"save": [
None,
" File to save the plot",
],
"lpos": [
0,
"Legend position",
],
"tight": [
True,
"tight_layout",
],
# 'frange' :[None ,"Limit the fit to given range. First integer is the lowest and second the highest index.",],
"prange": [
None,
"Limit the plot of the fit to given range",
],
"sigmas": [
0,
"Color the array of given ``sigma`` times uncertainty. Only works if the fit function is coded with ``unp``",
],
"data_sigmas": [
1,
"Color the array of given ``sigma`` times uncertainty. Only works if the data has uncertainties",
],
"init": [False, "Initialize a new plot"],
"ss": [
True,
"save, add legends and grid to the plot",
],
"also_data": [True, " also plot the data"],
"also_fit": [
True,
"also plot the fit",
],
"auto_fit": [
False,
"automatically fit",
],
"logy": [
False,
"logarithmic x axis",
],
"logx": [
False,
"logarithmic y axis",
],
"function_color": [
None,
"Color of the function plot",
],
"data_color": [
None,
"Color of the data plot",
],
"fit_color": [
None,
"Color of the fit plot",
],
"fit_fmt": [
"-",
"Format of the fit plot",
],
"residue": [
False,
"Display difference between fit and data in a second plot",
],
"residue_err": [
True,
"Differences between fit and data will have errorbars",
],
"show": [
False,
"Call plt.show()",
],
"size": [
None,
"Size of the plot as a tuple (x,y). Only has an effect if ``init`` is True",
],
"number_format": [
io.gf(4),
"Format to display numbers.",
],
# , 'selector' :[ None ,"Function that takes ``x`` and ``y`` as parameters and returns an array mask in order to limit the data points for fitting. Alternatively a mask for selecting elements from datax and datay.",],
# , 'fixed_params' :[ True ,"Enable fixing parameters by choosing the same-named variables from ``kwargs``.",],
# , 'sortbyx' :[ True , "Enable sorting the x and y data so that x is sorted.",],
"interpolate": [False, "Enable interpolation of the data."],
"interpolate_fmt": [
"-",
"Either format string or linestyle tuple.",
],
"interpolate_label": [
None,
"Label for the interpolation.",
],
"extrapolate": [
True,
"Enable extrapolation of whole data if fit range is limited by ``frange`` or ``fselector``.",
],
"extrapolate_min": [
None,
"Lower extrapolation bound",
],
"extrapolate_max": [
None,
"Higher extrapolation bound",
],
"extrapolate_fmt": [
"--",
"Format of the extrapolation line",
],
"extrapolate_hatch": [
r"||",
"Extrapolation shape/hatch for filled area in case of ``sigmas``>0. See https://matplotlib.org/stable/gallery/shapes_and_collections/hatch_style_reference.html",
],
"bbox_to_anchor": [
None,
"Position in a tuple (x,y),Shift position of the legend out of the main pane. ",
],
"ncol": [
None,
"Columns in the legend if used with ``bbox_to_anchor``.",
],
"steps": [
1000,
"resolution of the plotted function",
],
"fitinline": [
False,
"No newlines for each fit parameter",
],
"grid": [
True,
"Enable grid for the plot",
],
"hist": [
False,
"Enable histogram plot",
],
"stairs": [
False,
"Enable stair plot",
],
"capsize": [5, "size of cap on error bar plot"],
"axes": [None, "set current axis"],
"linestyle": [None, "linestyle, only active if `fmt`=None"],
"xspace": [
np.linspace,
"xspace gets called with xspace(xmin,xmax,steps) in :func:`function` to get the points of the function that will be drawn.",
],
"alpha": [0.2, "alpha value for the fill_between plot"],
}
[docs]
@doc.append_doc(ffit.fit_kwargs)
@doc.append_str("\t")
@doc.append_str(doc.array_table(default, init=False))
@doc.append_str(
doc.array_table({"plot_kwargs ": ["default", "description"]}, bottom=False)
)
@doc.append_str("\n\n")
def plot_kwargs(kwargs):
"""Set default :func:`plot_kwargs` if not set."""
kwargs = ffit.fit_kwargs(kwargs)
for k, v in default.items():
if k not in kwargs:
kwargs[k] = v[0]
return kwargs
# TODO optimize to minimize number of calls to function
# @append_doc(default_kwargs)
[docs]
def fit(func, *adata, **kwargs):
"""
Fit and plot function to datax and datay.
Parameters
----------
datax : array_like
X data either as ``unp.uarray`` or ``np.array`` or ``list``
datay : array_like
Y data either as ``unp.uarray`` or ``np.array`` or ``list``
function : func
Fit function with parameters: ``x``, ``params``
**kwargs : optional
see :func:`plot_kwargs`.
Fit parameters can be fixed via ``kwargs`` eg. ``a=5``.
Returns
-------
array_like
Optimized fit parameters of ``function`` to ``datax`` and ``datay``.
If ``datay`` is complex, both the real and imaginary part are returned.
Examples
--------
.. plot::
:include-source:
>>> from smpl import functions as f
>>> from smpl import plot
>>> param = plot.fit([0,1,2],[0,1,2],f.line)
>>> float(plot.unv(param).round()[0])
1.0
"""
if "xaxis" in kwargs and ("xlabel" not in kwargs or not kwargs["xlabel"]):
# warnings.warn("xaxis is deprecated. Use xlabel instead.", DeprecationWarning, 2)
kwargs["xlabel"] = kwargs["xaxis"]
# TODO maybe pop
if "yaxis" in kwargs and ("ylabel" not in kwargs or not kwargs["ylabel"]):
# warnings.warn("yaxis is deprecated. Use ylabel instead.", DeprecationWarning, 2)
kwargs["ylabel"] = kwargs["yaxis"]
# TODO maybe pop
function = func
if "function" in kwargs:
function = kwargs["function"]
del kwargs["function"]
adata = [func, *adata]
# Fix parameter order if necessary
elif isinstance(function, (list, tuple, np.ndarray)):
adata = [adata[-1], function, *adata[:-1]]
function = adata[0]
adata = adata[1:]
if util.true("bins", kwargs):
# yvalue will be overwritten
ndata = [*adata, *adata]
for i, o in enumerate(adata):
ndata[2 * i] = o
ndata[2 * i + 1] = o * 0
adata = ndata
assert len(adata) % 2 == 0, "data must be pairs of x and y data"
if len(adata) == 2:
datax, datay = adata
else:
rs = []
for i in range(0, len(adata), 2):
datax, datay = adata[i], adata[i + 1]
if util.true("bins", kwargs):
rs.append(fit(function, datax, **kwargs))
else:
rs.append(fit(function, datax, datay, **kwargs))
return rs
kwargs = plot_kwargs(kwargs)
if np.any(np.iscomplex(datay)):
label = util.get("label", kwargs, "")
kwargs["label"] = label + "(real)"
r = fit(datax, datay.real, function=function, **kwargs)
kwargs["label"] = label + "(imag)"
i = fit(datax, datay.imag, function=function, **kwargs)
return r, i
if kwargs["auto_fit"]:
best_f, best_ff, lambda_f = ffit.auto(datax, datay, function, **kwargs)
if best_f is not None:
del kwargs["auto_fit"]
fit(datax, datay, best_f, **kwargs)
return best_f, best_ff, lambda_f
if kwargs["also_fit"] == False and kwargs["label"] is None and kwargs["lpos"] == 0:
kwargs["lpos"] = -1
return _fit_impl(datax, datay, function, **kwargs)
def _fit_impl(datax, datay, function, **kwargs):
x = None
y = None
rfit = None
ifit = None
fig = None
fig = init_plot(kwargs)
ll = None
if kwargs["also_data"]:
ll = plt_data(datax, datay, **kwargs).get_color()
if kwargs["interpolate"]:
ifit, _, x, y = plt_interpolate(datax, datay, icolor=ll, **kwargs)
if kwargs["also_fit"]:
assert function is not None, "function must be given"
rfit, kwargs["fit_color"], _, _ = plt_fit(datax, datay, function, **kwargs)
if kwargs["ss"]:
kwargs["oldshow"] = kwargs["show"]
kwargs["show"] = kwargs["show"] and not kwargs["residue"]
save_plot(**kwargs)
kwargs["show"] = kwargs["oldshow"]
if kwargs["residue"] and fig is not None:
plt_residue(datax, datay, function, rfit, fig, **kwargs)
if not kwargs["also_fit"] and kwargs["interpolate"]:
return (ifit, x, y)
# return ifit
return rfit
# @append_doc(default_kwargs)
[docs]
def data(*data, function=None, **kwargs):
"""
Plot datay against datax via :func:`fit`
Parameters
----------
datax : array_like
X data either as ``unp.uarray`` or ``np.array`` or ``list``
datay : array_like
Y data either as ``unp.uarray`` or ``np.array`` or ``list``
function : func,optional
Fit function with parameters: ``x``, ``params``
**kwargs : optional
see :func:`plot_kwargs`.
Returns
-------
array_like
Optimized fit parameters of ``function`` to ``datax`` and ``datay``
"""
if "also_fit" not in kwargs:
kwargs["also_fit"] = False
kwargs = plot_kwargs(kwargs)
return fit(function=function, *data, **kwargs)
# @append_doc(default_kwargs)
[docs]
def auto(*adata, funcs=None, **kwargs):
"""
Automatically loop over functions and fit the best one.
Parameters
----------
funcs : function array
functions to consider as fit. Default all ``smpl.functions``.
**kwargs : optional
see :func:`plot_kwargs`.
Returns
-------
The best fit function and it's parameters. Also a lambda function where the parameters are already applied.
"""
if "auto_fit" not in kwargs:
kwargs["auto_fit"] = True
kwargs = plot_kwargs(kwargs)
return fit(function=funcs, *adata, **kwargs)
def _function(
func,
xfit,
fmt="-",
label=None,
function_color=None,
sigmas=0.0,
alpha=0.4,
**kwargs,
):
# kargs = {}
# if util.has("fmt", kwargs):
# kargs["fmt"] = kwargs["fmt"]
# if util.has("label", kwargs) and kwargs["label"] != "":
# kargs["label"] = kwargs["label"]
# if util.has("function_color", kwargs) and kwargs["function_color"] != "":
# kargs["color"] = kwargs["function_color"]
# if util.has("sigmas", kwargs) and kwargs["sigmas"] != "":
# kargs["sigmas"] = kwargs["sigmas"]
# if util.has("alpha", kwargs) and kwargs["alpha"] != "":
# kargs["alpha"] = kwargs["alpha"]
# __function(func, xfit, **kargs)
if label == "":
label = None
if function_color == "":
function_color = None
if sigmas == "":
sigmas = 0.0
if alpha == "":
alpha = 0.4
__function(
func,
xfit,
fmt=fmt,
label=label,
color=function_color,
sigmas=sigmas,
alpha=alpha,
**kwargs,
)
[docs]
def plt_plt(x, y, fmt, color, label, linestyle, **kwargs):
if linestyle is None and fmt is not None:
return plt.plot(x, y, fmt, label=label, color=color, **kwargs)
if linestyle is not None and fmt is None:
return plt.plot(x, y, label=label, color=color, linestyle=linestyle, **kwargs)
if linestyle is None and fmt is None:
return plt.plot(x, y, label=label, color=color, **kwargs)
# should not reach here
raise ValueError(
"Either fmt or linestyle must be given, but not both. fmt=%s, linestyle=%s"
% (fmt, linestyle)
)
def __function(
gfunc,
xlinspace,
fmt="-",
label=None,
color=None,
hatch=None,
sigmas=0.0,
linestyle=None,
alpha=0.4,
**kwargs,
):
# filter unused bad kwargs here to avoid passing them down
# TODO it would be better to not pass them down in the first place
for key in [
"pre",
"post",
"xaxis",
"yaxis",
"xvar",
"xmin",
"xmax",
"xlabel",
"ylabel",
"bins",
"binunc",
"bbox_to_anchor",
"tight",
"residue",
"lpos",
"interpolate",
"params",
"also_fit",
"init",
"frange",
"epsfcn",
"units",
"fselector",
"maxfev",
"sortbyx",
"xerror",
"yerror",
"fixed_params",
"autotqdm",
"fitter",
"title",
"where",
"save",
"prange",
"ss",
"also_data",
"auto_fit",
"data_sigmas",
"logy",
"logx",
"data_color",
"fit_color",
"fit_fmt",
"show",
"size",
"number_format",
"selector",
"fitinline",
"grid",
"hist",
"stairs",
"capsize",
"axes",
"xspace",
"extrapolate",
"extrapolate_min",
"extrapolate_max",
"extrapolate_fmt",
"extrapolate_hatch",
"function_color",
"residue_err",
"interpolate_fmt",
"interpolate_label",
"interpolate_lower_uncertainty",
"ncol",
"steps",
"interpolator",
"next_color",
]:
kwargs.pop(key, None)
func = gfunc
x = xlinspace
l = label
if isinstance(func(x)[0], uncertainties.UFloat):
if sigmas > 0:
(ll,) = plt_plt(
x,
unv(func(x)),
fmt,
label=None,
color=color,
linestyle=linestyle,
**kwargs,
)
y = func(x)
plt.fill_between(
x,
unv(y) - sigmas * usd(y),
unv(y) + sigmas * usd(y),
alpha=alpha,
label=l,
color=ll.get_color(),
hatch=hatch,
**kwargs,
)
else:
(ll,) = plt_plt(
x,
unv(func(x)),
fmt,
label=l,
color=color,
linestyle=linestyle,
**kwargs,
)
else:
(ll,) = plt_plt(
x, func(x), fmt, label=l, color=color, linestyle=linestyle, **kwargs
)
return ll
[docs]
def function(func, *args, fmt="-", **kwargs):
"""
Plot function ``func`` between ``xmin`` and ``xmax``
Parameters
----------
func : function
Function to be plotted between ``xmin`` and ``xmax``, only taking `array_like` ``x`` as parameter
*args : optional
arguments for ``func``
**kwargs : optional
see :func:`plot_kwargs`.
"""
kwargs["fmt"] = fmt
if not util.has("xmin", kwargs) or not util.has("xmax", kwargs):
kwargs["xmin"], kwargs["xmax"] = stat.get_interesting_domain(func)
# raise Exception("xmin or xmax missing.")
# if not util.has('lpos', kwargs) and not util.has('label', kwargs):
# kwargs['lpos'] = -1
if "label" not in kwargs:
kwargs = plot_kwargs(kwargs)
kwargs["label"] = get_fnc_legend(func, args, **kwargs)
else:
kwargs = plot_kwargs(kwargs)
xlin = kwargs["xspace"](kwargs["xmin"], kwargs["xmax"], kwargs["steps"])
init_plot(kwargs)
# kwargs['lpos'] = 0
# _plot(xfit, func(xfit, *args), **kwargs)
_function(wrap.get_lambda_argd(func, kwargs["xvar"], *args), xlin, **kwargs)
if kwargs["ss"]:
save_plot(**kwargs)
# xaxis="",yaxis="",fit_color=None,save = None,residue_err=True,show=False):
[docs]
def plt_residue(datax, datay, gfunction, rfit, fig, **kwargs):
function = wrap.get_lambda(gfunction, kwargs["xvar"])
fig.add_axes((0.1, 0.1, 0.8, 0.2))
kwargs["ylabel"] = "$\\Delta$" + kwargs["ylabel"]
kwargs["data_color"] = kwargs["fit_color"]
if kwargs["residue_err"]:
plt_data(datax, datay - function(datax, *rfit), **kwargs)
else:
plt_data(unv(datax), unv(datay - function(datax, *rfit)), **kwargs)
kwargs["lpos"] = -1
save_plot(**kwargs)
[docs]
def data_split(datax, datay, **kwargs):
return ffit.data_split(datax, datay, **kwargs)
def _fit(datax, datay, function, **kwargs):
"""
Returns a fit like :func:`fit` but does no plotting.
"""
return ffit.fit(datax, datay, function, **kwargs)
[docs]
def plt_data(datax, datay, **kwargs):
"""
Plot datay vs datax
"""
x, y, xerr, yerr = data_split(datax, datay, **kwargs)
if xerr is not None:
xerr = xerr * kwargs["data_sigmas"]
if yerr is not None:
yerr = yerr * kwargs["data_sigmas"]
ll = None
if xerr is None and yerr is None:
if kwargs["fmt"] is None:
if kwargs["linestyle"] is None:
(ll,) = plt.plot(
x, y, label=kwargs["label"], color=kwargs["data_color"]
)
else:
(ll,) = plt.plot(
x,
y,
label=kwargs["label"],
color=kwargs["data_color"],
linestyle=kwargs["linestyle"],
)
elif kwargs["fmt"] == "step":
(ll,) = plt.step(
x,
y,
where=kwargs["where"],
label=kwargs["label"],
color=kwargs["data_color"],
)
elif kwargs["fmt"] == "hist":
(ll,) = plt.step(
x,
y,
where=kwargs["where"],
label=kwargs["label"],
color=kwargs["data_color"],
)
plt.fill_between(x, y, step="mid", color=ll.get_color())
else:
(ll,) = plt.plot(
x, y, kwargs["fmt"], label=kwargs["label"], color=kwargs["data_color"]
)
elif kwargs["fmt"] is None:
if kwargs["linestyle"] is None:
(
ll,
_,
_,
) = plt.errorbar(
x,
y,
yerr=yerr,
xerr=xerr,
fmt=" ",
capsize=kwargs["capsize"],
label=kwargs["label"],
color=kwargs["data_color"],
)
else:
(
ll,
_,
_,
) = plt.errorbar(
x,
y,
yerr=yerr,
xerr=xerr,
fmt=" ",
capsize=kwargs["capsize"],
label=kwargs["label"],
color=kwargs["data_color"],
linestyle=kwargs["linestyle"],
)
elif kwargs["fmt"] == "step":
(ll,) = plt.step(x, y, where=kwargs["where"], color=kwargs["data_color"])
if xerr is not None:
for ix, xv in enumerate(x):
dx = xerr[ix]
tx = [xv - dx, xv + dx]
plt.fill_between(
tx,
y[ix] - yerr[ix],
y[ix] + yerr[ix],
label=kwargs["label"] if ix == 1 else None,
alpha=kwargs["alpha"],
step="pre",
color=ll.get_color(),
)
else:
plt.fill_between(
x,
y - yerr,
y + yerr,
label=kwargs["label"],
alpha=kwargs["alpha"],
step="mid",
color=ll.get_color(),
)
elif kwargs["fmt"] == "hist":
(
ll,
_,
_,
) = plt.errorbar(
x,
y,
yerr=yerr,
xerr=xerr,
fmt=" ",
capsize=kwargs["capsize"],
color="black",
)
plt.fill_between(x, y, step="mid", label=kwargs["label"], color=ll.get_color())
else:
(
ll,
_,
_,
) = plt.errorbar(
x,
y,
yerr=yerr,
xerr=xerr,
fmt=kwargs["fmt"],
capsize=kwargs["capsize"],
label=kwargs["label"],
color=kwargs["data_color"],
)
return ll
[docs]
def get_fnc_legend(function, rfit, **kwargs):
l = wrap.get_latex(function)
vnames = wrap.get_varnames(function, kwargs["xvar"])
for i in range(1, len(vnames)):
l = l + ("\n" if not kwargs["fitinline"] or i == 1 else " ")
l = l + "$" + sympy.latex(sympy.symbols(str(vnames[i]))) + "$="
if kwargs["units"] is not None and usd(rfit[i - 1]) > 0:
l = l + "("
if "number_format" in kwargs:
l = l + kwargs["number_format"].format(rfit[i - 1])
else:
l = l + "%s" % (rfit[i - 1])
if kwargs["units"] is not None and usd(rfit[i - 1]) > 0:
l = l + ")"
if kwargs["units"] is not None:
l = l + " " + kwargs["units"][i - 1]
return l
[docs]
def plt_fit_or_interpolate(
datax, datay, fitted, l=None, c=None, f=None, ls=None, **kwargs
):
# just filter these kwargs out, so they dont get passed down and are replaced by above args
# TODO why not pass label=XXX directly to this?
# -> probably since there are cases where both e.g. color and replace color are needed
for key in ["color", "label", "fmt", "linestyle", "hatch"]:
kwargs.pop(key, None)
if kwargs["prange"] is None:
x, _, _, _ = ffit.fit_split(datax, datay, **kwargs)
xfit = kwargs["xspace"](np.min(unv(x)), np.max(unv(x)), kwargs["steps"])
else:
xfit = kwargs["xspace"](
kwargs["prange"][0], kwargs["prange"][1], kwargs["steps"]
)
ll = __function(
fitted,
xfit,
kwargs["fit_fmt"] if f is not None and ls is None else f,
label=l,
color=kwargs["fit_color"] if c is None else c,
linestyle=ls,
**kwargs,
)
if (
(
(kwargs["frange"] is not None or kwargs["fselector"] is not None)
and util.true("extrapolate", kwargs)
)
or util.has("extrapolate_max", kwargs)
or util.has("extrapolate_min", kwargs)
):
xxfit = kwargs["xspace"](
util.get("extrapolate_min", kwargs, np.min(unv(datax))),
util.get("extrapolate_max", kwargs, np.max(unv(datax))),
kwargs["steps"],
)
for pmin, pmax in [
(np.min(xxfit), np.min(xfit)),
(np.max(xfit), np.max(xxfit)),
]:
__function(
fitted,
kwargs["xspace"](pmin, pmax, kwargs["steps"]),
util.get("extrapolate_fmt", kwargs, "--"),
color=ll.get_color(),
hatch=util.get("extrapolate_hatch", kwargs, r"||"),
**kwargs,
)
return ll.get_color(), xfit, fitted(xfit)
[docs]
def plt_interpolate(datax, datay, icolor=None, **kwargs):
"""
Interpolate and Plot that Interpolation.
"""
inter = interpolate.interpolate(datax, datay, **kwargs)
kargs = {}
if isinstance(kwargs["interpolate_fmt"], tuple):
kargs["ls"] = kwargs["interpolate_fmt"]
else:
kargs["f"] = kwargs["interpolate_fmt"]
if kwargs["interpolate_label"] is not None:
kargs["l"] = kwargs["interpolate_label"]
# l = None so that no label
return (
inter,
*plt_fit_or_interpolate(datax, datay, inter, c=icolor, **kargs, **kwargs),
)
[docs]
def plt_fit(datax, datay, gfunction, **kwargs):
"""
Fit and Plot that Fit.
"""
func = wrap.get_lambda(gfunction, kwargs["xvar"])
rfit = _fit(datax, datay, gfunction, **kwargs)
def fitted(x):
return func(x, *rfit)
vnames = wrap.get_varnames(gfunction, kwargs["xvar"])
for v in vnames[1:]: # remove fixed parameters from kwargs
kwargs.pop(v, None)
l = get_fnc_legend(gfunction, rfit, **kwargs)
return (rfit, *plt_fit_or_interpolate(datax, datay, fitted, l, **kwargs))
[docs]
def init_plot(kwargs):
fig = None
if util.has("axes", kwargs) and kwargs["axes"] is not None:
plt.sca(kwargs["axes"])
fig = kwargs["axes"].get_figure()
if kwargs["init"] or util.true("residue", kwargs):
if kwargs["size"] is None:
fig = plt.figure()
else:
fig = plt.figure(figsize=kwargs["size"])
if kwargs["residue"]:
fig.add_axes((0.1, 0.3, 0.8, 0.6))
if util.has("next_color", kwargs) and not kwargs["next_color"]:
lines = plt.gca()._get_lines
tmp_color = lines._cycler_items[lines._idx]["color"]
if kwargs["data_color"] is None:
kwargs["data_color"] = tmp_color
if kwargs["fit_color"] is None:
kwargs["fit_color"] = tmp_color
if kwargs["function_color"] is None:
kwargs["function_color"] = tmp_color
return fig
[docs]
def save_plot(**kwargs):
"""
save plot
"""
smplr.style_plot1d(**kwargs)
if "lpos" in kwargs and kwargs["lpos"] >= 0:
if util.has("bbox_to_anchor", kwargs):
if util.has("ncol", kwargs):
plt.legend(
loc=kwargs["lpos"],
bbox_to_anchor=kwargs["bbox_to_anchor"],
ncol=kwargs["ncol"],
borderaxespad=0,
)
else:
plt.legend(loc=kwargs["lpos"], bbox_to_anchor=kwargs["bbox_to_anchor"])
else:
plt.legend(loc=kwargs["lpos"])
if "save" in kwargs and kwargs["save"] is not None:
io.mkdirs(kwargs["save"])
plt.savefig(kwargs["save"] + ".pdf")
if kwargs.get("show"):
show(**kwargs)
[docs]
def show(**kwargs):
kwargs = plot_kwargs(kwargs)
smplr.style_plot1d(**kwargs)
plt.show()
from smpl.plot2d import plot2d as _plot2d
from smpl.plot2d import plot2d_kwargs as _plot2d_kwargs
[docs]
def plot2d(*args, **kwargs):
_plot2d(*args, **kwargs)
[docs]
def plot2d_kwargs(*args, **kwargs):
_plot2d_kwargs(*args, **kwargs)