Dash Plotly - Как сделать 2 условия для построения гистограммы? - PullRequest
1 голос
/ 06 марта 2019

Я ищу способ построения гистограммы для данных, относящихся к 2 Dropdown.Я должен выбрать значение firstcall и значение secondcall, чтобы построить гистограмму.Я не нахожу много литературы по этому вопросу. Надеюсь, один из вас уже сталкивался с этим.

Пожалуйста, найдите файл Excel с некоторыми данными и кодом, который я пытаюсь использовать ниже:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd

df = pd.read_excel(
    "/Users/appelexcel.xlsx"
)

mgr_options = df["premierappel"].unique()
mgr_options_second = df["secondappel"].unique()

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

colors = {
    'background': '#FDFFFF',
    'text': '#0A25DC'
}

app.layout = html.Div(style={'backgroundColor': colors['background']},children=[
    html.H1(children='Call',
     style={
            'textAlign': 'center',
            'color': colors['text']
        }
        ),

    html.Div(
        [
            dcc.Dropdown(
                id="premierappel",
                options=[{
                    'label': i,
                    'value': i
                } for i in mgr_options],
                value='All First Call'),
        ],
        style={'width': '25%',
               'display': 'inline-block'}),
    dcc.Graph(id='secondcallgraph'), 
 #The first plot just give the 2nd call

    html.Div(
        [
            dcc.Dropdown(
                id="secondappel",
                options=[{
                    'label': i,
                    'value': i
                } for i in mgr_options_second],
                value='All Second Call'),
        ],
        style={'width': '25%',
               'display': 'inline-block'}),
    dcc.Graph(id='thirdcallgraph'), # second figure
])


@app.callback(
    dash.dependencies.Output('secondcallgraph', 'figure'),
    [dash.dependencies.Input('premierappel', 'value')])
def update_graph(premierappel):
    if premierappel == "All First Call":
        df_plot = df.copy()
    else:
        df_plot = df[df['premierappel'] == premierappel]

    #func=(lambda x: round(100*x.count()/df_plot.shape[0] ,2))
    pv = pd.pivot_table(
        df_plot,
        index=['Age_1_2'],
        columns=['secondappel'],
        values=['frequency_1_2'],
        aggfunc=sum,
        fill_value=0)

    trace1 = go.Bar(x=pv.index, y=pv[('frequency_1_2', 'modification')], name='Modification')
    trace2 = go.Bar(x=pv.index, y=pv[('frequency_1_2', 'informations')], name='Informations')
    trace3 = go.Bar(x=pv.index, y=pv[('frequency_1_2', 'autres')], name='Autres')
    trace4 = go.Bar(x=pv.index, y=pv[('frequency_1_2', 'achat')], name='Achat')

    return {
        'data': [trace1, trace2, trace3, trace4],
        'layout':
        go.Layout(
            title='Appel 2 / {}'.format(premierappel),
            xaxis=dict(
                title='Days after 1st Call'),
            yaxis=dict(
                title='Count'),
            barmode='stack')
    }

Второй график (при третьем вызове)

Здесь возникает моя проблема, как я могу сказать ему, чтобы он принял во внимание 2 условия (одно при первом вызове и другое при квалификации второго вызова)?

@app.callback(
    dash.dependencies.Output('thirdcallgraph', 'figure'),
    [dash.dependencies.Input('premierappel', 'value'), dash.dependencies.Input('secondappel', 'value')])
def update_graph(premierappel,secondappel):
    if premierappel & secondappel == "All Second Call":
        df_plot = df.copy()
    else:
        df_plot = df[(df['premierappel']==premierappel) & (df['secondappel']==secondappel)]

    #func=(lambda x: round(100*x.count()/df_plot.shape[0] ,2))
    pv = pd.pivot_table(
        df_plot,
        index=['Age_2_3'],
        columns=['troisiemeappel'],
        values=['frequency_2_3'],
        aggfunc=sum,
        fill_value=0)

    trace1 = go.Bar(x=pv.index, y=pv[('frequency_2_3', 'modification')], name='Modification')
    trace2 = go.Bar(x=pv.index, y=pv[('frequency_2_3', 'informations')], name='Informations')
    trace3 = go.Bar(x=pv.index, y=pv[('frequency_2_3', 'autres')], name='Autres')
    trace4 = go.Bar(x=pv.index, y=pv[('frequency_2_3', 'achat')], name='Achat')

    return {
        'data': [trace1, trace2, trace3, trace4],
        'layout':
        go.Layout(
            title='Appel 2 / {}'.format(secondappel),
            xaxis=dict(
                title='Days after 2nd Call'),
            yaxis=dict(
                title='Count'),
            barmode='stack')
    }


if __name__ == '__main__':
    app.run_server(debug=True)

Спасибо за ваше время!

Возраст _._.: время между звонками.

Частота: должна быть частотой, но она действительно случайна, просто чтобы посмотреть, как она работает.

Пожалуйста, найдите данные выше.https://docs.google.com/spreadsheets/d/1u7E6GwJj1nsjOwIQIntcCWCKsczw36_iHPiEV2bjMcs/edit?usp=sharing

1 Ответ

0 голосов
/ 07 марта 2019

Я не могу обернуть голову вокруг того, что это значит.Но вот что я могу предположить из сообщений об ошибках, которые я получаю:

File "pandas\_libs\index.pyx", line 672, inpandas._libs.index.BaseMultiIndexCodesEngine.get_loc

KeyError: ('frequency_2_3', 'modification')

Вот и все.

При вашем втором обратном вызове вы назначаете четыре трассировки.Но переменная (pandas.Series ()) pv будет содержать только один столбец (во время моих испытаний по отладке).

Предполагается, что второй обратный вызов должен работать как фильтр: решение может включатьIf ... elif ... else блок.

...