python - Plotly-Dash:如何过滤具有多个数据框列的仪表板?

标签 python plotly plotly-dash plotly-python

我有一个使用 dash 构建的 Python 仪表板,我想过滤 Investor Fund专栏。

  Investor    Fund Period Date Symbol  Shares  Value
0     Rick  Fund 3  2019-06-30   AVLR       3      9
1     Faye  Fund 2  2015-03-31    MEG      11     80
2     Rick  Fund 3  2018-12-31    BAC      10    200
3      Dre  Fund 4  2020-06-30   PLOW       2     10
4     Faye  Fund 2  2015-03-31   DNOW      10    100
5     Mike  Fund 1  2015-03-31    JNJ       1     10
6     Mike  Fund 1  2018-12-31    QSR       4     20
7     Mike  Fund 1  2018-12-31  LBTYA       3     12

换句话说,用户应该能够在同一过滤字段中输入一个或多个投资者和/或一个或多个基金,并且仪表板将相应更新。所以我认为我需要改变:

options=[{'label': i, 'value': i} for i in df['Investor'].unique()]

类似于 groupby但我不积极?这是我的代码:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

data = {'Investor': {0: 'Rick', 1: 'Faye', 2: 'Rick', 3: 'Dre', 4: 'Faye', 5: 'Mike', 6: 'Mike', 7: 'Mike'},
        'Fund': {0: 'Fund 3', 1: 'Fund 2', 2: 'Fund 3', 3: 'Fund 4', 4: 'Fund 2', 5: 'Fund 1', 6: 'Fund 1', 7: 'Fund 1'},
        'Period Date': {0: '2019-06-30', 1: '2015-03-31', 2: '2018-12-31', 3: '2020-06-30', 4: '2015-03-31', 5: '2015-03-31', 6: '2018-12-31', 7: '2018-12-31'},
        'Symbol': {0: 'AVLR', 1: 'MEG', 2: 'BAC', 3: 'PLOW', 4: 'DNOW', 5: 'JNJ', 6: 'QSR', 7: 'LBTYA'},
        'Shares': {0: 3, 1: 11, 2: 10, 3: 2, 4: 10, 5: 1, 6: 4, 7: 3},
        'Value': {0: 9, 1: 80, 2: 200, 3: 10, 4: 100, 5: 10, 6: 20, 7: 12}}
df = pd.DataFrame.from_dict(data)

def generate_table(dataframe, max_rows=100):
    return html.Table(
        # Header
        [html.Tr([html.Th(col) for col in dataframe.columns])] +

        # Body
        [html.Tr([
            html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
        ]) for i in range(min(len(dataframe), max_rows))]
    )

app = dash.Dash()
app.layout = html.Div(
    children=[html.H4(children='Investor Portfolio'),
    dcc.Dropdown(
        id='dropdown',
        options=[{'label': i, 'value': i} for i in df['Investor'].unique()],
        multi=True, placeholder='Filter by Investor or Fund...'),
    html.Div(id='table-container')
])

@app.callback(dash.dependencies.Output('table-container', 'children'),
    [dash.dependencies.Input('dropdown', 'value')])

def display_table(dropdown_value):
    if dropdown_value is None:
        return generate_table(df)
    dff = df[df.Investor.str.contains('|'.join(dropdown_value))]
    dff = dff[['Investor', 'Period Date', 'Symbol','Shares', 'Value']]
    return generate_table(dff)

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

最佳答案

诚然,我对 Dash 还很陌生,但据我所知,您可以通过扩展选项列表,然后使用 or 来实现您想要的目标。条件在 dff您在 Dash 应用程序中显示的内容包括 Fund专栏。

这有点暴力,更好的解决方案是让 Dash 知道您选择的选项来自哪些列。但是,只有当不同列中的条目包含相同的字符串时,这才会成为问题(这里 InvestorFund 的唯一值不相同)。

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

data = {'Investor': {0: 'Rick', 1: 'Faye', 2: 'Rick', 3: 'Dre', 4: 'Faye', 5: 'Mike', 6: 'Mike', 7: 'Mike'},
        'Fund': {0: 'Fund 3', 1: 'Fund 2', 2: 'Fund 3', 3: 'Fund 4', 4: 'Fund 2', 5: 'Fund 1', 6: 'Fund 1', 7: 'Fund 1'},
        'Period Date': {0: '2019-06-30', 1: '2015-03-31', 2: '2018-12-31', 3: '2020-06-30', 4: '2015-03-31', 5: '2015-03-31', 6: '2018-12-31', 7: '2018-12-31'},
        'Symbol': {0: 'AVLR', 1: 'MEG', 2: 'BAC', 3: 'PLOW', 4: 'DNOW', 5: 'JNJ', 6: 'QSR', 7: 'LBTYA'},
        'Shares': {0: 3, 1: 11, 2: 10, 3: 2, 4: 10, 5: 1, 6: 4, 7: 3},
        'Value': {0: 9, 1: 80, 2: 200, 3: 10, 4: 100, 5: 10, 6: 20, 7: 12}}
df = pd.DataFrame.from_dict(data)

def generate_table(dataframe, max_rows=100):
    return html.Table(
        # Header
        [html.Tr([html.Th(col) for col in dataframe.columns])] +

        # Body
        [html.Tr([
            html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
        ]) for i in range(min(len(dataframe), max_rows))]
    )

app = dash.Dash()
app.layout = html.Div(
    children=[html.H4(children='Investor Portfolio'),
    dcc.Dropdown(
        id='dropdown',
        ## extend the options to consider unique Fund values as well
        options=[{'label': i, 'value': i} for i in df['Investor'].unique()] + [{'label': i, 'value': i} for i in df['Fund'].unique()],
        multi=True, placeholder='Filter by Investor or Fund...'),
    html.Div(id='table-container')
])

@app.callback(dash.dependencies.Output('table-container', 'children'),
    [dash.dependencies.Input('dropdown', 'value')])

def display_table(dropdown_value):
    if dropdown_value is None:
        return generate_table(df)

    ## add an 'or' condition for the other column you want to use to slice the df 
    ## and update the columns that are displayed
    dff = df[df.Investor.str.contains('|'.join(dropdown_value)) | df.Fund.str.contains('|'.join(dropdown_value))]
    dff = dff[['Investor', 'Fund', 'Period Date', 'Symbol','Shares', 'Value']]
    return generate_table(dff)

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

enter image description here

关于python - Plotly-Dash:如何过滤具有多个数据框列的仪表板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65656053/

相关文章:

python - Altair 中的多项选择

Python noob for 循环?

python - 破折号/阴谋在间隔= 500时歇斯底里

python - 使用plotly创建条形图

plotly - 如何在 Plotly 中设置非零零线

javascript - Plotly-Dash:如何确定客户端回调中的触发器输入

python - 安装 Steam 库时出现 PermissionError no 13

python - 在 Kubernetes 上创建 HTTPS 端点的最简单方法是什么?

r - 如何使用函数 ggplot() 和 plot_ly 增加 R 中轴标签和轴标题之间的空间?

plotly - 如何从可编辑表中更新绘图/破折号?