def assign_style_props(df, color=None, marker=None, linestyle=None,
                       cmap=None):
    if color is None and cmap is not None:
        raise ValueError('`cmap` must be provided with the `color` argument')
    n = len(df[color].unique()) if color in df.columns else \
        len(df[list(set(df.columns) & set(IAMC_IDX))].drop_duplicates())
    defaults = default_props(reset=True, num_colors=n, colormap=cmap)
    props = {}
    rc = run_control()
    kinds = [('color', color), ('marker', marker), ('linestyle', linestyle)]
    for kind, var in kinds:
        rc_has_kind = kind in rc
        if var in df.columns:
            rc_has_var = rc_has_kind and var in rc[kind]
            props_for_kind = {}
            for val in df[var].unique():
                if rc_has_var and val in rc[kind][var]:
                    props_for_kind[val] = rc[kind][var][val]
                    next(defaults[kind])
                else:
                    props_for_kind[val] = next(defaults[kind])
            props[kind] = props_for_kind
    if 'color' in props:
        d = props['color']
        values = list(d.values())
        overlap_idx = np.in1d(values, list(PYAM_COLORS.keys()))
        if overlap_idx.any():
            keys = np.array(list(d.keys()))[overlap_idx]
            values = np.array(values)[overlap_idx]
            for k, v in zip(keys, values):
                d[k] = PYAM_COLORS[v]
            props['color'] = d
    return props