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):
    """Plot data as a scatter chart.

    Parameters
    ----------
    df : pd.DataFrame
        Data to plot as a long-form data frame
    x : str
        column to be plotted on the x-axis
    y : str
        column to be plotted on the y-axis
    ax : matplotlib.Axes, optional
    legend : bool, optional
        Include a legend (`None` displays legend only if less than 13 entries)
        default: None
    title : bool or string, optional
        Display a custom title.
    color : string, optional
        A valid matplotlib color or column name. If a column name, common
        values will be provided the same color.
        default: None
    marker : string
        A valid matplotlib marker or column name. If a column name, common
        values will be provided the same marker.
        default: 'o'
    linestyle : string, optional
        A valid matplotlib linestyle or column name. If a column name, common
        values will be provided the same linestyle.
        default: None
    cmap : string, optional
        A colormap to use.
        default: None
    groupby : list-like, optional
        Data grouping for plotting.
        default: ['model', 'scenario']
    with_lines : bool, optional
        Make the scatter plot with lines connecting common data.
        default: False
    kwargs : Additional arguments to pass to the pd.DataFrame.plot() function
    """
    if ax is None:
        fig, ax = plt.subplots()

    # assign styling properties
    props = assign_style_props(df, color=color, marker=marker,
                               linestyle=linestyle, cmap=cmap)

    # group data
    groups = df.groupby(groupby)

    # loop over grouped dataframe, plot data
    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')  # scatter() can't take a linestyle
            ax.scatter(group[x], group[y], **kwargs)

    # build legend handles and labels
    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)

    # add labels and title
    ax.set_xlabel(x)
    ax.set_ylabel(y)
    if title:
        ax.set_title(title)

    return ax
Plot data as a scatter chart.

    Parameters
    ----------
    df : pd.DataFrame
        Data to plot as a long-form data frame
    x : str
        column to be plotted on the x-axis
    y : str
        column to be plotted on the y-axis
    ax : matplotlib.Axes, optional
    legend : bool, optional
        Include a legend (`None` displays legend only if less than 13 entries)
        default: None
    title : bool or string, optional
        Display a custom title.
    color : string, optional
        A valid matplotlib color or column name. If a column name, common
        values will be provided the same color.
        default: None
    marker : string
        A valid matplotlib marker or column name. If a column name, common
        values will be provided the same marker.
        default: 'o'
    linestyle : string, optional
        A valid matplotlib linestyle or column name. If a column name, common
        values will be provided the same linestyle.
        default: None
    cmap : string, optional
        A colormap to use.
        default: None
    groupby : list-like, optional
        Data grouping for plotting.
        default: ['model', 'scenario']
    with_lines : bool, optional
        Make the scatter plot with lines connecting common data.
        default: False
    kwargs : Additional arguments to pass to the pd.DataFrame.plot() function