dash plotly - 来自输入和数据框的卡片动态回调

问题描述 投票:0回答:0

我是 Dash 的新手,目前正在开发仪表板组合。我有一个关于动态回调的问题:

from dash import Dash, dcc, html, Output, Input
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.figure_factory as ff
import pandas as pd

# df = pd.read_csv('anime_data_upto_mar_2023_production.csv')
df = pd.read_csv('https://github.com/mangarahutagalung/anime-dash-plotly/blob/main/anime_data_upto_mar_2023_production.csv?raw=true')
print(df.iloc[:5, 5:8])

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

# The Bootstrap grid has twelve columns, and six responsive tiers. 
# The width of your columns can be specified in terms of how many of the twelve grid columns it should span, or you can allow the columns to expand or shrink to fit either their content or the available space in the row.
app.layout = dbc.Container([
    dbc.Row([
        dbc.Col([
            dcc.Markdown('# Anime Stats Dashboard', style={'textAlign': 'left', 'color': 'black'})
        ], width=12)
    ]),
    
    dbc.Row([
        dbc.Col([
            dcc.Markdown('### Your one-stop dashboard for anime stats!', style={'textAlign': 'left', 'color': 'black'})
        ], width=12)
    ]),

    dbc.Row([
            html.Div(html.Hr(style={'borderWidth': "0.5vh", "color": "#146C94"}))
        ]),
    
    dbc.Row([
        dbc.Col([
            dcc.Markdown('#### Select aired year range'),
            year_slider := dcc.RangeSlider(min=df.year.min(), max=df.year.max(), value=[1980, 2022], step=1,
                                            marks={'1961': '1961', '1970': '1970', '1980': '1980',
                                                   '1990': '1990', '2000': '2000','2010': '2010', 
                                                   '2020': '2020', '2024': '2024'},
                                            tooltip={"placement": "bottom", "always_visible": True}
                                            )
        ], width=12)
    ]),
    
    dbc.Row([
        dbc.Col([
            dcc.Markdown('##### Top 5 Anime by Score based on selected year range', style={'textAlign': 'left', 'color': 'black'})
        ], width=12)
    ], style={'marginTop': '20px'}),    

    dbc.Row([
        dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(id = 'rank1_img', src=df.sort_values(by='score', ascending=False).iloc[0]['images_webp_url'], 
                            top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                id = 'rank1_title',
                                df.sort_values(by='score', ascending=False).iloc[0]['title'],
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            id = 'rank1_url',
                            href=df.sort_values(by='score', ascending=False).iloc[0]['url'],
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            id = 'rank1_synopsis',
                            df.sort_values(by='score', ascending=False).iloc[0]['synopsis'][:100]+'...',
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            id = 'rank1_trailer',
                            href= df.sort_values(by='score', ascending=False).iloc[0]['trailer_url'] if \
                                isinstance(df.sort_values(by='score', ascending=False).iloc[3]['trailer_url'], str) \
                                    else 'https://www.youtube.com/watch?v=',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
        dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(src=df.sort_values(by='score', ascending=False).iloc[1]['images_webp_url'], top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                df.sort_values(by='score', ascending=False).iloc[1]['title'],
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            href=df.sort_values(by='score', ascending=False).iloc[1]['url'],
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            df.sort_values(by='score', ascending=False).iloc[1]['synopsis'][:100]+'...',
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            href= df.sort_values(by='score', ascending=False).iloc[1]['trailer_url'] if \
                                isinstance(df.sort_values(by='score', ascending=False).iloc[3]['trailer_url'], str) \
                                    else 'https://www.youtube.com/watch?v=',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
        dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(src=df.sort_values(by='score', ascending=False).iloc[2]['images_webp_url'], top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                df.sort_values(by='score', ascending=False).iloc[2]['title'],
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            href=df.sort_values(by='score', ascending=False).iloc[2]['url'],
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            df.sort_values(by='score', ascending=False).iloc[2]['synopsis'][:100]+'...',
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            href= df.sort_values(by='score', ascending=False).iloc[2]['trailer_url'] if \
                                isinstance(df.sort_values(by='score', ascending=False).iloc[3]['trailer_url'], str) \
                                    else 'https://www.youtube.com/watch?v=',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
        dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(src=df.sort_values(by='score', ascending=False).iloc[3]['images_webp_url'], top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                df.sort_values(by='score', ascending=False).iloc[3]['title'],
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            href=df.sort_values(by='score', ascending=False).iloc[3]['url'],
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            df.sort_values(by='score', ascending=False).iloc[3]['synopsis'][:100]+'...',
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            href= df.sort_values(by='score', ascending=False).iloc[3]['trailer_url'] if \
                                isinstance(df.sort_values(by='score', ascending=False).iloc[3]['trailer_url'], str) \
                                    else 'https://www.youtube.com/',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
        dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(src=df.sort_values(by='score', ascending=False).iloc[4]['images_webp_url'], top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                children=df.sort_values(by='score', ascending=False).iloc[4]['title'],
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            href=df.sort_values(by='score', ascending=False).iloc[4]['url'],
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            children= df.sort_values(by='score', ascending=False).iloc[4]['synopsis'][:100]+'...',
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            href= df.sort_values(by='score', ascending=False).iloc[4]['trailer_url'] if \
                                isinstance(df.sort_values(by='score', ascending=False).iloc[3]['trailer_url'], str) \
                                    else 'https://www.youtube.com/watch?v=',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                )
    ]),
    
    dbc.Row([
        dbc.Col([
            score_hist := dcc.Graph(id='fig',
                                    figure={})
        ], width=5)
    ]),

    dbc.Row([
        dbc.Col([
            year_by_score := dcc.Graph(id='fig2',
                                       figure={})
        ], width=12)
    ])
])


@app.callback(
    [Output(component_id=score_hist, component_property='figure'),
     Output(component_id=year_by_score, component_property='figure'),
     Output(component_id='rank1_img', component_property='src'),
     Output(component_id='rank1_title', component_property='children'),
     Output(component_id='rank1_synopsis', component_property='children'),
     Output(component_id='rank1_url', component_property='href')],
    Input(component_id=year_slider, component_property='value')
)

def update_graph(year_value):
    print(year_value)
    
    dff = df[(df.year >= year_value[0]) & (df.year <= year_value[1])]

    fig = px.histogram(dff, 
                       x="year", 
                       nbins=20,
                       color_discrete_sequence=['#146C94']
                       )
    fig.update_layout(title_text='Anime count by year', 
                      title_x=0.5,
                      xaxis_title='Year',
                      yaxis_title='Count',
                      legend_title='Year',
                      font_family='Sans-Serif')
                        
    
    fig2 = ff.create_distplot([dff['score']], 
                             group_labels=['score'], 
                             bin_size=0.5, 
                             colors=['#146C94']
                             )
    fig2.update_layout(title_text='Anime score distribution', 
                       title_x=0.5,
                       xaxis_title='Score',
                       yaxis_title='Density',
                       showlegend=False
                       )
    return fig, fig2

def update_card(year_value):
    print(year_value)
    
    dff = df[(df.year >= year_value[0]) & (df.year <= year_value[1])]
    
    rank1_img = dff.sort_values(by='score', ascending=False).iloc[0]['images_webp_url']
    rank1_title = dff.sort_values(by='score', ascending=False).iloc[0]['title']
    rank1_synopsis = dff.sort_values(by='score', ascending=False).iloc[0]['synopsis']
    rank1_url = dff.sort_values(by='score', ascending=False).iloc[0]['url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[0]['url'], str) \
            else 'https://myanimelist.net/'
    rank1_trailer = dff.sort_values(by='score', ascending=False).iloc[0]['trailer_url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[0]['trailer_url'], str) \
            else 'https://www.youtube.com/watch?v='

    return rank1_img, rank1_title, rank1_synopsis, rank1_url, rank1_trailer


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

当我尝试运行 Python 文件时代码中断,并且由于某种原因它没有返回任何错误消息。当我运行它时,它会打开控制台并立即关闭。有谁知道我如何返回“rank1_title”、“rank1_url”、“rank1_synopsis”和“rank1_trailer”?

python plotly-dash
© www.soinside.com 2019 - 2024. All rights reserved.