Ejemplo n.º 1
0
def ts_gradient(dfg, type_trans, avg_month):
    """
        Creates a timeseries plot where all years are ploted simultaneously

        Args:
            dfg:        dataframe to use
            type_trans: type of transaction [Income/Expense]
            avg_month:  month to use in time average

        Returns:
            the plotly plot as html-div format
    """

    if type_trans in [c.names.INCOMES, c.names.EXPENSES]:
        df = dfg[dfg[c.cols.TYPE] == type_trans].copy()

    else:
        df = dfg.copy()
        mfilter = df[c.cols.TYPE] == c.names.EXPENSES
        df.loc[mfilter, c.cols.AMOUNT] = -df.loc[mfilter, c.cols.AMOUNT]

    df = u.group_df_by(df, "M")

    if df.shape[0] == 0:
        return {}

    df = u.time_average(df, avg_month)

    max_width = 5

    color_name = {
        c.names.INCOMES: "green",
        c.names.EXPENSES: "red"
    }.get(type_trans, "amber")

    data = []

    for year in sorted(set(df.index.year), reverse=False):

        index_color = max(100, 900 - 200 * (max(df.index.year) - year))
        color = u.get_colors((color_name, index_color))

        df_aux = df[df.index.year == year]

        data.append(
            go.Scatter(
                x=df_aux.index.month,
                y=df_aux[c.cols.AMOUNT].values,
                line={
                    "width": min(0.5 * (year - min(df.index.year)) + 1,
                                 max_width)
                },
                marker={"color": color},
                name=year,
                mode="lines",
            ))

    layout = go.Layout(title="Time comparison ({})".format(type_trans),
                       hovermode="closest")
    return go.Figure(data=data, layout=layout)
Ejemplo n.º 2
0
def dist_plot(dfg):
    """
        Creates a distribution plot with expenses, incomes and ebit

        Args:
            dfg:    dataframe to use

        Returns:
            the plotly plot as html-div format
    """

    dfe = u.group_df_by(dfg[dfg[c.cols.TYPE] == c.names.EXPENSES], "M")
    dfi = u.group_df_by(dfg[dfg[c.cols.TYPE] == c.names.INCOMES], "M")

    df_baii = dfi - dfe

    iter_data = [
        (df_baii, c.names.EBIT, c.colors.EBIT),
        (dfe, c.names.EXPENSES, c.colors.EXPENSES),
        (dfi, c.names.INCOMES, c.colors.INCOMES),
    ]

    # Generate traces to show. This allow to disable traces if there is no data
    data, names, colors = [], [], []
    for df, name, color in iter_data:

        # Some data needed
        if (df[c.cols.AMOUNT].sum() > 0) and (len(df[c.cols.AMOUNT].unique()) >
                                              1):
            data.append(df[c.cols.AMOUNT].fillna(0).tolist())
            names.append(name)
            colors.append(color)

    if not data:
        return {}

    fig = FF.create_distplot(data, names, colors=colors, bin_size=100)

    fig["layout"].update(title="Incomes, Expenses and EBIT distribution")

    return fig
Ejemplo n.º 3
0
def plot_expenses_vs_liquid(df_liquid_in,
                            df_trans_in,
                            avg_month,
                            show_rec=True,
                            height=None):
    """
        Creates a plot to compare liquid and expenses

        Args:
            df_liq_in:      dataframe with liquid info
            df_trans_in:    dataframe with transactions
            avg_month:      month to use in time average
            show_rec:       bool for show/hide recommended liquids
            height:     height of the plot

        Returns:
            the plotly plot as html-div format
    """

    df_l = df_liquid_in.set_index(c.cols.DATE).copy()
    df_l = u.time_average(df_l.fillna(0), avg_month)

    df_t = u.group_df_by(
        df_trans_in[df_trans_in[c.cols.TYPE] == c.names.EXPENSES], "M")
    df_t = u.time_average(df_t, avg_month)

    iter_data = [
        (df_t, df_t[c.cols.AMOUNT], c.names.EXPENSES, c.colors.EXPENSES),
        (df_l, df_l[c.names.TOTAL], c.names.LIQUID, c.colors.LIQUID),
        (df_t, MONTHS_MIN * df_t[c.cols.AMOUNT], c.names.LIQUID_MIN_REC,
         c.colors.LIQUID_MIN_REC),
        (df_t, MONTHS_REC * df_t[c.cols.AMOUNT], c.names.LIQUID_REC,
         c.colors.LIQUID_REC),
    ]

    if not show_rec:
        iter_data = iter_data[:2]

    data = [
        go.Scatter(x=df.index,
                   y=y,
                   name=name,
                   marker={"color": color},
                   mode="lines") for df, y, name, color in iter_data
    ]

    layout = go.Layout(title="Liquid vs Expenses",
                       showlegend=show_rec,
                       height=height)
    return go.Figure(data=data, layout=layout)
Ejemplo n.º 4
0
def plot_months(df_liquid_in,
                df_trans_in,
                avg_month,
                show_rec=True,
                height=None):
    """
        Creates a plot to compare liquid and expenses

        Args:
            df_liq_in:      dataframe with liquid info
            df_trans_in:    dataframe with transactions
            avg_month:      month to use in time average
            show_rec:       bool for show/hide recommended liquids
            height:     height of the plot

        Returns:
            the plotly plot as html-div format
    """

    df_l = df_liquid_in.set_index(c.cols.DATE).copy()
    df_l = u.time_average(df_l.fillna(0), avg_month)

    df_t = u.group_df_by(
        df_trans_in[df_trans_in[c.cols.TYPE] == c.names.EXPENSES], "M")
    df_t = u.time_average(df_t, avg_month)

    serie = df_l[c.names.TOTAL] / df_t[c.cols.AMOUNT]

    iter_data = [
        (serie, "Months", c.colors.LIQUID),
        ([MONTHS_MIN] * len(serie), "Minimum months of liquid",
         c.colors.LIQUID_MIN_REC),
        ([MONTHS_REC] * len(serie), "Recommended months of liquid",
         c.colors.LIQUID_REC),
    ]

    if not show_rec:
        iter_data = iter_data[:1]

    data = [
        go.Scatter(x=serie.index,
                   y=y,
                   name=name,
                   marker={"color": color},
                   mode="lines") for y, name, color in iter_data
    ]

    layout = go.Layout(title="Survival months with current liquid",
                       height=height)
    return go.Figure(data=data, layout=layout)
Ejemplo n.º 5
0
def passive_income_vs_expenses(df_wor_in, df_trans_in, avg_month, smooth):
    """
        Compares what can be generated with passive income to expanses

        Args:
            df_wor_in:      dataframe with investment worth
            df_trans_in:    dataframe with transactions
            avg_month:      month to use in time average
            smooth:     bool to allow/disable passive smoothing

        Returns:
            the plotly plot as html-div format
    """

    dfw = df_wor_in.set_index(c.cols.DATE)[[c.names.TOTAL]]
    if smooth:
        dfw = u.time_average(dfw, avg_month)

    dfe = u.group_df_by(
        df_trans_in[df_trans_in[c.cols.TYPE] == c.names.EXPENSES], "M")
    dfe = u.time_average(dfe, avg_month)

    data = [
        go.Scatter(
            x=dfw.index,
            y=dfw[c.names.TOTAL] * 0.04 / 12,
            name="Passive income",
            marker={"color": c.colors.INCOMES_PASSIVE},
        ),
        go.Scatter(x=dfe.index,
                   y=dfe[c.cols.AMOUNT],
                   name="Expenses",
                   marker={"color": c.colors.EXPENSES}),
    ]

    layout = go.Layout(title="Passive income vs expenses", barmode="stack")
    return go.Figure(data=data, layout=layout)
Ejemplo n.º 6
0
def get_heatmap(dfg, type_trans):
    """
        Creates a heatmap with expenses or incomes

        Args:
            dfg:        dataframe to use
            type_trans: type of transaction [Income/Expense]

        Returns:
            the plotly plot as html-div format
    """

    df = u.group_df_by(dfg[dfg[c.cols.TYPE] == type_trans], "M")

    # No data no fun
    if df.shape[0] < 2:
        return {}

    df[c.cols.YEAR], df[c.cols.MONTH_DATE] = df.index.year, df.index.month

    df = df.pivot(c.cols.MONTH_DATE, c.cols.YEAR,
                  c.cols.AMOUNT).sort_index(ascending=False)

    # Fix month names
    df.index = [month_abbr[x] for x in df.index]

    cmap = {c.names.INCOMES: "Greens", c.names.EXPENSES: "YlOrRd"}[type_trans]

    data = go.Heatmap(x=df.columns,
                      y=df.index,
                      z=df.values,
                      colorscale=cmap,
                      reversescale=True,
                      showscale=False)

    layout = go.Layout(title="Heatmap ({})".format(type_trans))
    return go.Figure(data=[data], layout=layout)