def scatter(df, x, y, ax=None, legend=None, title=None,
            color=None, marker='o', linestyle=None, cmap=None,
            groupby=['model', 'scenario'], with_lines=False, **kwargs):
    if ax is None:
        fig, ax = plt.subplots()
    props = assign_style_props(df, color=color, marker=marker,
                               linestyle=linestyle, cmap=cmap)
    groups = df.groupby(groupby)
    legend_data = []
    for name, group in groups:
        pargs = {}
        labels = []
        for key, kind, var in [('c', 'color', color),
                               ('marker', 'marker', marker),
                               ('linestyle', 'linestyle', linestyle)]:
            if kind in props:
                label = group[var].values[0]
                pargs[key] = props[kind][group[var].values[0]]
                labels.append(repr(label).lstrip("u'").strip("'"))
            else:
                pargs[key] = var
        if len(labels) > 0:
            legend_data.append(' '.join(labels))
        else:
            legend_data.append(' '.join(name))
        kwargs.update(pargs)
        if with_lines:
            ax.plot(group[x], group[y], **kwargs)
        else:
            kwargs.pop('linestyle')
            ax.scatter(group[x], group[y], **kwargs)
    handles, labels = ax.get_legend_handles_labels()
    if legend_data != [''] * len(legend_data):
        labels = sorted(list(set(tuple(legend_data))))
        idxs = [legend_data.index(d) for d in labels]
        handles = [handles[i] for i in idxs]
    if legend is None and len(labels) < 13 or legend is not False:
        _add_legend(ax, handles, labels, legend)
    ax.set_xlabel(x)
    ax.set_ylabel(y)
    if title:
        ax.set_title(title)
    return ax