Добрый день,
В настоящее время я создаю Dash-приложение на Python. Цель этого приложения - визуализировать прогнозы и сравнивать их с данными прошлых лет.
Проблема, с которой я сталкиваюсь, заключается в следующем: вместо этого я хотел бы иметь свою ось х в неделю года (начало воскресенья)даты.
До сих пор я пытался создать недельный столбец и использовать его для своих графиков. Проблема в том, что WK01 не будет после WK52, он пойдет в начале моего сюжета, чего я не хочу. В идеале, я хотел бы иметь 10 + недельный горизонт и -10 против сегодняшней даты на моем графике (с WK45 для 2019 и 2018 годов, например).
Мой формат df и фактические значения следующие:
category date store brand volume week year version
BAG 2019-09-22 LONDON LV ... 2428.0 38 2019 FCT
BAG 2019-09-29 LONDON LV ... 0.0 39 2019 FCT
BAG 2019-10-06 LONDON LV ... 0.0 40 2019 DFT
BAG 2019-10-13 LONDON LV ... 0.0 41 2019 FCT
BAG 2019-10-20 LONDON LV ... 0.0 42 2019 DFT
Вот мой код:
# Import required libraries
import pandas as pd
from flask import Flask
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import datetime
from datetime import datetime as dt
app = dash.Dash(__name__)
server = app.server
#Data preparation
df = pd.read_csv('Export.csv')
actuals = pd.read_csv('actuals.csv')
df['date'] = pd.to_datetime(df['date'])
df['year'] = pd.DatetimeIndex(df['date']).year
actuals['date'] = pd.to_datetime(actuals['date'])
actuals['year'] = actuals['date'].dt.year
df['week'] = pd.DatetimeIndex(df['date']).week
actuals['week'] = actuals['date'].dt.week
df = pd.concat([df, actuals])
upperdatelimit = (pd.datetime.today() + pd.to_timedelta(pd.np.ceil(10), unit="W")).strftime('%Y-%m-%d')
lowerdatelimit = (pd.datetime.today() + pd.to_timedelta(pd.np.ceil(-10), unit="W")).strftime('%Y-%m-%d')
mask = (df['date'] <= upperdatelimit) & (df['date'] >= lowerdatelimit)
df = df.loc[mask]
# Create controls
brand_options = [{'label': str(brand), 'value': str(brand)}
for brand in df['brand'].unique()]
year_options = [{'label': year,
'value': year}
for year in actuals['year'].unique()]
store_options = [{'label': str(store), 'value': str(store)}
for store in df['store'].unique()]
category_options = [{'label': str(category),
'value': str(category)}
for category in df['category'].unique()]
# Load data
app.layout = html.Div(
[
dcc.Store(id='aggregate_data'),
html.Div(
[
html.Div(
[
html.H2(
'Phantasm',
),
html.H4(
'Forecast Overview',
)
],
className='eight columns'
),
html.Img(
src="x.png",
className='two columns',
),
],
id="header",
className='row',
),
html.Div(
[
html.Div(
[
html.P(
'Actuals Comparison Year',
className="control_label"
),
dcc.Dropdown(
id='dropdown',
options=year_options,
multi=False,
value=pd.datetime.today().year - 1,
className="dcc_control"
),
html.P(
'Filter by category:',
className="control_label"
),
dcc.Dropdown(
id='category_names',
options=category_options,
multi=True,
value=list(df['category'].unique()),
className="dcc_control"
),
html.P(
'Filter by brand:',
className="control_label"
),
dcc.Dropdown(
id='brand_names',
options=brand_options,
multi=True,
value=list(df['brand'].unique()),
className="dcc_control"
),
html.P(
'Filter by store:',
className="control_label"
),
dcc.Dropdown(
id='store_names',
options=store_options,
multi=True,
value=list(df['store'].unique()),
className="dcc_control"
),
],
className="pretty_container four columns"
),
html.Div(
[
html.Div(
[
html.Div(
[
html.Div(
[
html.P("Hermes"),
html.H6(
id="brand_text",
className="info_text"
)
],
id="Hermes",
className="pretty_container"
),
html.Div(
[
html.P("LV"),
html.H6(
id="branda_text",
className="info_text"
)
],
id="LV",
className="pretty_container"
),
html.Div(
[
html.P("Valentino"),
html.H6(
id="brandb_text",
className="info_text"
)
],
id="valentino",
className="pretty_container"
),
],
id="tripleContainer",
)
],
id="infoContainer",
className="row"
),
html.Div(
[
dcc.Graph(
id='count_graph',
)
],
id="countGraphContainer",
className="pretty_container"
)
],
id="rightCol",
className="eight columns"
)
],
className="row"
),
html.Div(
[
html.Div(
[
dcc.Graph(id='main_graph')
],
className='pretty_container eight columns',
),
html.Div(
[
dcc.Graph(id='individual_graph')
],
className='pretty_container four columns',
),
],
className='row'
),
html.Div(
[
html.Div(
[
dcc.Graph(id='pie_graph')
],
className='pretty_container seven columns',
),
html.Div(
[
dcc.Graph(id='aggregate_graph')
],
className='pretty_container five columns',
),
],
className='row'
),
],
id="mainContainer",
style={
"display": "flex",
"flex-direction": "column"
}
)
# Create callbacks
@app.callback(Output('brand_text', 'children'),
[Input('store_names', 'value'),
Input('category_names', 'value')])
def update_forecast_text(store_names,category_names):
dff = df[df['store'].isin(store_names) & df['category'].isin(category_names)
& df['brand'].isin(['Hermes']) & df['version'].isin(['DFT'])]
return ""+"{:,}".format(int(dff['volume'].sum()))
@app.callback(Output('branda_text', 'children'),
[Input('store_names', 'value'),
Input('category_names', 'value')])
def update_forecast_text(store_names,category_names):
dff = df[df['store'].isin(store_names) & df['category'].isin(category_names)
& df['brand'].isin(['LV']) & df['version'].isin(['DFT'])]
return ""+"{:,}".format(int(dff['volume'].sum()))
@app.callback(Output('brandb_text', 'children'),
[Input('store_names', 'value'),
Input('category_names', 'value')])
def update_forecast_text(store_names,category_names):
dff = df[df['store'].isin(store_names) & df['category'].isin(category_names)
& df['brand'].isin(['Valentino']) & df['version'].isin(['DFT'])]
return ""+"{:,}".format(int(dff['volume'].sum()))
@app.callback(Output('main_graph', 'figure'),
[Input('dropdown', 'value'),
Input('store_names', 'value'),
Input('category_names', 'value'),
Input('brand_names','value')])
def update_graph(dropdown_value,store_names,category_names,brand_names):
actualsdf = actuals[actuals['year'] == dropdown_value]
dffdraft = df[df['store'].isin(store_names) & df['category'].isin(category_names)
& df['brand'].isin(brand_names) & df['version'].isin(['DFT','ACTUALS'])]
dfffct = df[df['store'].isin(store_names) & df['category'].isin(category_names)
& df['brand'].isin(brand_names) & df['version'].isin(['FCT','ACTUALS'])]
dffactuals = actualsdf[actualsdf['store'].isin(store_names) & actualsdf['category'].isin(category_names)
& actualsdf['brand'].isin(brand_names) & actualsdf['version'].isin(['ACTUALS'])]
dffdraft = dffdraft.groupby('date')['volume'].sum().reset_index()
dfffct = dfffct.groupby('date')['volume'].sum().reset_index()
dffactuals = dffactuals.groupby('date')['volume'].sum().reset_index()
trace1 = go.Scatter(y=dffdraft['volume'],x=dffdraft['date'],mode='lines',name='Draft')
trace2 = go.Scatter(y=dfffct['volume'], x=dfffct['date'], mode='lines', name='Forecast')
trace3 = go.Scatter(y=dffactuals['volume'], x=dffactuals['date'], mode='lines', name='Actuals')
data = [trace1,trace2,trace3]
return {"data": data}
# Main
if __name__ == '__main__':
app.server.run(debug=True, threaded=True)
Большое спасибо!
Цель
Токовый выход