Questions about cards dynamic callbacks

Hi! I’m new to Dash and I’m currently working on a dashboard portfolio. I have a question regarding dynamic callbacks (below is a snippet of my code which I have questions about, the other codes are about figures which I, fortunately, was able to run):

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_url',
                            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")
                    ]
                ),
            ],


@app.callback(
    [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_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)

The code breaks when I try to run the Python file, and it doesn’t return any error message for some reason. When I run it, it opens up the console and closes it instantly. Anyone knows how I can return the ‘rank1_title’, ‘rank1_url’, ‘rank1_synopsis’, and ‘rank1_trailer’?

Hi @mangarapaul and welcome to the Dash community :slight_smile:

Nothing jumps out as incorrect in the code snippet you posted. It would be helpful if you can include a complete minimal example with some sample data that we can run and see the same error.

To find out more about how to do that, see this post: How to Get your Questions Answered on the Plotly Forum

This is my full code:

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(
                                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(
                            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)

I’ve only played around with the first card, just to see if it works so that is why the other cards are left static

1 Like

Hey @mangarapaul Cool app :sunglasses:


Just a couple syntax errors. Which IDE are you using? Pycharm made 2 of the errors easy to find. If you hover over this line it gives the message;

Positional argument after keyword argument

image


You can fix it by either doing this:

html.H4(
   id='rank1_title',
   children=df.sort_values(by='score', ascending=False).iloc[0]['title'],

or

html.H4(
   df.sort_values(by='score', ascending=False).iloc[0]['title'],
   id='rank1_title',  

Same error is in the html.P component right below.

If you fix those two errors and run it, you will see an error with a callback. The update_graph callback has 6 Outputs, but only has 2 figures returned.

Here is the full code with those 3 errors corrected

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',
                                    children=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',
                                children=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(
                                    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(
                                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)


4 Likes

Thank you, it works now! I also realized that the top 5 anime given the year input will not work with my current script, so I had to remove the arguments and pass it an empty dict or list instead. I also realized that you can only have 1 function after your callbacks, although I’m not sure if this is the case or if you can have multiple functions but I probably just didn’t know how.

Oh and I’m using vs code.

Anyway, for everyone else that’s interested in looking the full working code, here you go:

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={}, 
                            top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                id = 'rank1_title',
                                children={},
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            id = 'rank1_url',
                            href='',
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            id = 'rank1_synopsis',
                            children={},
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            id = 'rank1_trailer',
                            href='',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(id = 'rank2_img', 
                            src={}, 
                            top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                id = 'rank2_title',
                                children={},
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            id = 'rank2_url',
                            href='',
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            id = 'rank2_synopsis',
                            children={},
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            id = 'rank2_trailer',
                            href= '',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(id = 'rank3_img', 
                            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(
                                id = 'rank3_title',
                                children={},
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            id = 'rank3_url',
                            href='',
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            id = 'rank3_synopsis',
                            children={},
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            id = 'rank3_trailer',
                            href= '',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(id = 'rank4_img', 
                            src={}, 
                            top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                id = 'rank4_title',
                                children={},
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            id = 'rank4_url',
                            href='',
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            id = 'rank4_synopsis',
                            children={},
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            id = 'rank4_trailer',
                            href='',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
dbc.Col([
            dbc.Card(
            [
                dbc.CardImg(id = 'rank5_img', 
                            src={}, 
                            top=True, style={'height': '300px', 'width': '200px'}),
                dbc.CardBody(
                    [
                        dcc.Link(
                            html.H4(
                                id = 'rank5_title',
                                children={},
                                className="card-title",
                                style={'fontSize': '18px'}
                            ),
                            id = 'rank5_url',
                            href='',
                            target="_blank",
                            style={'color': 'black'}
                        ),
                        html.P(
                            id = 'rank5_synopsis',
                            children={},
                            className="card-text",
                            style={'fontSize': '13px'}
                        ),
                        dcc.Link(
                            dbc.Button("YouTube Trailer",
                                       color="secondary",
                                       style={'fontSize': '16px'}),
                            id = 'rank5_trailer',
                            href= '',
                            target="_blank")
                    ]
                ),
            ],
            style={"width": "13rem"}
            )
            ]
                ),
    ]),
    
    dbc.Row([
        dbc.Col([
            score_hist := dcc.Graph(id='fig',
                                    figure={})
        ], width=12)
    ]),

    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'),
     Output(component_id='rank1_trailer', component_property='href'),
     Output(component_id='rank2_img', component_property='src'),
     Output(component_id='rank2_title', component_property='children'),
     Output(component_id='rank2_synopsis', component_property='children'),
     Output(component_id='rank2_url', component_property='href'),
     Output(component_id='rank2_trailer', component_property='href'),
     Output(component_id='rank3_img', component_property='src'),
     Output(component_id='rank3_title', component_property='children'),
     Output(component_id='rank3_synopsis', component_property='children'),
     Output(component_id='rank3_url', component_property='href'),
     Output(component_id='rank3_trailer', component_property='href'),
     Output(component_id='rank4_img', component_property='src'),
     Output(component_id='rank4_title', component_property='children'),
     Output(component_id='rank4_synopsis', component_property='children'),
     Output(component_id='rank4_url', component_property='href'),
     Output(component_id='rank4_trailer', component_property='href'),
     Output(component_id='rank5_img', component_property='src'),
     Output(component_id='rank5_title', component_property='children'),
     Output(component_id='rank5_synopsis', component_property='children'),
     Output(component_id='rank5_url', component_property='href'),
     Output(component_id='rank5_trailer', component_property='href')
     ],
    Input(component_id=year_slider, component_property='value')
)

def update_front(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'][:100] + '...'
    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='
    
    rank2_img = dff.sort_values(by='score', ascending=False).iloc[1]['images_webp_url']
    rank2_title = dff.sort_values(by='score', ascending=False).iloc[1]['title']
    rank2_synopsis = dff.sort_values(by='score', ascending=False).iloc[1]['synopsis'][:100] + '...'
    rank2_url = dff.sort_values(by='score', ascending=False).iloc[1]['url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[1]['url'], str) \
            else 'https://myanimelist.net/'
    rank2_trailer = dff.sort_values(by='score', ascending=False).iloc[1]['trailer_url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[1]['trailer_url'], str) \
            else 'https://www.youtube.com/watch?v='
            
    rank3_img = dff.sort_values(by='score', ascending=False).iloc[2]['images_webp_url']
    rank3_title = dff.sort_values(by='score', ascending=False).iloc[2]['title']
    rank3_synopsis = dff.sort_values(by='score', ascending=False).iloc[2]['synopsis'][:100] + '...'
    rank3_url = dff.sort_values(by='score', ascending=False).iloc[2]['url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[2]['url'], str) \
            else 'https://myanimelist.net/'
    rank3_trailer = dff.sort_values(by='score', ascending=False).iloc[2]['trailer_url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[2]['trailer_url'], str) \
            else 'https://www.youtube.com/watch?v='
        
    rank4_img = dff.sort_values(by='score', ascending=False).iloc[3]['images_webp_url']
    rank4_title = dff.sort_values(by='score', ascending=False).iloc[3]['title']
    rank4_synopsis = dff.sort_values(by='score', ascending=False).iloc[3]['synopsis'][:100] + '...'
    rank4_url = dff.sort_values(by='score', ascending=False).iloc[3]['url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[3]['url'], str) \
            else 'https://myanimelist.net/'
    rank4_trailer = dff.sort_values(by='score', ascending=False).iloc[3]['trailer_url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[3]['trailer_url'], str) \
            else 'https://www.youtube.com/watch?v='
            
    rank5_img = dff.sort_values(by='score', ascending=False).iloc[4]['images_webp_url']
    rank5_title = dff.sort_values(by='score', ascending=False).iloc[4]['title']
    rank5_synopsis = dff.sort_values(by='score', ascending=False).iloc[4]['synopsis'][:100] + '...'
    rank5_url = dff.sort_values(by='score', ascending=False).iloc[4]['url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[4]['url'], str) \
            else 'https://myanimelist.net/'
    rank5_trailer = dff.sort_values(by='score', ascending=False).iloc[4]['trailer_url'] if \
        isinstance(dff.sort_values(by='score', ascending=False).iloc[4]['trailer_url'], str) \
            else 'https://www.youtube.com/watch?v='

    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, rank1_img, rank1_title, rank1_synopsis, rank1_url, rank1_trailer, \
              rank2_img, rank2_title, rank2_synopsis, rank2_url, rank2_trailer, \
              rank3_img, rank3_title, rank3_synopsis, rank3_url, rank3_trailer, \
              rank4_img, rank4_title, rank4_synopsis, rank4_url, rank4_trailer, \
              rank5_img, rank5_title, rank5_synopsis, rank5_url, rank5_trailer

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