我是 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”?