Dash python - 基于 pandas 列的图像回调

Dash python - images callbacks based on pandas columns

我从 excel 文件中得到了这个 df:

URL Category    Tag1    Tag2    formatted
0   https://www.youtube.com/embed/K8L6KVGG-7o   Tutorial    Python  Regex   html.Iframe(src='https://www.youtube.com/embed...
1   https://www.youtube.com/embed/VPUX7nRlYAU   Docu    Mushroom    Fake leather    html.Iframe(src='https://www.youtube.com/embed...
2   https://www.youtube.com/embed/c6nurN-Hii8   Tutorial    Mushroom    Fake leather    html.Iframe(src='https://www.youtube.com/embed...
3   https://www.youtube.com/embed/K-v2erXztnY   Tutorial    Blender Geometry    html.Iframe(src='https://www.youtube.com/embed...
4   https://www.youtube.com/embed/1jHUY3qoBu8   Tutorial    Blender Low poly modeling   html.Iframe(src='https://www.youtube.com/embed...

我想创建一个 dash 应用程序,该应用程序将 return 基于下拉菜单选项列表的视频,例如类别或标签 1。

我能够通过从嵌入视频列表的列表中创建一个 html.Iframe 循环来可视化应用程序中的所有视频,但无法使下拉菜单起作用。

我在回调中做错了什么?

目前,如果我 select 从下拉列表中选择一个值 return:

值错误: ('Lengths must match to compare', (5,), (1,))

没有选择,我得到一个空框。

urls_list = df['URL'].to_list()

app = dash.Dash(__name__) 

app.css.config.serve_locally = True
app.scripts.config.serve_locally = True

""" videos = []
for url in urls_list:
    videos.append(html.Iframe(src=url)) """ 
videos = []
for url in urls_list:
    videos.append('(src='+"'"+url+"'"+')')

df['formatted'] = videos



app.layout = html.Div([
    
    html.Div([
                html.Div(className="header", 
                         children=[
                          html.Div(['YT Cat!'], id='title'),
                          html.Div([dcc.Link('Most viewed', href='', id='link-menu'),
                          dcc.Link('Newly added', href='', id='link-menu2')],
                         className='header-links')
                      ]),
                
                ], className='header-container'),
                
                       
    html.Div([
        html.Div([html.Img(id='logo')])
    ]),
    dcc.Dropdown(
        id='dropdown_main',
        options=[{'label':x, 'value':x} for x in df['Category'].unique()] + [{'label':x, 'value':x} for x in df['Tag1'].unique()],
        multi=True
    ),

    html.Div(id='video_placeholder'),#children=videos)
    
    ])

@app.callback(
    dash.dependencies.Output('video_placeholder', 'children'),
    [dash.dependencies.Input('dropdown_main', 'value')]
)
def update_output(dropdown_value):
    return display_video(dropdown_value)

def display_video(dropdown_value):
    if dropdown_value == 'Tutorial':
       df[df['Category'] == 'Tutorial'].formatted
       
    elif dropdown_value == 'Docu':
       df[df['Category'] == 'Docu'].formatted

    return html.Iframe(df[df['Category'] == dropdown_value].formatted)

由于您的 dcc.Dropdown 中有 multi=True,因此 dropdown_value 参数是一个列表,而不是字符串。当您尝试评估

时会引发 ValueError
df[df['Category'] == dropdown_value]

在您的 display_video 函数中。如果 dropdown_value 是一个字符串,那会起作用,但如果它是一个列表,它就不起作用。

首先,我会将您的 display_video 函数更改为如下内容:

def display_video(dropdown_value):
    if not isinstance(dropdown_value, list):
        dropdown_value = [dropdown_value]

    if not dropdown_value:
        return None
    elif 'Tutorial' in dropdown_value:
        return html.Iframe(df[df['Category'] == 'Tutorial'].formatted)
    elif 'Docu' in dropdown_value:
        return df[df['Category'] == 'Docu'].formatted
    else:
        return [html.Iframe(df[df['Category'] == dropdown_value[i]].formatted)
                for i in df[df['Category'].unique()]]

在那之后,我仍然不完全清楚您希望该应用程序如何工作,因此我需要更多详细信息。

使用pandas.Series.isin检查系列中的元素是否包含在容器中。

filter_ = df['Category'].isin(dropdown_value)
filtered_df = df[filter_]

return filtered_df.formatted