Lets say I have some code as follows below:
import pandas as pd
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import helper
from datetime import date
app = dash.Dash(__name__)
# import data
app.layout = html.Div(children=[
dcc.Dropdown(
id='slct_dataset',
options= ['dataset1', 'dataset2'],
placeholder="Select a dataset",
multi=False,
style={'width': '40%'}
),
dcc.DatePickerRange(
id='slct_date',
#todo make: below below depend upon dataset selection
min_date_allowed=date(1980, 1, 1),
max_date_allowed=date(2021, 1, 1),
initial_visible_month=date(2017, 8, 5),
end_date=date(2017, 8, 25)
),
html.Div(id='output_container', children=[], style={
'textAlign': 'center'
}),
html.Br(),
dcc.Graph(id='my_graph', figure={})
])
#callback to produce graph
#app.callback(
[
Output(component_id='output_container', component_property='children'),
Output(component_id='my_series_graph', component_property='figure')
],
[
Input(component_id='slct_dataset', component_property='value'),
Input(component_id='slct_date', component_property='start_date'),
Input(component_id='slct_date', component_property='end_date')
]
)
def update_graph(dataset_slctd, start_date_slctd, end_date_slctd):
container = 'Dataset: {}'.format(dataset_slctd) +\
'. Start date: {}'.format(start_date_slctd) + \
'. End date: {}'.format(end_date_slctd)
dff = helper.get_dataset(dataset_slctd, start_date_slctd, end_date_slctd)
dff['Datetime'] = dff.index
fig = px.line(dff, x='Datetime', y='Value', title=dataset_slctd)
return container, fig
if __name__ == '__main__':
app.run_server(debug=False)
Right now I have min and max date allowed hard coded as this
min_date_allowed=date(1980, 1, 1) in date picker range. How can I define a date range dynamically based on the selection of a dataset in the first dropdown? Eg. lets say I have 01-01-2000/01-01-2001 as my min/max dataset for dataset1, and I have 02-02-2000/02-02-2001 as my min/max daterange for dataset2. How can I make my datepickerrange dynamically update based on whether I select dataset1 or dataset2 in my slct_dataset dropdown? As I understand this might depend on using a callback, but I can't really find what the standard way to do this is. Let me know if any more information can make the question more clear- I basically took the code I am actually writing and simplified it as much as possible so hopefully its clear what Im trying to do here. thanks for the help.
You can take the dropdown as an input to a callback and output to the date ranges of the datepicker based on the selected value. The signature should look like this:
#app.callback(
[
Output(component_id='slct_date', component_property='min_date_allowed'),
Output(component_id='slct_date', component_property='max_date_allowed'),
],
[
Input(component_id='slct_dataset', component_property='value'),
]
)
Related
I am building a dash app. I want to viz a graph for crypto data (being extracted from APIs). The dash dropdowns contain different crypto ticker symbols & on that basis, I want to showcase different graphs. For e.g, if a user selects ETH in the dropdown, the API will extract the eth market price data & feeds it to the dash app so the user can see the graph, but I am struggling with using multiple datasets with the dropdowns.
So far, I think a dropdown is used to change the property of 1 dataset via changing rows, limits, etc. but unable to choose between multiple datasets.
I am looking for a method to show market price graphs for different cryptocurrencies through the dash app.
########################### Importing Libraries #############################################
import numpy as np
import pandas as pd
from dash import dcc,html,Dash
import plotly.express as px
import warnings
warnings.filterwarnings("ignore")
from api_to_df import open_df,high_df,low_df,close_df,volume_df,mkt_cap_df
###########################################################################################
# Defining app name
app = Dash(__name__)
colors = {
'background': '#231F20',
'text': '#ADD8E6'
}
############### Defining elements for dropdowns ####################################################
ticker_list = ['ETH', 'XRP','BTC','LTC','LRC','DOT','MANA','EGLD','SHIB','SOL','TFUEL','ICP','SAND','MATIC']
type_list = ['Open', 'High','Low','Close','Volume','Mkt cap']
currency_list = ['USD']
############################################################################################################
markdown_text = '''
Koin is a webapp focussed at providing crypto coin data to crypto newbies in a simple yet elegant fashion.
'''
def generate_table(dataframe, max_rows=15):
'''
generate_table function is used to parse pandas dataframes into html tables.
'''
return html.Table([
html.Thead(
html.Tr([html.Th(col) for col in dataframe.columns])
),
html.Tbody([
html.Tr([
html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
]) for i in range(min(len(dataframe), max_rows))
])
])
#fig = px.bar(open_df, x="date", y="open",barmode = "group")
fig = px.line(open_df, x="date", y="open",markers = 1)
# Updating the layout of the figure
fig.update_layout(
plot_bgcolor=colors['background'],
paper_bgcolor=colors['background'],
font_color=colors['text']
)
#fig.update_traces(marker=dict(size=12,
# line=dict(width=2,
# color='Red')),
# selector=dict(mode='markers'))
# Div is used to create divisions in an html block
# children is a subbranch of an Division tree
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
# H1 is header 1 i.e Heading of the webapp
html.H1(
children='KOIN',
style={
'textAlign': 'center',
'color': colors['text']
}
),
# style is used to style a particular dash/html component
html.Div(children='Your Koin, Our Data', style={
'textAlign': 'center',
'color': colors['text']
}),
#dcc.markdown is used to add markdown/text info to the frontend
html.Div(children =[dcc.Markdown(children=markdown_text,style={
'textAlign': 'center',
'color': colors['text'] } )]),
#Inside children branch, a dcc dropdown component is created to add filters
html.Div(children =[html.Label('Ticker symbol'),
dcc.Dropdown(ticker_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.Div(children =[html.Label('Data type'),
dcc.Dropdown(type_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.Div(children = [html.Label('Currency'),
dcc.Dropdown(currency_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.H2(children='ETH opening price',style={'color':colors['text']}),
# Adding generate_table function to html division
html.Div(generate_table(open_df),style={'color':colors['text']}),
#dcc.graph is used to parse plotly graphs to html
dcc.Graph(
id='open graph',
figure=fig
)
]
)
if __name__ =="__main__":
app.run_server(debug=True)enter code here
You need a callback that listens to the dropdown and builds a graph for each value selected. It should loop over the selected values, and append a graph to the output value for each one.
I am very new to Plotly Dash and I cannot get a hang of the #callback function with multiple inputs linked to two (scatter/bar) graphs.
Dashboard
Sample Data
For some reason, after selecting the inputs and clicking the “Run selection” button, the graphs do not update accordingly. Does anyone know what I am doing wrong? Been reading the documentation and browsing through online examples, but could not figure this one out... I believe something is wrong with the #callback function or the way I defined the data in my function.
Thank you in advance, would highly appreciate every bit of help! :slight_smile:
import pandas as pd
import dash
import dash_bootstrap_components as dbc
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
import plotly.graph_objs as go
import plotly.express as px
# load the data
data = pd.read_excel('example_data.xlsx')
data.fillna(0, inplace=True)
data['Satellite'] = data['Satellite'].astype(int)
#initiate app and set theme
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
# navigation bar
navbar = dbc.NavbarSimple(
children=[
dbc.NavItem(dbc.NavLink("Page 1", href="#")),
dbc.DropdownMenu(
children=[
dbc.DropdownMenuItem("Page 2", href="#"),
dbc.DropdownMenuItem("Page 3", href="#"),
],
nav=True,
in_navbar=True,
label="More",
),
],
brand="Sample Dash Application",
brand_href="#",
color="primary",
dark=True,
)
# Construct a dictionary of dropdown values for the days
day_options = []
for day in data['AsofDate'].unique():
# grab day_options and append to it
day_options.append({'label':str(day),'value':day})
# Construct a dictionary of dropdown values for the portfolios
portfolio_options = []
for portfolio in data['Satellite'].unique():
portfolio_options.append({'label':str(portfolio),'value':int(portfolio) or 0})
# Construct a dictionary of dropdown values for the region
region_options = []
for region in data['Region'].unique():
region_options.append({'label':str(region),'value':region})
###############################################################################
# Filter pane
# Check dash core components at https://dash.plotly.com/dash-core-components
###############################################################################
controls = [
html.Div(
[
'Select Day',
dcc.Dropdown(
id='day-dropdown',
options=day_options,
value=data['AsofDate'].min(),
clearable=False
),
]
),
html.Div(
[
'Select Portfolio',
dcc.Dropdown(
id='portfolio-dropdown',
options=portfolio_options,
value=data['Satellite'].min(),
clearable=False
),
]
),
html.Div(
[
'Select Region',
dcc.Dropdown(
id='region-dropdown',
options=region_options,
value=data['Region'].min(),
clearable=False
),
]
),
html.Br(),
dbc.Button("Run selection", color="primary", id="button-submit")
]
###############################################################################
# Add components here, e.g. graphs
###############################################################################
avp_graph = dcc.Graph(id="avp-graph", style={"height": "500px"})
bar_plot_graph = dcc.Graph(id='bar-plot-graph', style={"height": "500px"})
###############################################################################
# Container
# Check dash core components at https://dash.plotly.com/dash-core-components
###############################################################################
container = dbc.Container(
fluid=True,
children=[
html.Hr(),
html.H3('Dashboard'),
html.Hr(),
# Bootstrap Layout examples:
# https://getbootstrap.com/docs/4.0/examples/
# Bootstrap grid system: https://getbootstrap.com/docs/4.0/layout/grid/
# Under each column (2, 5, 5) you can add components.
# The left column has a width of 2 and contains the controls only.
# The middle column has a width of 5 and contains a table and a graph.
# The right column has a width of 5 and contains a table and a graph.
dbc.Row(
[
dbc.Col(
[
# See https://dash-bootstrap-components.opensource.faculty.ai/docs/components/card/
dbc.Card([
dbc.CardHeader("Filter Pane"),
dbc.CardBody(controls),
]
),
],
sm=2
),
dbc.Col(
[
html.H5('Column 1'),
avp_graph # middle column, graph 1
],
sm=5
),
dbc.Col(
[
html.H5('Column 2'),
bar_plot_graph # right column, graph 2
],
sm=5
)
]
)
]
)
# Define Layout
app.layout = html.Div([
navbar,
container
])
#app.callback(
[
Output("avp-graph", "figure"),
Output("bar-plot-graph", "figure")
],
[Input("button-submit", "n_clicks")],
[
State("day-dropdown", "value"),
State("portfolio-dropdown", "value"),
State("region-dropdown", "value"),
],
)
def run_submit(n_clicks, day, portfolio, region):
# Bar plot
mask = data["AsofDate"] == day
bar_plot_graph = px.bar(data[mask], x=data['Region'], y=data['Return'], title='Bar Plot') # barmode="group",
# Scatter Plot
avp_graph = px.scatter(
x=data['line_x'],
y=data['line_y'],
labels={"x": "x", "y": "y"},
title=f"Scatter Plot",
)
return [avp_graph, bar_plot_graph] # return the components in the order of Output Callbacks!!!
if __name__ == '__main__':
app.run_server(port=8051, debug=False)
I'm not sure how you want your plots to change, but what I can see is:
The variables portfolio and region are defined by the state of the dropdown menus, but they are not used in your callback function.
The plot avp_graph in the callback function doesn't depend on any input. Therefore, it makes sense that it remains constant independently of what you select in your dropdown menus.
The plot bar_plot_graph only depends on the variable day.
I am creating an app where the first page should take only 'text input' and results(graph) must show on second page or new tab. I do not want text input and charts on the same page. It means, if I write the input as 'USA' in text input bar, the graph of USA should populate on second tab. Following is the working code that I have written so far in dropdown format. In this code, dropdown and graphs are on the same page which I do not want. Please suggest.
import pandas as pd
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
import numpy as np
import plotly.io as pio
pio.renderers.default='browser'
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Economy Analysis"),
dcc.Dropdown(id='Country_select',
options=[{'label': x, 'value': x}
for x in df.Country.unique()],
value = 'USA'
),
dcc.Graph(id ='my-graph', figure = {})
])
#app.callback(
Output(component_id = 'my-graph', component_property = 'figure'),
Input(component_id = 'Country_select', component_property = 'value'))
def interactive_graphing(value_country):
print(value_country)
s = 100
cat_g = ["developing","develop"]
sample_cat = [cat_g[np.random.randint(0,2)]for i in range(100)]
df = pd.DataFrame({"Country": np.random.choice(["USA", "JPY", "MEX", "IND", "AUS"], s),
"Net": np.random.randint(5, 75, s),
})
df["sample_cat"] = sample_cat
df = df[df.Country==value_country]
df2 = df.pivot_table(index='Country',columns='sample_cat',values='Net',aggfunc='sum')
df2.reset_index(inplace=True)
fig = px.bar(df2, x="Country",
y=['develop','developing'])
return fig
if __name__=='__main__':
app.run_server()
You can use dcc.Tabs and dcc.Tab containers in your layout, and put the input/graph in separate tabs. Dash bootstrap components tabs would also work for this. The ids will still work as inputs/outputs with your callback.
Sample layout:
app.layout = html.Div([
html.H1("Economy Analysis"),
dcc.Tabs([
dcc.Tab(
label='Dropdown',
children=[
dcc.Dropdown(id='Country_select',
options=[{'label': x, 'value': x}
for x in df.Country.unique()],
value = 'USA')
]
),
dcc.Tab(
label='Graph',
children=[
dcc.Graph(id ='my-graph')
]
)
])
])
I can't get this code to run and I am supposed to get a couple of things to work. First, a data table which I managed to get up and get to work. Then I created a few buttons so I can filter the data table. The buttons don't do anything to change the data table, I need to get them to work. Second, I am trying to get a pie chart to work and have it be interactive with the data table. The pie chart does not render. Lastly, I need a geolocation chart that interacts with the data table as well. The data table has a lateral location and a longitude location. geolocation doesn't render either*
from jupyter_plotly_dash import JupyterDash
import dash
import dash_leaflet as dl
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import dash_table as dt
from dash.dependencies import Input, Output, State
import os
import numpy as np
import pandas as pd
from pymongo import MongoClient
from bson.json_util import dumps
# change animal_shelter and AnimalShelter to match your CRUD Python module file name and class name
from AnimalShelter import AnimalShelter
import base64
###########################
# Data Manipulation / Model
###########################
# FIX ME change for your username and password and CRUD Python module name
username = "aacuser"
password = "42213"
shelter = AnimalShelter(username, password)
# class read method must support return of cursor object
df = pd.DataFrame.from_records(shelter.read())
#########################
# Dashboard Layout / View
#########################
app = JupyterDash('SimpleExample')
#FIX ME Add in Grazioso Salvare’s logo
image_filename = 'Grazioso Salvare Logo.png' # replace with your own image
encoded_image = base64.b64encode(open(image_filename, 'rb').read())
#FIX ME Place the HTML image tag in the line below into the app.layout code according to your design
#FIX ME Also remember to include a unique identifier such as your name or date
#html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()))
app.layout = html.Div([
html.Div(id='hidden-div', style={'display':'none'}),
html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode())),
html.Center(html.B(html.H1('Willi Blanco CS-340 Dashboard'))),
html.Hr(),
html.Div(
#FIXME Add in code for the interactive filtering options. For example, Radio buttons, drop down, checkboxes, etc.
className='row',
style={'display': 'flex'},
children=[
html.Button(id='submit-button-one',n_clicks=0, children= 'Water Rescue'),
html.Button(id='submit-button-two',n_clicks=0, children= 'Mountain or Wilderness Rescue'),
html.Button(id='submit-button-three',n_clicks=0, children='Disaster Rescue or Individual Tracking'),
html.Button(id='submit-button-four', n_clicks=0, children='reset')
]
),
html.Hr(),
dt.DataTable(
id='datatable-id',
columns=[
{"name": i, "id": i, "deletable": False, "selectable": True} for i in df.columns
],
data=df.to_dict('records'),
#FIXME: Set up the features for your interactive data table to make it user-friendly for your client
#If you completed the Module Six Assignment, you can copy in the code you created here
page_size=100,
style_table={'height':'300px','overflowY':'auto','overflowX':'auto'},
style_header={
'backgroundColor':'rgb(230,230,230)',
'fontWeight':'bold'
},
style_data={
'whiteSpace':'normal',
'height':'auto'
},
#tooltips that we are going to use on the table so that we know what information we are looking at
tooltip ={i: {
'value': i,
'use_with': 'both' # both refers to header & data cell
} for i in df.columns},
tooltip_delay=0,
tooltip_duration = None,
#sorting features that we are going to use
sort_action='native',
sort_mode='multi',
filter_action='native',
editable=False,
column_selectable=False,
row_selectable='single',
row_deletable=False,
selected_rows=[],
),
html.Br(),
html.Hr(),
#This sets up the dashboard so that your chart and your geolocation chart are side-by-side
html.Div(className='row',
style={'display' : 'flex'},
children=[
html.Div(
id='graph-id',
className='col s12 m6',
),
html.Div(
id='map-id',
className='col s12 m6',
)
])
])
#############################################
# Interaction Between Components / Controller
#############################################
#app.callback([Output('datatable-id','data')],
[Input('submit-button-one', 'n_clicks'),Input('submit-button-two','n_clicks'),
Input('submit-button-three','n_clicks'),Input('submit-button-four','n_clicks')])
def update_dashboard(bt1,bt2,bt3,bt4):
### FIX ME Add code to filter interactive data table with MongoDB queries
if (int(bt1) >= 1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'Labrador Retriever Mix'}, {'breed':'Chesapeake Bay Retriever'},
{'breed':'Newfoundland'}]},
{'sex_upon_outcome':'Intact Female'}, {'age_upon_outcome_in_weeks':{'$lte':26, 'gte':156}}]}))
bt2, bt3, bt4 = 0
elif (int(bt2)>= 1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'German Shepherd'}, {'breed':'Alaskan Malamute'},
{'breed':'Old English Sheepdog'},{'breed':'Siberian Husky'},{'breed':'Rottweiler'}]},
{'sex_upon_outcome':'Intact Male'}, {'age_upon_outcome_in_weeks':{'$lte':26, 'gte':156}}]}))
bt1, bt3 ,bt4 = 0
elif (int(bt3)>=1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'Doberman Pinscher'}, {'breed':'German Sheperd'},
{'breed':'Golden Retriever'},{'breed':'Bloodhound'},{'breed':'Rottweiler'}]},
{'sex_upon_outcome':'Intact Male'}, {'age_upon_outcome_in_weeks':{'$lte':20, 'gte':300}}]}))
bt1, bt2, bt4 = 0
elif(int(bt4)>=1):
df = pd.Dataframe.from_records(shelter.read())
bt1, bt2, bt3 = 0
columns=[{"name": i, "id": i, "deletable": False, "selectable": True} for i in df.columns]
data=df.to_dict('records')
return data
#app.callback(
Output('datatable-id', 'style_data_conditional'),
[Input('datatable-id', 'selected_columns')]
)
def update_styles(selected_columns):
return [{
'if': { 'column_id': i },
'background_color': '#D2F3FF'
} for i in selected_columns]
#app.callback(
Output('graph-id', "children"),
[Input('datatable-id', "derived_viewport_data")])
def update_graphs(viewData):
###FIX ME ####
# add code for chart of your choice (e.g. pie chart)
df = pd.DataFrame.from_dict(viewData)
return [
dcc.Graph(
figure = px.pie(df, values=values, names=names, title='Percentage of breeds available')
)
]
#app.callback(
Output('map-id', "children"),
[Input('datatable-id', "derived_viewport_data"),
Input('datatable-id',"derived_viewport_selected_rows")])
def update_map(viewData):
#FIXME: Add in the code for your geolocation chart
#If you completed the Module Six Assignment, you can copy in the code you created here.
viewDF = pd.DataFrame.from_dict(viewData)
dff = viewDF.loc[rows]
return [ dl.Map(style={'width': '1000px', 'height': '500px'}, center=[dff.loc[0,'location_lat'],dff.loc[0,'location_long']], zoom=15, children=[
dl.TileLayer(id="base-layer-id"),
# Marker with tool tip and pop up
dl.Marker(position=[dff.loc[0,'location_lat'],dff.loc[0,'location_long']], children=[
dl.Tooltip(dff['breed']),
dl.Popup([
html.H1("Animal Name"),
html.P(dff.loc[0,'name'])
])
])
])]
app
In the #app.callback([Output('datatable-id','data')], add [Input('filter-type', 'value')]).
Also, in the callback before update_map, remove Input('datatable-id',"derived_viewport_selected_rows")]). Try: #app.callback(Output('map-id', "children"), [Input('datatable-id', "derived_viewport_data")])
I succeed in adding dynamically container/bloc in my dash app when clicking on a button.
Each bloc contains one graph and two dropdown (one for X axis and the other for Y axis)
Each time I update a dropdown input (X or Y) the graph axis are updated and datas are correctly plotted
It works, but...
Before I choose dropdown value, some values are inially plotted on the graph zone. And I don't want this. I would like an empty graph
enter image description here
Here is my app code:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, MATCH, ALL
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
app = dash.Dash(name="OUATT")
DATA = pd.read_csv('C:/Users/joris/Desktop/donnees.txt', sep=';')
print(DATA)
#graphe_test= px.scatter(DATA,x=DATA.x,y=DATA.y)
def create_figure(column_x, column_y):
return px.scatter(DATA,x=column_x,y=column_y)
app.layout = html.Div([
html.Button(" + Graphe", id="ajout-graphe", n_clicks=0),
html.Div(),
html.Div(id='bloc_graphe', children=[])
])
#app.callback( Output('bloc_graphe', 'children'),
[Input('ajout-graphe', 'n_clicks')],
[State('bloc_graphe', 'children')])
def ajouter_graphe(n_clicks, children):
nouvelle_zone_graphe = html.Div(
style={'width': '23%', 'display': 'inline-block', 'outline': 'thin lightgrey solid', 'padding': 10},
children=[
dcc.Graph(
id ={'type': 'Graphique',
'index': n_clicks}
),
dcc.Dropdown(
id={
'type':'Selection_variable_X',
'index': n_clicks
},
options=[{'label':i, 'value':i} for i in DATA.columns],
value = None
),
dcc.Dropdown(
id={
'type':'Selection_variable_Y',
'index': n_clicks
},
options=[{'label':i, 'value':i} for i in DATA.columns],
value = None
),
])
children.append(nouvelle_zone_graphe)
return children
#app.callback( Output({'type':'Graphique', 'index':MATCH},'figure'),
[Input({'type':'Selection_variable_X', 'index':MATCH}, 'value'),
Input({'type':'Selection_variable_Y', 'index':MATCH}, 'value')]
)
def display_output(column_x,column_y):
return create_figure(column_x, column_y)
if __name__ == '__main__':
app.run_server(debug=True)
My datas are basic and located in a text file:
enter image description here
I use Pattern-Matching callbacks. I'm sure I miss something in this part of my code:
#app.callback( Output({'type':'Graphique', 'index':MATCH},'figure'),
[Input({'type':'Selection_variable_X', 'index':MATCH}, 'value'),
Input({'type':'Selection_variable_Y', 'index':MATCH}, 'value')]
)
def display_output(column_x,column_y):
return create_figure(column_x, column_y)
If someone can tell me why I have not empty graph when adding a new bloc ?
Thanks a lot in advance for your support
Joe
I always suggest explicitly setting the prop you plan to update, figure in this case, to some default you want, such as {}.
It's possible the callback is running when you add the dropdowns. You can stop that by doing something like this:
#app.callback( Output({'type':'Graphique', 'index':MATCH},'figure'),
[Input({'type':'Selection_variable_X', 'index':MATCH}, 'value'),
Input({'type':'Selection_variable_Y', 'index':MATCH}, 'value')]
)
def display_output(column_x,column_y):
if column_x is None and column_y is None:
raise dash.exceptions.PreventUpdate
return create_figure(column_x, column_y)
Hopefully that keeps your figure empty until the user selects from the dropdowns.