Я только что задал аналогичный вопрос об обновлении карт в Plotly Dash, но по какой-то причине эта немного другая ситуация ставит меня в тупик. У меня есть несколько карточек на панели инструментов, которые я хочу обновить с помощью ползунка даты. Использование раскрывающегося меню с переменной строкового типа работало нормально, но теперь, когда у нас есть значение даты в ползунке, это доставляет мне некоторые проблемы.
Вот часть моего кода:
#Import packages
import pandas as pd
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import time
who_data = pd.read_csv("https://covid19.who.int/WHO-COVID-19-global-data.csv")
pops = pd.read_csv("https://gist.githubusercontent.com/curran/0ac4077c7fc6390f5dd33bf5c06cb5ff/raw/605c54080c7a93a417a3cea93fd52e7550e76500/UN_Population_2019.csv")
who_data.rename(columns={'New_cases': 'New Cases', 'Cumulative_cases': 'Cumulative Cases', 'New_deaths': 'New Deaths','Cumulative_deaths': 'Cumulative Deaths'}, inplace=True)
daterange = pd.date_range(start=who_data['Date_reported'].min(),
end=who_data['Date_reported'].max(),
freq='D')
def unixTimeMillis(dt):
''' Convert datetime to unix timestamp '''
return int(time.mktime(dt.timetuple()))
def unixToDatetime(unix):
''' Convert unix timestamp to datetime. '''
return pd.to_datetime(unix,unit='s')
def getMarks(start, end, Nth=50):
''' Returns the marks for labeling.
Every Nth value will be used.
'''
result = {}
for i, date in enumerate(daterange):
if(i%Nth == 1):
# Append value to dict
result[unixTimeMillis(date)] = str(date.strftime('%Y-%m-%d'))
return result
card1_body = dbc.CardBody([html.H4("Card title", className="card-title",id="card_num1"),
html.P("Cumulative Cases for Date", className="card-text",id="card_text1")
],
style={'display': 'inline-block',
'text-align': 'center',
'color':'white',
'background-color': 'rgba(37, 150, 190)'})
card2_body = dbc.CardBody([html.H4("Card title", className="card-title",id="card_num2"),
html.P("Cumulative Deaths for Date", className="card-text",id="card_text2")
],
style={'display': 'inline-block',
'text-align': 'center',
'color':'white',
'background-color': 'rgba(37, 150, 190)'})
card1 = dbc.Card(card1_body,outline=True)
card2 = dbc.Card(card2_body,outline=True)
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div([
dcc.Tabs([
dcc.Tab(label='Spread',
children=[
html.Div([
dcc.RangeSlider(id='slider',
min = unixTimeMillis(daterange.min()),
max = unixTimeMillis(daterange.max()),
value = [unixTimeMillis(daterange.min())],
marks=getMarks(daterange.min(),daterange.max())
),
dbc.Row(id="card_row",children=[dbc.Col(card1),
dbc.Col(card2)
])
])
]),
dcc.Tab(label="Top 10",
children=[
html.P('Some stuff will go here eventually.')
])
])
])
@app.callback(
Output('card_row','children'),
Input('slider','value')
)
def update_cards(date_select):
date_df = who_data[(who_data.Date_reported<=date_select)]
tot_cases = f"{date_df['New Cases'].sum():,.0f}"
tot_deaths = f"{date_df['New Deaths'].sum():,.0f}"
card1 = dbc.Card([
dbc.CardBody([
html.H4(tot_cases, className="card-title"),
html.P(f"Cumulative Cases on {date_select}")
])
],
style={'display': 'inline-block',
'width': '50%',
'text-align': 'center',
'background-color': 'rgba(37, 150, 190)',
'color':'white',
'fontWeight': 'bold',
'fontSize':20},
outline=True)
card2 = dbc.Card([
dbc.CardBody([
html.H4(tot_deaths, className="card-title"),
html.P(f"Cumulative Deaths on {date_select}")
])
],
style={'display': 'inline-block',
'width': '50%',
'text-align': 'center',
'background-color': 'rgba(37, 150, 190)',
'color':'white',
'fontWeight': 'bold',
'fontSize':20},
outline=True)
return (card1, card2)
app.run_server(host='0.0.0.0',port='8050')
Когда я запускаю это, две карты не обновляются, и я получаю сообщение об ошибке: ValueError: для сравнения длины должны совпадать. Это относится к строке, в которой я пытаюсь создать date_df в функции update_cards. Проведя небольшое исследование StackOverflow, я нашел несколько примеров, в которых предполагалось, что date_select представляет собой серию из 1 значения и что мне нужно прикрепить .values [0] в конце, чтобы выбрать одно значение, но это тоже не сработало. . Не знаете, как действовать, любая помощь будет принята с благодарностью!
Спасибо!