Guys I’ve this code that basically prints out a graph, followed by two dropdown menu and once the values from the dropdown menus are confirmed, it prints out some data, this way:
That’s the code:
import dash
from dash import dcc, html
from dash.dependencies import Input, Output, State
import pandas as pd
import plotly.graph_objs as go
def create_dashboard(mean_values, pivot_tablevalori, curryear):
# Initialize the Dash app
app = dash.Dash(__name__)
# Define the layout of the app
app.layout = html.Div([
dcc.Graph(id="graph"),
html.Div([
html.P("Start Date:"),
dcc.Dropdown(id="start-date-dropdown",
options=[{'label': date, 'value': date} for date in mean_values['Date']],
value=mean_values['Date'].iloc[0]
),
html.P("End Date:"),
dcc.Dropdown(id="end-date-dropdown",
options=[{'label': date, 'value': date} for date in mean_values['Date']],
value=mean_values['Date'].iloc[-1]
),
html.Button('Confirm', id='confirm-button', n_clicks=0),
html.Div(id='output')
]),
html.Div([
html.Div(id='positive-ratios', style={'flex': '50%'}),
html.Div(id='negative-ratios', style={'flex': '50%'}),
], style={'display': 'flex'}),
])
@app.callback(
Output("graph", "figure"),
[Input("start-date-dropdown", "value"),
Input("end-date-dropdown", "value")]
)
def update_plot(start_date, end_date):
# Slice the data based on the selected interval
selected_data = mean_values
currentyear = curryear
# Create trace for 'Cento' column
trace_cento = go.Scatter(x=selected_data['Date'], y=selected_data['Cento'], mode='lines', name='Seasonality 15 Years')
trace_current = go.Scatter(x=currentyear.loc[:,'Date'], y=currentyear.loc[:, 'serie2024'], mode='lines', name='Current Year',yaxis='y2')
# Create layout
layout = go.Layout(
title=f"<b>Copper Seasonality</b><br>",
titlefont=dict(size=16, color='black', family='Arial'),
yaxis=dict(title='Performance - Seasonality 15 Years'),
yaxis2=dict(title='Performance - Current Year', overlaying='y', side='right'),
showlegend=True,
title_x=0.5
)
# Create figure with trace and layout
fig = go.Figure(data=[trace_cento, trace_current], layout=layout)
return fig
@app.callback(
[Output('positive-ratios', 'children'),
Output('negative-ratios', 'children')],
[Input('confirm-button', 'n_clicks')],
[State('start-date-dropdown', 'value'),
State('end-date-dropdown', 'value')]
)
def update_ratios(n_clicks, start_date, end_date):
if n_clicks > 0:
print("Update ratios function called")
print("Start date:", start_date)
print("End date:", end_date)
print("Pivot table:")
# Reset the index of the pivot_tablevalori
newstart = pd.to_datetime(start_date, format='%d %B')
newstart = newstart.strftime('%m-%d')
print(newstart)
newend = pd.to_datetime(end_date, format='%d %B')
newend = newend.strftime('%m-%d')
# Find the corresponding rows in pivot_tablevalori based on selected dates
start_row = pivot_tablevalori.loc[newstart]
end_row = pivot_tablevalori.loc[newend]
# Calculate the ratio between corresponding values in start_row and end_row
# Calculate the ratio between corresponding values in start_row and end_row
ratios = [(end_row_val / start_row_val) - 1 if not pd.isna(end_row_val) and not pd.isna(start_row_val) else float('nan') for end_row_val, start_row_val in zip(end_row, start_row)]
# Count positive and negative ratios
positive_ratios = [ratio for ratio in ratios if ratio >= 0]
negative_ratios = [ratio for ratio in ratios if ratio < 0]
# Calculate mean of positive and negative ratios
positive_mean = sum(positive_ratios) / len(positive_ratios) if positive_ratios else 0
negative_mean = sum(negative_ratios) / len(negative_ratios) if negative_ratios else 0
# Calculate the probability of positive and negative ratios
prob_positive_ratio = len(positive_ratios) / len(ratios)
prob_negative_ratio = len(negative_ratios) / len(ratios)
# Create tables for positive and negative ratios
positive_table = html.Table([
html.Tr([html.Th('Positive Data')]),
html.Tr([html.Td('Start - Date'), html.Td(start_date)]),
html.Tr([html.Td('End - Date'), html.Td(end_date)]),
html.Tr([html.Td('\n')]),
html.Tr([html.Td(f'Probability of a Positive Return:'), html.Td(f'{prob_positive_ratio:.2%}', style={'text-align': 'right'})]),
html.Tr([html.Td(f'Average Return:'), html.Td(f'{positive_mean:.2%}', style={'text-align': 'right'})]),
], style={'margin-left': 'auto', 'margin-right': 'auto', 'height': '150px'})
negative_table = html.Table([
html.Tr([html.Th('Negative Ratios')]),
html.Tr([html.Td('Start - Date'), html.Td(start_date)]),
html.Tr([html.Td('End - Date'), html.Td(end_date)]),
html.Tr([html.Td('\n')]),
html.Tr([html.Td(f'Probability of a Negative Return:'), html.Td(f'{prob_negative_ratio:.2%}', style={'text-align': 'right'})]),
html.Tr([html.Td(f'Average Return:'), html.Td(f'{negative_mean:.2%}', style={'text-align': 'right'})]),
], style={'margin-left': 'auto', 'margin-right': 'auto', 'height': '150px'})
return positive_table, negative_table
else:
return dash.no_update, dash.no_update
# Run the app
app.run_server()
# Call the function with your dataframes
create_dashboard(mean_values, pivot_tablevalori.loc[:, pivot_tablevalori.columns != 2024], annocorrente)
PROBLEM: However, the problem,as you can see also from my screen is that toggle bar. I’d like to get rid of it, expading the output cell. I tried incresing the width in the first Div, but plotly recognise the app as a two step, meaning that it increases the width after the dropdown menu but when I select the values, the toggle bar is back.
Moreover, I tried working in full screen but, weirdly, only half of the screen is used as output, like this, were the scrolling bar is activated: