动态数据框和Dash回调中的条件样式化

huangapple go评论58阅读模式
英文:

Dynamic dataframe and conditional styling in dash callbacks

问题

我是新手,尝试为我的数据表格(DashTable)添加样式,使得与同一列第一行中的单元格值不同的每个单元格都会突出显示。因为我需要在Kubernetes上部署Dash,还有一些与路径相关的原因,我将Dash应用程序作为一个具有多个Input/Output回调的类(我知道我也不喜欢它)。我正在尝试为每个回调动态生成的数据帧添加样式。

注意代码不完整,但函数的返回值是正确的,它创建了一个字典列表。当我添加代码中的for循环部分时,我的表格没有更新。但仅使用selected_row_style来突出显示选定行时,它可以更新。非常感谢任何帮助。此外,代码没有缩进问题。

英文:

I am new to dash and trying to style my dashtable so that every cell with a different value from the cell in the same column in the first row gets highlighted. Because I need to deploy dash in Kubernetes and other reasons that have to do with paths I have the dashapp as a class with a giant multiple Input/Output callback. ( I know I don't like it either) I am trying to style a dataframe that is dynamically generated for every callback.

                            html.Div(
                            className="eight columns div-for-charts bg-grey",
                            children=[
                                dcc.Graph(id="graph"),
                                html.Div(
                                    className="text-padding",
                                    children=[
                                        "You can filter the table columns by clicking on the column name.",
                                    ],
                                ),
                                dash_table.DataTable(
                                    id='datatable-interactivity',
                                    columns=[
                                        {"name": i, "id": i, "deletable": False, "selectable": True} for i in
                                        self.predictions.columns
                                    ],
                                    # make header font black
                                    style_header={'color': 'black', 'backgroundColor': 'white'},
                                    style_data={'color': 'black', 'backgroundColor': 'white'},
                                    data=self.predictions.to_dict('records'),
                                    editable=False,
                                    filter_action="native",
                                    sort_mode="multi",
                                    column_selectable="single",
                                    row_selectable="multi",
                                    row_deletable=True,
                                    selected_columns=[],
                                    selected_rows=[],
                                    page_action="native",
                                    page_current=0,
                                    page_size=20,
                                    style_table={'overflowX': 'scroll'},
                                ),

                            ],
                        ),
    def start_callback(self):
        @self.multiple_callbacks.callback(
            [dash.dependencies.Output("graph", "figure"),
             dash.dependencies.Output(component_id="datatable-interactivity", component_property='data'),
             dash.dependencies.Output("datatable-interactivity", "style_data_conditional")],
            [dash.dependencies.Input(component_id='algorithm_dd', component_property='value'),
             dash.dependencies.Input(component_id="graph", component_property="selectedData"),
             dash.dependencies.Input(component_id='value_slider', component_property='value'),
             dash.dependencies.Input(component_id='checklist', component_property='value'),
             dash.dependencies.Input(component_id="datatable-interactivity", component_property="active_cell"),
             ])
                if len(selectedData['points']) == 1:
                    key = selectedData['points'][:]
                    a = key[0]['hovertext']

                    df_f = self.get_nearest_neighbours(self.predictions, hovertexts[0], value_slider, alg_name)
                    selected_row_style =[{"if": {"filter_query": "{{apk_name}} ={}".format(a)}, "backgroundColor": "yellow", }]
                    cell_styles = []
                    for column in df_f.columns:
                        cell_styles.append({
                            'if': {
                                'column_id': column,
                                'filter_query': f'{{{column}}} != {df_f[column].iloc[0]}',
                            },
                            'backgroundColor': 'pink',
                            'color': 'white',
                        })
                    selected_row_style.extend(cell_styles)
                return plot_fig_selected, df_f.to_dict('records'), selected_row_style

Notice how the code is not complete, but the return values of the function are correct and it creates a list of dictionaries. Somehow my table does not update when I add the for loop part in the code. It does update with only the selected_row_style with the yellow highlighting for the selected row though. Any help is much appreciated. Also there is no indent problem on the code.

答案1

得分: 1

由于您的代码尚未完成,并且不是可复制的示例,请参考以下代码来修改您的代码:

import pandas as pd
import dash_table
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc

df = pd.DataFrame({'num': [1, 2, 1, 3, 1, 5, 1]})
df['matches?'] = df['num'].shift(1) != df['num']
df['matches?'] = df['matches?'].astype(str)

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.LUX])

app.layout = dash_table.DataTable(
    data=df.to_dict('records'),
    columns=[{'name': i, 'id': i} for i in df.columns[0:1]],
    style_data_conditional=[
        {'if': {'filter_query': '{matches?} eq "True"', 'column_id': 'num'},
         'color': 'black', 'backgroundColor': 'white'
        },
        {'if': {'filter_query': '{matches?} eq "False"', 'column_id': 'num'},
         'color': 'white', 'backgroundColor': 'green'
        }
    ]
)

if __name__ == '__main__':
    app.run_server(debug=False, port=1213)

如您所见,我们需要首先使用shift找到不同的单元格,然后将其用于dash_table的条件格式化。

英文:

Because of your code still not finish and it's not reproductive sample so please refer below code to revise yours.

import pandas as pd
import dash_table
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc

df = pd.DataFrame({'num': [1, 2, 1, 3, 1, 5, 1]})
df['matches?'] = df['num'].shift(0)==df['num'].loc[0]
df['matches?'] = df['matches?'].astype(str)

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.LUX])

#print(df)
app.layout = dash_table.DataTable(
    data=df.to_dict('records'),
    #sort_action='native',
    columns=[{'name': i, 'id': i} for i in df.columns[0:1]],
    style_data_conditional=[
        {'if': {'filter_query': '{matches?} eq "False"',
                'column_id': 'num'
            },
            'color': 'white','backgroundColor':'green'
        },
                {'if': {'filter_query': '{matches?} eq "True"',
                'column_id': 'num'
            },
            'color': 'black','backgroundColor':'white'
        },
        
    ] 
)

if __name__ == '__main__':
    app.run_server(debug=False, port=1213)

As you see we need to find the different cell first by using shift then use this to conditional_formating dash_table.

动态数据框和Dash回调中的条件样式化

huangapple
  • 本文由 发表于 2023年3月15日 17:41:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75742904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定